/* * We represent a game board by an array of 9 squares. * Each square is either 'x', 'o', or ' '. * So a game position is an array of 9 chars, but is not a string. * * Players, whose turn it is, etc, are represented by 'x' or 'o'. */ #include extern void clearboard(char *b); extern void printboard(char *b); extern char isover(char *b); /* returns winner or ' ', or 0 if not over */ extern void computermove(char *b, char player); extern void usermove(char *b, char player); extern char otherplayer(char player); int main() { char board[9]; char whoseturn = 'x'; char personplayer = 'x'; clearboard(board); while (!isover(board)) { printboard(board); if (whoseturn == personplayer) usermove(board, whoseturn); else computermove(board, whoseturn); whoseturn = otherplayer(whoseturn); } if (isover(board) == ' ') printf("draw\n"); else printf("%c won\n", isover(board)); return 0; } char isover(char *b) { extern int iswinner(char *b, char player), isdraw(char *b); if (iswinner(b, 'x')) return 'x'; if (iswinner(b, 'o')) return 'o'; if (isdraw(b)) return ' '; return 0; } int iswinner(char *b, char player) { int i; extern int horizwin(char *b, char player, int row); extern int vertwin(char *b, char player, int col); extern int diagwin(char *b, char player, int ismaindiag); for (i = 0; i < 3; i++) if (horizwin(b, player, i) || vertwin(b, player, i)) return 1; return diagwin(b, player, 0) || diagwin(b, player, 1); } int isdraw(char *b) { int i; for (i = 0; i < 9; i++) if (b[i] == ' ') return 0; return 1; } int horizwin(char *b, char player, int row) { int i; for (i = 0; i < 3; i++) if (b[row * 3 + i] != player) return 0; return 1; } int vertwin(char *b, char player, int col) { int i; for (i = 0; i < 3; i++) if (b[i * 3 + col] != player) return 0; return 1; } int diagwin(char *b, char player, int ismaindiag) { int i; if (ismaindiag) { for (i = 0; i <= 8; i += 4) if (b[i] != player) return 0; } else { for (i = 2; i <= 6; i += 2) if (b[i] != player) return 0; } return 1; } void computermove(char *b, char player) { int i; int bestsofar = -2; int bestmove; extern int howgood(char *pos, char player); for (i = 0; i < 9; i++) { /* how good is it if we move at loc 'i'? */ if (b[i] == ' ') { int rhowgood; b[i] = player; rhowgood = -howgood(b, otherplayer(player)); b[i] = ' '; if (rhowgood > bestsofar) { bestsofar = rhowgood; bestmove = i; } } } printf("I move at %d\n", bestmove); b[bestmove] = player; } /* * howgood(position, player) says how good that position is for that player, * if it's that player's move. * * Return value: * -1: player is going to lose (if both players play optimally) * 0: tie (if both players play optimally) * 1: player is going to win (if both players play optimally) */ int howgood(char *pos, char player) { int i, bestsofar, rhowgood; if (isdraw(pos)) return 0; if (iswinner(pos, player)) return 1; if (iswinner(pos, otherplayer(player))) return -1; bestsofar = -1; for (i = 0; i < 9; i++) { /* how good is it if we move at loc 'i'? */ if (pos[i] == ' ') { pos[i] = player; rhowgood = -howgood(pos, otherplayer(player)); pos[i] = ' '; if (rhowgood > bestsofar) bestsofar = rhowgood; } } return bestsofar; } void usermove(char *b, char player) { int i; printf("Enter your move, and I don't have time for error checking\n"); scanf("%d", &i); b[i] = player; } char otherplayer(char player) { return (player == 'x') ? 'o' : 'x'; } void clearboard(char *b) { int i; for (i = 0; i < 9; i++) b[i] = ' '; } void printboard(char *b) { extern void printrow(char *b); printrow(b); printf("---+---+---\n"); printrow(b + 3); printf("---+---+---\n"); printrow(b + 6); } void printrow(char *b) { printf(" %c | %c | %c\n", b[0], b[1], b[2]); }