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.