codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> struct State { int result; /* Stores the result: 0 is in progress, 1 is X Win, 2 is 0 Win, 3 is Cats Game */ int turn; /* Stores the number of turns since the current state. */ char currentPlayer; /* Stores the piece of the player whos turn it is. */ char board[3][3]; /* Stores information about the board. */ }; void setupNextState(struct State*, struct State*); void initializeState(struct State*); void initializeBoard(struct State*); void drawBoard(struct State*); void placeRandomPiece(struct State*); char checkForWinner(struct State* state); void clearScreen(); /* TaccyAI: A Tic-Tac-Toe AI Engine */ void TaccyRandomPiece(struct State* ); void TaccyMakeMove(struct State*); short TaccyStopMakeWin(struct State*, char); short TaccyBlockCorner(struct State*); int main(void) { struct State state[10]; /* The current state of our game. */ int x = -1, y = -1; /* Used for holding input of user/ coordinates */ short validCoordinates = 0; /* Used for looping until user enters valid coordinates. */ short currentState = 0; /* Holds the current state we're in */ char winner = ' '; /* Holds value of winner if applicable */ srand((int)time(0)); /* Seed RNG */ initializeState(&state[currentState]); printf("You are about to play against the TaccyAI, Tic-Tac-Toe Bot.\n"); printf("Try not to get too frustrated, but he never loses.\n"); printf("The best you can hope for is a cat's game.\n\n"); printf("Good luck and have fun!\n\n"); printf("Programmed by Joseph 'Ninwa' Bleau\n"); printf("(PS: I am not responsible for keyboards broken out of furstration.)\n\n"); system("pause"); while(state[currentState].turn != 10&& state[currentState].result == 0) { clearScreen(); drawBoard(&state[currentState]); if(state[currentState].turn % 2 == 0){ state[currentState].currentPlayer = 'O'; validCoordinates = 0; /* Reset checker. */ while(validCoordinates == 0){ printf("Enter coordinates to place your mark (e.g 0,1): "); scanf("%i,%i",&y,&x); /* Check range on coordinates */ if( x < 3 && x >= 0 && y < 3 && y >= 0 ){ /* Check that a piece is not already there. */ if( state[currentState].board[y][x] == ' ' ){ /* Everything checks out, place our piece. */ validCoordinates = 1; state[currentState].board[y][x] = 'O'; } else printf("\nThose were invalid coordinates, try again!\n"); } else{ printf("\nThose were invalid coordinates, try again!\n"); fflush(stdin); } } } else{ /* CPU's Turn (TaccyAI) */ state[currentState].currentPlayer = 'X'; TaccyMakeMove(&state[currentState]); } if(state[currentState].turn > 4){ /* Assess Board, is there a winner? */ winner = checkForWinner(&state[currentState]); if(winner != ' '){ clearScreen(); if(winner == 'X') state[currentState].result = 1; else if(winner == 'O') state[currentState].result = 2; if( winner != 'C' ) printf("There was a winner! \nCongratulations player '%c'\n\n",winner); else{ printf("I guess there was a cats game! Oh well, nice try both of you! :)\n\n"); state[currentState].result = 3; } printf("Final board:\n\n"); drawBoard(&state[currentState]); continue; } } setupNextState(&state[currentState],&state[currentState+1]); currentState++; } return 0; } void TaccyRandomPiece(struct State* state) { short piecePlaced = 0; int y,x; while(piecePlaced == 0) { x = rand()%3; y = rand()%3; if( state->board[y][x] == ' ' ){ piecePlaced = 1; state->board[y][x] = 'X'; } } } short TaccyBlockCorner(struct State* state) { //[x] [ ] //[ ] [ ] if( state->board[0][0] == 'X' ){ if(state->board[0][2] == ' '){ state->board[0][2] = 'X'; return 1; } if(state->board[2][0] == ' '){ state->board[2][0] = 'X'; return 1; } } //[ ] [x] //[ ] [ ] if( state->board[0][2] == 'X' ){ if(state->board[0][0] == ' '){ state->board[0][0] = 'X'; return 1; } if(state->board[2][2] == ' '){ state->board[2][2] = 'X'; return 1; } } //[ ] [ ] //[ ] [x] if( state->board[2][2] == 'X' ){ if(state->board[0][2] == ' '){ state->board[0][2] = 'X'; return 1; } if(state->board[2][0] == ' '){ state->board[2][0] = 'X'; return 1; } } //[ ] [ ] //[x] [ ] if( state->board[2][0] == 'X' ){ if(state->board[0][0] == ' '){ state->board[0][0] = 'X'; return 1; } if(state->board[2][2] == ' '){ state->board[2][2] = 'X'; return 1; } } if( state->board[0][2] == 'X' && state->board[0][0] == ' '){ state->board[0][0] = 'X'; return 1; } if( state->board[0][0] == 'O' && state->board[2][2] == ' ' ){ state->board[2][2] = 'X'; return 1; } if( state->board[0][2] == 'O' && state->board[2][0] == ' '){ state->board[2][0] = 'X'; return 1; } if( state->board[2][2] == 'O' && state->board[0][0] == ' ' ){ state->board[0][0] = 'X'; return 1; } if( state->board[2][0] == 'O' && state->board[0][2] == ' ' ){ state->board[0][2] = 'X'; return 1; } return 0; } short TaccyStopMakeWin(struct State* state, char check_for) { int i,j; for(i=0;i<3;i++){ for(j=0;j<3;j++){ if(state->board[i][j] == ' ') { state->board[i][j] = check_for; if(checkForWinner(state) == check_for){ state->board[i][j] = 'X'; return 1; } else{ state->board[i][j] = ' '; } } } } return 0; } short TaccyCheckEnemyCorners(struct State* state) { int counter = 0; if(state->board[0][0] == 'O') counter++; if(state->board[0][2] == 'O') counter++; if(state->board[2][2] == 'O') counter++; if(state->board[2][0] == 'O') counter++; if( counter > 1) { if( state->board[1][0] == ' ' ){ state->board[1][0] = 'X'; return 1; } if( state->board[2][1] == ' ' ){ state->board[2][1] = 'X'; return 1; } if( state->board[1][2] == ' '){ state->board[1][2] = 'X'; return 1; } if( state->board[0][1] == ' '){ state->board[0][1] = 'X'; return 1; } } return 0; } void TaccyMakeMove(struct State* state) { /* Easter egg. One out of approximately every fifty game the computer cheats and fills out the entire board. :o) */ int r = rand()%50; int i,j; if(r == 7) /* 7 is my favorite number :) */{ for( i=0; i<3; i++ ){ for( j=0; j<3; j++ ) { if( state->board[i][j] != 'O' ) state->board[i][j] = 'X'; } } return; } if(state->turn < 2 && state->board[1][1] == 'O'){ state->board[2][2] = 'X'; return; } if(TaccyStopMakeWin(state,'X') == 1) return; if(TaccyStopMakeWin(state,'O') == 1) return; if(state->board[1][1] == ' '){ state->board[1][1] = 'X'; return; } if( state->board[1][1] == 'X' ) if(TaccyCheckEnemyCorners(state) == 1) return; if(TaccyBlockCorner(state) == 1) return; /* Realistically, this shouldn't happen. */ TaccyRandomPiece(state); } void setupNextState(struct State* s1, struct State* s2) { int i, j; s2->turn = s1->turn+1; s2->result = s1->result; if( s1->currentPlayer == 'X' ) s2->currentPlayer = 'O'; else s2->currentPlayer = 'X'; for(i=0;i<3;i++) for(j=0;j<3;j++) s2->board[i][j] = s1->board[i][j]; } void initializeState(struct State* state) { state->turn = 0; state->currentPlayer = 'X'; state->result = 0; initializeBoard(state); } void initializeBoard(struct State* state) { int i, j; for(i = 0; i < 3; i++){ for(j = 0; j <3; j++){ state->board[i][j] = ' '; } } } /* Checks the board within the state for a winner. /* Return Values: /* '\0' - No Winner /* '0' - Player ('O') is the winner /* 'X' - CPU ('X') is the winner */ char checkForWinner(struct State* state) { int i,j; for(i=0;i<3;i++){ if( state->board[i][0] != ' ' ){ if( state->board[i][0] == state->board[i][1] && state->board[i][1] == state->board[i][2] ) return state->board[i][0]; } if( state->board[0][i] != ' ' ){ if( state->board[0][i] == state->board[1][i] && state->board[1][i] == state->board[2][i] ) return state->board[0][i]; } } for(i=0,j=2;i<=2;i+=2,j-=2){ if( state->board[0][i] != ' ' ){ if( state->board[0][i] == state->board[1][1] && state->board[1][1] == state->board[2][j] ) return state->board[0][i]; } } /* Check to see if all positions are filled with no win, aka cats-game. */ for(i=0;i<3;i++) for(j=0;j<3;j++){ if( state->board[i][j] == ' ' ) return ' '; } return 'C'; } void drawBoard(struct State* state) { int i,j; printf(" | 0 | 1 | 2 |\n"); printf(" +-----------+\n"); for(i=0;i<3;i++){ for(j=0;j<3;j++){ if(j == 0 ) printf(" %i ",i); printf("| %c ", state->board[j][i]); } printf("|\n"); } printf(" +-----------+\n\n"); } void clearScreen() { /* Stupid utility function to clear the screen by printing 80 newlines. */ int i; for(i = 0; i < 80; i++) printf("\n"); }
Private
[
?
]
Run code
Submit