7 SQUARE g_sComputerPlays = O_MARK; // what side comp plays
\r
9 //+----------------------------------------------------------------------------
\r
11 // Function: SquareContentsToChar
\r
13 // Synopsis: Helper function for DrawBoard
\r
15 // Arguments: IN SQUARE s - a square to return a char to represent
\r
17 // Returns: char - character representing square
\r
19 //+----------------------------------------------------------------------------
\r
20 char SquareContentsToChar(IN SQUARE s)
\r
38 //+----------------------------------------------------------------------------
\r
40 // Function: DrawBoard
\r
42 // Synopsis: Draw the board
\r
44 // Arguments: IN POSITION *p - pointer to a position whose board to draw
\r
48 //+----------------------------------------------------------------------------
\r
49 void DrawBoard(IN POSITION *p)
\r
53 for (y = 0; y < BOARD_SIZE; y++)
\r
55 for (x = 0; x < BOARD_SIZE; x++)
\r
57 printf("%c ", SquareContentsToChar(p->sBoard[y][x]));
\r
61 printf("\n%c to move.\n", SquareContentsToChar(p->sWhoseTurn));
\r
64 //+----------------------------------------------------------------------------
\r
66 // Function: ClearBoard
\r
68 // Synopsis: Clear the board
\r
70 // Arguments: IN OUT POSITION *p - pointer to position whose board to clear
\r
74 //+----------------------------------------------------------------------------
\r
75 void ClearBoard(IN OUT POSITION *p)
\r
77 memset(p->sBoard, 0, sizeof(p->sBoard));
\r
78 p->sWhoseTurn = X_MARK;
\r
79 p->uNumEmpty = (BOARD_SIZE * BOARD_SIZE);
\r
82 //+----------------------------------------------------------------------------
\r
84 // Function: IsLegalMove
\r
86 // Synopsis: Determine if a given move is legal on a given board
\r
88 // Arguments: IN POSITION *p - the board to play the move on
\r
89 // IN MOVE *m - the move in question
\r
91 // Returns: BOOL - TRUE if it's legal, FALSE otherwise
\r
93 //+----------------------------------------------------------------------------
\r
94 BOOL IsLegalMove(IN POSITION *p, IN MOVE *m)
\r
96 if ((m->cVpos < BOARD_SIZE) && (m->cHpos < BOARD_SIZE))
\r
98 if (IS_SQUARE_EMPTY(p->sBoard[m->cVpos][m->cHpos]))
\r
106 //+----------------------------------------------------------------------------
\r
108 // Function: GetHumanMove
\r
110 // Synopsis: Ask the human for a move
\r
112 // Arguments: IN POSITION *p - the current board
\r
113 // OUT MOVE *m - the move the human made; this struct is populated
\r
114 // as a side-effect of this function.
\r
116 // Returns: void* (populates the move struct)
\r
118 //+----------------------------------------------------------------------------
\r
119 void GetHumanMove(IN POSITION *p, OUT MOVE *m)
\r
125 printf("Enter your move number: ");
\r
128 m->cHpos = (x % BOARD_SIZE);
\r
129 m->cVpos = (x / BOARD_SIZE);
\r
130 m->sMark = g_sComputerPlays * -1;
\r
132 while(FALSE == IsLegalMove(p, m));
\r
135 //+----------------------------------------------------------------------------
\r
137 // Function: SearchForComputerMove
\r
139 // Synopsis: Use our sophisticated search algorithm to find a computer
\r
142 // Arguments: IN POSITION *p - the current board
\r
143 // OUT MOVE *m - the move the computer chooses; this move struct
\r
144 // is populated as a side-effect of this function.
\r
146 // Returns: void* (populates move struct)
\r
148 //+----------------------------------------------------------------------------
\r
149 void SearchForComputerMove(IN POSITION *p, OUT MOVE *m)
\r
155 x = rand() % (BOARD_SIZE * BOARD_SIZE);
\r
156 m->cHpos = (x % BOARD_SIZE);
\r
157 m->cVpos = (x / BOARD_SIZE);
\r
158 m->sMark = g_sComputerPlays;
\r
160 while(FALSE == IsLegalMove(p, m));
\r
163 //+----------------------------------------------------------------------------
\r
165 // Function: MakeMove
\r
167 // Synopsis: Make a move on a board
\r
169 // Arguments: IN OUT POSITION *p - the board
\r
170 // IN MOVE *m - the move
\r
174 //+----------------------------------------------------------------------------
\r
175 void MakeMove(IN OUT POSITION *p, IN MOVE *m)
\r
177 if (TRUE == IsLegalMove(p, m))
\r
179 p->sBoard[m->cVpos][m->cHpos] = m->sMark;
\r
181 p->sWhoseTurn *= -1;
\r
185 //+----------------------------------------------------------------------------
\r
187 // Function: GameOver
\r
189 // Synopsis: Is the game over?
\r
191 // Arguments: IN POSITION *p - the board
\r
192 // OUT SQUARE *psWhoWon - who won the game (if it's over)
\r
194 // Returns: TRUE if the game is over. Also sets psWhoWon telling
\r
195 // which side one if the game is over.
\r
197 // FALSE if the game is not over.
\r
199 //+----------------------------------------------------------------------------
\r
200 BOOL GameOver(IN POSITION *p, OUT SQUARE *psWhoWon)
\r
205 for (x = 0; x < BOARD_SIZE; x++)
\r
209 for (y = 0; y < BOARD_SIZE; y++)
\r
211 iSum += p->sBoard[x][y];
\r
213 if (abs(iSum) == BOARD_SIZE) goto winner;
\r
216 for (y = 0; y < BOARD_SIZE; y++)
\r
220 for (x = 0; x < BOARD_SIZE; x++)
\r
222 iSum += p->sBoard[x][y];
\r
224 if (abs(iSum) == BOARD_SIZE) goto winner;
\r
228 for (x = 0; x < BOARD_SIZE; x++)
\r
230 iSum += p->sBoard[x][x];
\r
232 if (abs(iSum) == BOARD_SIZE) goto winner;
\r
235 for (x = 0; x < BOARD_SIZE; x++)
\r
237 iSum += p->sBoard[x][(BOARD_SIZE - 1 - x)];
\r
239 if (abs(iSum) == BOARD_SIZE) goto winner;
\r
242 if (p->uNumEmpty == 0)
\r
252 *psWhoWon = (iSum / BOARD_SIZE);
\r
256 //+----------------------------------------------------------------------------
\r
260 // Synopsis: The program entry point and main game loop.
\r
266 //+----------------------------------------------------------------------------
\r
274 // Randomize: the random numbers returned by rand() will be based on
\r
275 // the system clock when the program starts up.
\r
280 // Setup the board and draw it once.
\r
291 // See whose turn it is -- the human's or the computers -- and
\r
292 // get a move from whoever's turn it is.
\r
294 if (p.sWhoseTurn == g_sComputerPlays)
\r
296 SearchForComputerMove(&p, &mv);
\r
300 GetHumanMove(&p, &mv);
\r
304 // Make the move on the board and draw the board again.
\r
309 while(FALSE == GameOver(&p, &sResult));
\r
312 // If we get here the game is over... see what happened.
\r
317 printf("\nX's win.\n");
\r
320 printf("\nO's win.\n");
\r
323 printf("Tie (what a surprise)\n");
\r