/* Problem 5: Andy Poe's Tic-Tac-Toe Given an incomplete Tic-Tac-Toe board configuration, determine the eventual winner of the game. */ #include #include #include typedef char BT[3][3]; /* The 3 x 3 Tic-Tac-Toe grid */ int main (int argc, char **argv); char Winner (BT Board); char Turn (BT Board); char WillWin (BT Board, char t); FILE *in, *out; int main (int argc, char **argv) { int n; /* # of test cases */ BT Board; /* Tic-Tac-Toe board */ char Bstr[10]; in = fopen ("prob5.in","r"); /* redirect I/O */ out = fopen ("prob5.out","w"); for (fscanf (in,"%d",&n); n>0; n--) { /* read in test cases */ fscanf (in,"%s",Bstr); memcpy (Board,Bstr,sizeof Board); /* read in the board */ switch (WillWin (Board,Turn(Board))) { /* print winner */ case 'X': fprintf (out,"X wins the game.\n"); break; case 'O': fprintf (out,"O wins the game.\n"); break; default: fprintf (out,"The game goes to the cat.\n"); } } fclose (in); fclose (out); return EXIT_SUCCESS; } /* Winner checks a tic-tac-toe board to determine if someone has already won, i.e. if there are 3 in a row of the same mark. If so, it returns the winner, otherwise it returns 'T'. */ char Winner (BT Board) { int i; /* Loop iterator */ for (i = 0; i < 3; i++) { if (Board[i][0]==Board[i][1] && Board[i][0]==Board[i][2] && Board[i][0]!='B') return Board[i][0]; /* horizontal row */ if (Board[0][i]==Board[1][i] && Board[0][i]==Board[2][i] && Board[0][i]!='B') return Board[0][i]; /* vertical row */ } if (Board[0][0]==Board[1][1] && Board[0][0]==Board[2][2] && Board[0][0]!='B') return Board[0][0]; /* diagaonal rows */ if (Board[0][2]==Board[1][1] && Board[0][2]==Board[2][0] && Board[0][2]!='B') return Board[0][2]; return 'T'; } /* Turn returns whose turn it is by counting X's and O's. If the same, it's X's turn. Otherwise, it's O's turn. */ char Turn (BT Board) { int i, j, x=0; /* i and j are loop iterators; x counts the difference between x's and o's */ for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) switch (Board[i][j]) { case 'X': x++; break; case 'O': x--; } return (x==0)?'X':'O'; } /* WillWin looks at a board and whose turn it is anddetermines who will win this game if everyone makes the best possible move */ char WillWin (BT Board, char t) { char w, ww; int i, j; w = Winner (Board); /* Has anyone already won the game? */ if (w=='T') { /* If not ... */ w = ' '; for (i = 0; i < 3; i++) { /* Go through the empty squares one by */ for (j = 0; j < 3; j++) { /* one, and assume the next turn will */ if (Board[i][j] == 'B') { /* be to that square. */ Board[i][j] = t; ww = WillWin (Board,t=='X'?'O':'X'); /* Who wins now? */ Board[i][j] = 'B'; /* Remove my mark */ if (ww==t) return t; /* If I win, that's where I will move!*/ else if (ww=='T') w = 'T'; /* if it's a tie, I will move there for now and hope a better move will present itself */ else if (w==' ') w = ww; /* Losing is only the best move so far if it's the first one I check. */ } } } if (w==' ') return 'T'; /* If there is no legal move, it's a tie! */ } return w; /* otherwise return my best alternative */ }