home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / sampler / 03 / diverse / tictac.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-14  |  6.3 KB  |  247 lines

  1. unit TicTac;
  2. {
  3.    TICTAC.PAS  unit for implement abstract data types MOVE,
  4.                LOCATION, GAME
  5.    author      bruce f. webster
  6.    last update 12 dec 87
  7. }
  8. interface
  9.  
  10. {  definitions for abstract data type Move }
  11.  
  12. type
  13.   Move        = (BLANK,X,O);
  14.  
  15. function Opposite(M : Move) : Move;
  16.  
  17. { definitions for abstract data type Location }
  18.  
  19. const
  20.   GLim        = 9;
  21.  
  22. type
  23.   Location    = 1..GLim;
  24.  
  25. { defintions for abstract data type Game }
  26.  
  27. type
  28.   Board       = array[Location] of Move;
  29.   Game        = record
  30.     Grid      : Board;
  31.     Next,Win  : Move;
  32.     Moves     : Integer
  33.   end;
  34.  
  35. function GetLoc(var G : Game; L : Location) : Move;
  36. function NextMove(G : Game) : Move;
  37. function MovesMade(G : Game) : Integer;
  38. function GameOver(var G : Game) : Boolean;
  39. function Winner(G : Game) : Move;
  40. procedure DoMove(var G : Game; L : Location);
  41. procedure NewGame(var G : Game; First : Move);
  42.  
  43. implementation
  44.  
  45. function Opposite(M : Move) : Move;
  46. {
  47.   purpose      return opposite of value passed
  48.   pre          m has a value of X, O, or BLANK
  49.   post         if m = X, then returns O
  50.                if m = O, then returns X
  51.                else returns BLANK
  52. }
  53. begin
  54.   case M of
  55.     BLANK  : Opposite := BLANK;
  56.     X      : Opposite := O;
  57.     O      : Opposite := X
  58.   end
  59. end; { of proc Opposite }
  60.  
  61. procedure SetLoc(var G : Game; L : Location; M : Move);
  62. {
  63.    purpose     sets a location in the game to a given value
  64.    pre         l is in the range 1..9
  65.                m has a value of X, O, or BLANK
  66.    post        location l in the game has value m
  67. }
  68. begin
  69.   G.Grid[L] := M
  70. end; { of proc SetLoc }
  71.  
  72. function GetLoc(var G : Game; L : Location) : Move;
  73. {
  74.    purpose     returns value of a given location in the game
  75.    pre         g has been initialized, l is in the range 1..9
  76.    post        returns value of g at location l
  77. }
  78. begin
  79.   GetLoc := G.Grid[L]
  80. end; { of proc GetLoc }
  81.  
  82. function NextMove(G : Game) : Move;
  83. {
  84.    purpose     returns next move
  85.    pre         g has been initialized
  86.    post        if game is not over
  87.                  then returns X or O
  88.                  else returns BLANK
  89. }
  90. begin
  91.   NextMove := G.Next
  92. end; { of func NextMove }
  93.  
  94. function MovesMade(G : Game) : Integer;
  95. {
  96.    purpose     returns number of moves made in game so far
  97.    pre         g has been initialized
  98.    post        returns a value in the range 0..9
  99. }
  100. begin
  101.   MovesMade := G.Moves
  102. end; { of func MovesMade }
  103.  
  104. procedure InARow(var G : Game; I,J,K : Location);
  105. {
  106.    puporse     checks for three X's or O's in a row
  107.    pre         g has been initialized, 0 or more moves made
  108.    post        if locations i,j,k all have the same value
  109.                and that value is not BLANK
  110.                  then the winner is set to that value
  111. }
  112. begin
  113.   with G do begin
  114.     if Win = BLANK then begin
  115.       if  (Grid[I] = Grid[J]) and (Grid[J] = Grid[K])
  116.       and (Grid[I] <> BLANK)  then Win := Grid[I]
  117.     end
  118.   end
  119. end; { of proc InARow }
  120.  
  121. procedure CheckForWin(var G : Game; L : Location);
  122. {
  123.    purpose     see if last move won the game
  124.    pre         g has been initialized, 1 or more moves made,
  125.                l is in the range 1..9, location l has X or O,
  126.                last move was made at location l
  127.    post        if l forms 3 X's or O's in a row
  128.                  then the winner is set to that value (X or O)
  129. }
  130. begin
  131.   case L of
  132.     1  : begin
  133.            InARow(G,1,2,3);
  134.            InARow(G,1,5,9);
  135.            InARow(G,1,4,7)
  136.          end;
  137.     2  : begin
  138.            InARow(G,1,2,3);
  139.            InARow(G,2,5,8)
  140.          end;
  141.     3  : begin
  142.            InARow(G,1,2,3);
  143.            InARow(G,3,5,7);
  144.            InARow(G,3,6,9)
  145.          end;
  146.     4  : begin
  147.            InARow(G,1,4,7);
  148.            InARow(G,4,5,6)
  149.          end;
  150.     5  : begin
  151.            InARow(G,1,5,9);
  152.            InARow(G,2,5,8);
  153.            InARow(G,3,5,7);
  154.            InARow(G,4,5,6)
  155.          end;
  156.     6  : begin
  157.            InARow(G,3,6,9);
  158.            InARow(G,4,5,6)
  159.          end;
  160.     7  : begin
  161.            InARow(G,1,4,7);
  162.            InARow(G,3,5,7);
  163.            InARow(G,7,8,9)
  164.          end;
  165.     8  : begin
  166.            InARow(G,2,5,8);
  167.            InARow(G,7,8,9)
  168.          end;
  169.     9  : begin
  170.            InARow(G,1,5,9);
  171.            InARow(G,3,6,9);
  172.            InARow(G,7,8,9)
  173.          end
  174.   end
  175. end; { of proc CheckForWin }
  176.  
  177. function GameOver(var G : Game) : Boolean;
  178. {
  179.    purpose     returns status of game (over or not)
  180.    pre         g has been initialized, 0 or more moves have been made
  181.    post        if game is over
  182.                  then returns TRUE
  183.                  else returns FALSE
  184. }
  185. begin
  186.   GameOver := (G.Win <> BLANK) or (G.Moves = GLim)
  187. end; { of func GameOver }
  188.  
  189. function Winner(G : Game) : Move;
  190. {
  191.    purpose     returns winner of game
  192.    pre         g has been initialized, the game is over
  193.    post        if there are 3 X's in a row, returns X
  194.                if there are 3 O's in a row, returns O
  195.                else returns BLANK (draw)
  196. }
  197. begin
  198.   Winner := G.Win
  199. end; { of func Winner }
  200.  
  201. procedure DoMove(var G : Game; L : Location);
  202. {
  203.    purpose     make next move in game
  204.    pre         g has been initialized, 0 or more moves made,
  205.                the game is not over, l is in the range 1..9,
  206.                getloc(g,l) is BLANK
  207.    post        the next move is made at location l
  208.                a possible win is checked
  209.                if game is not over,
  210.                  then the next move is toggled
  211.                  else the next move is set to BLANK
  212. }
  213. begin
  214.   with G do begin
  215.     SetLoc(G,L,G.Next);
  216.     Moves := Moves + 1;
  217.     CheckForWin(G,L);
  218.     if not GameOver(G)
  219.       then Next := Opposite(Next)
  220.    else Next := BLANK
  221.   end
  222. end; { of proc DoMove }
  223.  
  224. procedure NewGame(var G : Game; First : Move);
  225. {
  226.    purpose     initialize a new game
  227.    pre         first has a value of X or O
  228.    post        g has been initialized:
  229.                  locations 1..9 are setBto BLANK
  230.                  the next move is set to first
  231.                  the winner is set to BLANK
  232.                  the number of moves is set to 0
  233. }
  234. var
  235.   I           : Integer;
  236. begin
  237.   with G do begin
  238.     for I := 1 to GLim do
  239.       SetLoc(G,I,BLANK);
  240.     Next  := First;
  241.     Win   := BLANK;
  242.     Moves := 0
  243.   end
  244. end; { of proc NewGame }
  245.  
  246. end. { of unit TicTac }
  247.