DEFINITION MODULE history;

(**************************************************************************)
(*                                                                        *)
(*   Here you will find all that you will need to maintain the history    *)
(* list for your Ataxx game program.  Actually, I bet this module would   *)
(* work pretty well for any program where you need a history of the past  *)
(* states.  The available functions for such a history data structure     *)
(* are:                                                                   *)
(*                                                                        *)
(*      InitHistory          Sets up the history data structure so that   *)
(*                           it can then be used.                         *)
(*                                                                        *)
(*      CloseHistory         The logical alternative to InitHistory.      *)
(*                           It needs to be called to clean up properly.  *)
(*                                                                        *)
(*      AddToHistory         This is the constructor.  It's the only way  *)
(*                           to build your history.                       *)
(*                                                                        *)
(*      PopHistory           This removes the last (most recent) item in  *)
(*                           the history data structure and returns it to *)
(*                           the caller.  Its stack-like action gives it  *)
(*                           its name.                                    *)
(*                                                                        *)
(*      ClearHistory         The fast way to get a tabula rasa.           *)
(*                                                                        *)
(**************************************************************************)

FROM header
  IMPORT boardtype, histnodeptrtype, historytype, playertype;



PROCEDURE InitHistory (VAR history : historytype;
                       board : boardtype;  player : playertype) : BOOLEAN;

(*   This takes an uninitialized variable of history type and sets all    *)
(* the appropriate things to an initial value.                            *)
(*                                                                        *)
(*   INPUT                                                                *)
(*            history           Variable of history type.  It should be   *)
(*                              unused.                                   *)
(*                                                                        *)
(*            board             This board should represent the current   *)
(*                              board state.                              *)
(*                                                                        *)
(*            player            And similarly for the player.             *)
(*                                                                        *)
(*   OUTPUT                                                               *)
(*            history           Same variable.  It will be modified so    *)
(*                              that it will reflect an initial state.    *)
(*                                                                        *)
(*            The function will return TRUE only if it can properly in-   *)
(*            itialize the variable.  If something goes wrong -> FALSE.   *)


PROCEDURE CloseHistory (VAR history : historytype);

(*   This takes a variable of history type and clears all the memory and  *)
(* etc associated with it.                                                *)
(*                                                                        *)
(*   INPUT                                                                *)
(*            history           Variable of history type.                 *)
(*                                                                        *)
(*   OUTPUT                                                               *)
(*            history           Same variable.  It will be modified and   *)
(*                              should NOT be used after calling this     *)
(*                              routine.                                  *)


PROCEDURE AddToHistory (VAR history : historytype;
                            board : boardtype;  player : playertype)
                              : BOOLEAN;

(*   This takes an initialized variable of history type and adds the      *)
(* board to it.  NOTE: it is up to the caller to maintain all the proper  *)
(* changes to its own state.  This just keeps track of the moves.         *)
(*                                                                        *)
(*   INPUT                                                                *)
(*            history           Variable of history type.  It definately  *)
(*                              should be initialized.                    *)
(*                                                                        *)
(*            board             A boardtype.  It is what will be added    *)
(*                              to the history.                           *)
(*                                                                        *)
(*            player            Whose turn it was to move at this board's *)
(*                              configuration.                            *)
(*                                                                        *)
(*   OUTPUT                                                               *)
(*            history           Same variable.  It will be modified so    *)
(*                              that it will now hold the new board.      *)
(*                                                                        *)
(*            The function will return TRUE only if it can properly add   *)
(*            the new board to the history.  If something goes wrong,     *)
(*            then this will try to return the original history and       *)
(*            return FALSE.                                               *)


PROCEDURE PopHistory (VAR history : historytype;
                     VAR board : boardtype;  VAR player : playertype)
                         : BOOLEAN;

(*   This takes an initialized variable of history type and removes the   *)
(* most recent move from it.  The result is put into the variable board.  *)
(* If there are no boards in the current history (ie, the history list    *)
(* is empty) then the function will return FALSE.                         *)
(*                                                                        *)
(*   INPUT                                                                *)
(*            history           Variable of history type.  It definately  *)
(*                              should be initialized.                    *)
(*                                                                        *)
(*            board             A boardtype.  Initially it is garbage.    *)
(*                                                                        *)
(*            player            A playertype.  Also garbage at the start. *)
(*                                                                        *)
(*   OUTPUT                                                               *)
(*            history           Same variable.  It will be modified so    *)
(*                              that it no longer holds the returned      *)
(*                              board.                                    *)
(*                                                                        *)
(*            board             This will hold the board that is re-      *)
(*                              turned.  If the history contains no pre-  *)
(*                              vious boards, then this variable is un-   *)
(*                              changed.                                  *)
(*                                                                        *)
(*            player            Holds the player whose turn it is for the *)
(*                              returned board.                           *)
(*                                                                        *)
(*            The function will return TRUE only if it can properly pop   *)
(*            a board from it.  If the history is empty, then the func-   *)
(*            returns FALSE.                                              *)

(**************************************************************************)
PROCEDURE UpHistory (VAR history : historytype;  VAR board : boardtype;
                     VAR player : playertype) : BOOLEAN;

(*   This is used to REDO moves.  It is called and works very much like   *)
(* PopHistory.                                                            *)
(*                                                                        *)
(*   INPUT                                                                *)
(*            history           Variable of history type.  It definately  *)
(*                              should be initialized.                    *)
(*                                                                        *)
(*            board             A boardtype.  Initially it is garbage.    *)
(*                                                                        *)
(*            player            A playertype.  Also garbage at the start. *)
(*                                                                        *)
(*   OUTPUT                                                               *)
(*            history           Same variable.  It may be modified, but   *)
(*                              don't worry about it.                     *)
(*                                                                        *)
(*            board             This will hold the board that is re-      *)
(*                              turned.  If the history contains no next  *)
(*                              boards, then this variable is unchange.   *)
(*                                                                        *)
(*            player            Holds the player whose turn it is for the *)
(*                              returned board.                           *)
(*                                                                        *)
(*                                                                        *)
(*            The function will return TRUE only if it can properly make  *)
(*            a board from it.  If there is no further boards to go Up,   *)
(*            it returns FALSE.                                           *)

(**************************************************************************)
PROCEDURE NewHistory (VAR history : historytype;  board : boardtype;
                      player : playertype);

(*   Given an already initialized history, this resets it to make a brand *)
(* new history structure with the current board and player set in it.     *)
(*                                                                        *)
(*   INPUT                                                                *)
(*            history           Variable of history type.  It definately  *)
(*                              should be initialized, though not neces-  *)
(*                              sarily full of boards.                    *)
(*                                                                        *)
(*            board             This board should represent the current   *)
(*                              board state.                              *)
(*                                                                        *)
(*            player            And similarly for the player.             *)
(*                                                                        *)
(*   OUTPUT                                                               *)
(*            history           Same variable.  It will be modified so    *)
(*                              that it now is devoid of boards save one. *)

END history.
