home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TP_ADV.ZIP / LIST1203.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-11-17  |  8.8 KB  |  295 lines

  1. Program TicTac;
  2.  
  3. Uses
  4.   CRT;
  5.  
  6. Const
  7.   PLAY = 1;        { Semaphore values }
  8.   MOVE = 2;
  9.   GOAHEAD = 3;
  10.   WAITING = 4;
  11.   GAMEOVER = 5;
  12.  
  13. Type
  14.   PlayerRec   = Record
  15.                   Status : Byte;  { semaphore status field }
  16.                   Pos    : Byte;  { player's move field    }
  17.                 End;
  18.   PlayerArray = Array [1..2] of PlayerRec;
  19.   PlayerFile  = File of PlayerArray;
  20.  
  21. Var
  22.   loop : Byte;
  23.   first : boolean;     { TRUE = first program to start the game }
  24.   FileName : String;   { Name of the data file }
  25.   pa : PlayerArray;
  26.   pf : PlayerFile;
  27.   slot,                { Holds the position of player in the playerarray }
  28.   other : Byte;        { Holds the opponent position in the playerarray }
  29.   pPos : Byte;
  30.   board : Array [1..9] of Byte;       { Play field }
  31.   solution : Byte;                    { Who won the game? }
  32.  
  33. Procedure Terminate; Forward;
  34.  
  35. Function PlayFileExists : Boolean;
  36. { This function will check to see if the play file that is specified }
  37. { in the global FileName variable exists in the current directory.   }
  38. { TRUE = File exists    }
  39. { FALSE = No file found }
  40. Var
  41.   ioErr : Word;
  42. Begin
  43.   Assign ( pf, FileName );
  44.   {$I-}
  45.   Reset ( pf );
  46.   {$I+}
  47.   ioErr := IOResult;
  48.   If ( ioErr = 2 ) Then   { This is the first program to run }
  49.   Begin
  50.     PlayFileExists := FALSE;
  51.     slot := 1;
  52.     other := 2;
  53.   End
  54.   Else
  55.   Begin                   { Somebody else already set the game up }
  56.     If ( ioErr = 0 ) Then
  57.       Close ( pf );
  58.     slot := 2;
  59.     other := 1;
  60.   End;
  61. End;
  62.  
  63. Procedure GameInProgress;
  64. { Not too elegant, but you may taylor this to your own needs }
  65. Begin
  66.   WriteLn ( 'Game already in progress.' );
  67.   Halt;
  68. End;
  69.  
  70. Function CheckSolution : Byte;
  71. { This function will return a TRUE is there is a Win Solution to }
  72. { the game. With a TicTacToe set up as follows:                  }
  73. {    1   2   3                                                   }
  74. {    4   5   6                                                   }
  75. {    7   8   9                                                   }
  76. { The combinations checked will be:                              }
  77. {         1.)  1 2 3                                             }
  78. {         2.)  1 4 7                                             }
  79. {         3.)  1 5 9                                             }
  80. {         4.)  7 8 9                                             }
  81. {         5.)  7 5 3                                             }
  82. {         6.)  2 5 8                                             }
  83. {         7.)  3 6 9                                             }
  84. {         8.)  4 5 6                                             }
  85. Var
  86.   Check : Array [1..2] of Boolean;
  87. Begin
  88.   For loop := 1 to 2 do
  89.   Begin
  90.     Check [loop] := FALSE;
  91.     If ( board [1] = loop ) AND
  92.        ( ( ( board [2] = loop ) AND ( board [3] = loop ) ) OR
  93.          ( ( board [4] = loop ) AND ( board [7] = loop ) ) OR
  94.          ( ( board [5] = loop ) AND ( board [9] = loop ) ) ) Then
  95.       Check [loop] := TRUE
  96.     Else
  97.     If ( board [7] = loop ) AND
  98.        ( ( ( board [8] = loop ) AND ( board [9] = loop ) ) OR
  99.          ( ( board [5] = loop ) AND ( board [3] = loop ) ) ) Then
  100.       Check [loop] := TRUE
  101.     Else
  102.     If ( (board [2] = loop) AND (board [5] = loop) AND (board [8] = loop) ) OR
  103.        ( (board [3] = loop) AND (board [6] = loop) AND (board [9] = loop) ) OR
  104.        ( (board [4] = loop) AND (board [5] = loop) AND (board [6] = loop) ) Then
  105.       Check [loop] := TRUE;
  106.   End;
  107.   If ( Check [1] ) Then
  108.     CheckSolution := 1
  109.   Else
  110.   If ( Check [2] ) Then
  111.     CheckSolution := 2
  112.   Else
  113.   Begin
  114.     Check [1] := TRUE;
  115.     For loop := 1 to 9 Do
  116.       Check [1] := Check [1] AND ( board [loop] in [1..2] );
  117.     If ( Check [1] ) Then
  118.       CheckSolution := 3  { Cat's game, no winner }
  119.     Else
  120.       CheckSolution := 0;
  121.   End;
  122. End;
  123.  
  124. Procedure Signal ( sig : Byte );
  125. { This procedure will set the appropriate status flag in the file }
  126. { specified by FileName to the value in SIG. SPECIAL CASE: If the }
  127. { flag SIG = PLAY, this procedure will determine if a game is     }
  128. { already in progress and will terminate the program is so.       }
  129. Begin
  130.   Assign ( pf, FileName );
  131.   {$I-}
  132.   Repeat                     { Repeat until the file is not    }
  133.     Reset ( pf );            { locked. File is locked when     }
  134.   Until ( IOResult = 0 );    { the other program is accessing. }
  135.   {$I+}
  136.   Read ( pf, pa );           { Read the player information }
  137.  
  138.   Case ( sig ) Of
  139.        Move: Begin
  140.                pa [ slot ].Pos := pPos;
  141.                pa [ slot ].Status := MOVE;
  142.                pa [ other ].Status := GOAHEAD;
  143.              End;
  144.        Play: Begin
  145.                If ( pa [ slot ].Status <> WAITING ) Then
  146.                  GameInProgress;
  147.                pa [ slot ].Status := PLAY;
  148.              End;
  149.        GameOver : pa [ slot ].Status := GAMEOVER;
  150.   End;
  151.   Seek ( pf, 0 );                { Move to the start of the file }
  152.   Write ( pf, pa );              { Write the new information out }
  153.   Close ( pf );                  { Close the file }
  154. End;
  155.  
  156. Procedure WaitFor ( position, sig : Byte );
  157. { This procedure will wait for the appropriate status flag in the }
  158. { file specified by FileName to be set to the value in SIG.       }
  159. Begin
  160.   Assign ( pf, FileName );
  161.   Repeat
  162.     {$I-}
  163.     Repeat
  164.       Reset ( pf );            { Repeat until the file is not locked }
  165.     Until ( IOResult = 0 );
  166.     {$I+}
  167.     Read ( pf, pa );           { Read the player information in }
  168.     Close ( pf );              { Close the file }
  169.     Delay ( 500 );     { Delay to give the other program a chance  }
  170.                        { to change the status.                     }
  171.   Until ( pa [ position ].Status = sig );
  172.   If ( pa [ other ].Status in [Move,GameOver] ) Then
  173.     board [ pa [ other ].Pos ] := other;
  174. End;
  175.  
  176. Procedure Terminate;
  177. { This procedure will be called when the current program has }
  178. { determined that the game is over. It will either set the   }
  179. { EOG ( End of Game ) signal and end, or will wait for the   }
  180. { other program to signal end of game, then erase the file   }
  181. { and end.                                                   }
  182. Begin
  183.   If ( solution = 3 ) Then
  184.     WriteLn ( 'Sorry, no winner in this game.' )
  185.   Else
  186.   If ( solution = slot ) Then
  187.     WriteLn ( 'Congradulations! You won the game!' )
  188.   Else
  189.     WriteLn ( 'I am sorry, you lost the game.' );
  190.   Signal ( GameOver );
  191.   If ( slot = 1 ) Then
  192.   Begin
  193.     WaitFor ( other, GameOver );
  194.     Assign ( pf, FileName );
  195.     {$I-}
  196.     Erase ( pf );
  197.     {$I+}
  198.   End;
  199. End;
  200.  
  201. Procedure CreatePlayFile;
  202. { This procedure will create a new Play File, the name of this }
  203. { file is specified by the variable FileName.                  }
  204. Begin
  205.   Assign ( pf, FileName );
  206.   Rewrite ( pf );
  207.   pa [ slot ].Status := Play;
  208.   pa [ other ].Status := Waiting;
  209.   Write ( pf, pa );
  210.   Close ( pf );
  211. End;
  212.  
  213. Function XXorOO ( b : Byte ) : String;
  214. Begin
  215.   If ( board [ b ] = 1 ) Then
  216.     XXorOO := 'XX'
  217.   Else
  218.   If ( board [ b ] = 2 ) Then
  219.     XXorOO := 'OO'
  220.   Else
  221.     XXorOO := '  ';
  222. End;
  223.  
  224. Procedure ShowBoard;
  225. Var
  226.   oldWindMin,
  227.   oldWindMax : Word;
  228. Begin
  229.   oldWindMin := WindMin;
  230.   oldWindMax := WindMax;
  231.   Window ( 1,1,20,8 );
  232.   ClrScr;
  233.   WriteLn ( XXorOO ( 7 ):4, ' |', XXorOO ( 8 ):4, ' |', XXorOO ( 9 ):3 );
  234.   WriteLn ( ' ----+-----+----' );
  235.   WriteLn ( XXorOO ( 4 ):4, ' |', XXorOO ( 5 ):4, ' |', XXorOO ( 6 ):3 );
  236.   WriteLn ( ' ----+-----+----' );
  237.   WriteLn ( XXorOO ( 1 ):4, ' |', XXorOO ( 2 ):4, ' |', XXorOO ( 3 ):3 );
  238.   WindMin := oldWindMin;
  239.   WindMax := oldWindMax;
  240. End;
  241.  
  242. Procedure GetMove;
  243. { This procedure will get the move of the player and make sure }
  244. { that it is a valid move.                                     }
  245. Var
  246.   x, y : Byte;
  247. Begin
  248.   ShowBoard;
  249.   Repeat
  250.     Window ( 1, 20, 80, 25 );
  251.     ClrScr;
  252.     Write ( 'What is your move? ' );
  253.     ReadLn ( pPos );
  254.   Until ( pPos in [1..9] ) AND ( board [ pPos ] = 0 );
  255.   board [ pPos ] := Slot;
  256.   ShowBoard;
  257. End;
  258.  
  259. Begin
  260.   ClrScr;
  261.   CheckBreak := FALSE;            { Initialize the variables }
  262.   For loop := 1 to 9 Do                      { " }
  263.     board [ loop ] := 0;                     { " }
  264.   FileName := 'F:\tictac.dat';               { " }
  265.  
  266.   If PlayFileExists Then
  267.   Begin
  268.     Signal ( Play ); { signal will abort if another game is in progress }
  269.     First := FALSE;
  270.     ShowBoard;       { display the empty playing field }
  271.   End
  272.   Else
  273.   Begin
  274.     CreatePlayFile;
  275.     First := TRUE;
  276.     WriteLn ( 'Waiting for other player to join game.' );
  277.     WaitFor ( other, Play );
  278.     ClrScr;
  279.     GetMove;
  280.     Signal ( Move );
  281.   End;
  282.   Repeat
  283.     WaitFor ( slot, GoAhead );
  284.     solution := CheckSolution;
  285.     if ( Solution = 0 ) Then
  286.     Begin
  287.       GetMove;
  288.       Signal ( Move );
  289.     End;
  290.     solution := CheckSolution;
  291.   Until ( solution in [1..3] );
  292.   ShowBoard;
  293.   Terminate;
  294. End.
  295.