Play Tic Tac Toe
By real programmers standards this is a dumb version. But it works, much to
my suprise. Give it a shot. Sometimes the simpler things are best.
Download a ziped microsoft DOS/windows executable ttt.zip 22.9 KB
I also found that this executable, compiled for microsoft, also runs with wine on linux.
Just download, unzip it, and type "wine ttt.exe" at the command line.
C++ Source Code:
//
// by Floyd Reed July 30, 2002
//
// so far pretty stupid, only fills in when win in one move
// will try to add blocking in one move and a larger play
// again loop. Would like a more general planning depth
// based on relative likelihood of outcomes but having trouble
// getting it that far
//
#include
#include // required for rand function
#include // required for srand seed with time
int print_board(char [3][3]);
int win_check(char [3][3]);
int computers_move (char [3][3]);
int main()
{
srand (time(NULL)); // uses time to seed random generator
int x,y,nStart;
int nWin = 0;
int nComputer=0;
int nPlayer=0;
int nDraw=0;
// flips a coin to see who starts
cout << "\nTick, Tack, Toe; Version 6\n by Reed-ware, 2002\n\n";
int nPlay=1;
char cPlay;
while (nPlay)
{
int nTotalTurns = 0;
cout << "Lets flip a coin to see who starts.\n"
<< "Enter your choice: heads (h) or tails (t)? ";
char cChoice;
cin >> cChoice;
char cCoinResult;
if (int (rand()%2) == 0) {cCoinResult='h';}
else {cCoinResult='t';}
cout << "Flip . . . " << cCoinResult << "\n";
if (cCoinResult == cChoice) {cout << "You win! Go first.\n"; nStart=1;}
else {cout << "I win! I'll go first.\n"; nStart=0;}
// creates and initializes the game board
char cBoard[3][3];
int i;
int j;
for (i=0; i<3; i++)
{
for (j=0; j<3; j++) {cBoard[i][j]=' ';}
}
while(1) // if go first picks an empty place on the board
{
if (nStart==1) {break;}
x=int(rand()%3);
y=int(rand()%3);
if (cBoard[x][y]==' ') {cBoard[x][y]='X'; break;}
int count3 = 0;
if (count3>1000) {cout << "\nError 4"; break;}
count3++;
}
if (nStart==0) {nTotalTurns++;}
print_board(cBoard);
// play the game until a win or draw
while(1)
{
// users move
while (1)
{
cout << "Your x coordinate: ";
cin >> x;
x--;
cout << "Your y coordinate: ";
cin >> y;
y--;
if (cBoard[x][y]==' ') {cBoard[x][y]='O'; break;}
else{cout<<"Not an option!\n";}
int count2 = 0;
if (count2>1000) {cout << "\nError 3"; break;}
count2++;
}
// print the board
print_board(cBoard);
// descides if there is a win
nWin = win_check(cBoard);
if (nWin!=0) {break;}
// descide if a draw, important to put this after the win check
nTotalTurns++;
if (nTotalTurns==9) {break;}
// computers move
int nMove;
nMove = computers_move(cBoard);
if (nMove==1) {x=0; y=0;}
if (nMove==2) {x=0; y=1;}
if (nMove==3) {x=0; y=2;}
if (nMove==4) {x=1; y=0;}
if (nMove==5) {x=1; y=1;}
if (nMove==6) {x=1; y=2;}
if (nMove==7) {x=2; y=0;}
if (nMove==8) {x=2; y=1;}
if (nMove==9) {x=2; y=2;}
cBoard[x][y]='X';
cout << "My move.\n";
// print the board
print_board(cBoard);
// descides if there is a win
nWin = win_check(cBoard);
if (nWin!=0) {break;}
// descide if a draw, important to put this after the win check
nTotalTurns++;
if (nTotalTurns==9) {break;}
int count = 0;
if (count>1000) {cout << "\nError 2"; break;}
count++;
}
if (nWin==1) {cout << "\nI won!!!\n";nComputer++;} // computer won
if (nWin==2) {cout << "\nYou won!!!\n";nPlayer++;} // user won
if (nWin==0) {cout << "\nIt's a draw.\n";nDraw++;} // 9 turns with no win
cout << "Computer: " << nComputer << ", Player: " << nPlayer << ", Draws: " << nDraw << "\n";
cout << "Want to play again? (y) or (n): ";
cin >> cPlay;
if (cPlay=='n') {nPlay=0;}
}
//cout << "\nHit a 1 and enter to close";
//int nWait;
//cin >> nWait;
return 0;
}
int print_board(char cBoard[3][3])
{
cout << "\n"
<< "\t1: " << cBoard[0][0] << "|" << cBoard[1][0] << "|" << cBoard[2][0] << "\n"
<< "\t -+-+-\n"
<< "\t2: " << cBoard[0][1] << "|" << cBoard[1][1] << "|" << cBoard[2][1] << "\n"
<< "\t -+-+-\n"
<< "\t3: " << cBoard[0][2] << "|" << cBoard[1][2] << "|" << cBoard[2][2] << "\n"
<< "\t 1 2 3\n\n";
return 0;
}
int win_check(char cBoard[3][3])
{
// descides if there is a win
int nWin=0;
int i;
for (i=0; i<3; i++) // scan columns
{
if (cBoard[i][0] == 'O' && cBoard[i][1] == 'O' && cBoard[i][2] == 'O')
{nWin=2;}
if (cBoard[i][0] == 'X' && cBoard[i][1] == 'X' && cBoard[i][2] == 'X')
{nWin=1;}
}
for (i=0; i<3; i++) // scan rows
{
if (cBoard[0][i] == 'O' && cBoard[1][i] == 'O' && cBoard[2][i] == 'O')
{nWin=2;}
if (cBoard[0][i] == 'X' && cBoard[1][i] == 'X' && cBoard[2][i] == 'X')
{nWin=1;}
}
// scan forward diagonal
if (cBoard[0][2] == 'O' && cBoard[1][1] == 'O' && cBoard[2][0] == 'O')
{nWin=2;}
if (cBoard[0][2] == 'X' && cBoard[1][1] == 'X' && cBoard[2][0] == 'X')
{nWin=1;}
// scan backward diagonal
if (cBoard[0][0] == 'O' && cBoard[1][1] == 'O' && cBoard[2][2] == 'O')
{nWin=2;}
if (cBoard[0][0] == 'X' && cBoard[1][1] == 'X' && cBoard[2][2] == 'X')
{nWin=1;}
return nWin;
}
int computers_move (char cBoard[3][3])
{
//srand (time(NULL));
int x, y;
int nMove;
int nNextMove=0;
int nWin = 0;
int nLookAhead = 4;
int nReplicates = 100;
int nOutcome[9][2]; // stores results of next possible outcomes
int i;
int j;
int k;
// int l;
// sets outcome array
for (i=0; i<9; i++)
{
for (j=0; j<2; j++) {nOutcome[i][j]=0;}
}
char cBoardCopy[3][3];
for (i=0; i<3; i++)
{
for (j=0; j<3; j++)
{
cBoardCopy[i][j]=cBoard[i][j];
}
}
// DEFENSE
// looks for a lose in one move and blocks it
for (i=0; i1000) {cout << "\nError 1"; break;}
count++;
}
// sorts out position code
if (x==0)
{
if (y==0) {nMove=1;}
if (y==1) {nMove=2;}
if (y==2) {nMove=3;}
}
if (x==1)
{
if (y==0) {nMove=4;}
if (y==1) {nMove=5;}
if (y==2) {nMove=6;}
}
if (x==2)
{
if (y==0) {nMove=7;}
if (y==1) {nMove=8;}
if (y==2) {nMove=9;}
}
// descides if there is a lose in 1 move
nWin = win_check(cBoardCopy);
if (nWin==2) // if there is a win in 1 move break and return coordinates
{
nNextMove=nMove; // stores winning move as next move
break;
cBoardCopy[x][y]=' '; // reset board
}
// reset board
for (k=0; k<3; k++)
{
for (j=0; j<3; j++)
{
cBoardCopy[k][j]=cBoard[k][j];
}
}
} // close replicate loop
// OFFENSE
// looks for a win in one move and takes it
// tries random possible next moves
for (i=0; i1000) {cout << "\nError 1"; break;}
count++;
}
// sorts out position code
if (x==0)
{
if (y==0) {nMove=1;}
if (y==1) {nMove=2;}
if (y==2) {nMove=3;}
}
if (x==1)
{
if (y==0) {nMove=4;}
if (y==1) {nMove=5;}
if (y==2) {nMove=6;}
}
if (x==2)
{
if (y==0) {nMove=7;}
if (y==1) {nMove=8;}
if (y==2) {nMove=9;}
}
// descides if there is a win in 1 move
nWin = win_check(cBoardCopy);
if (nWin==1) // if there is a win in 1 move break and return coordinates
{
nNextMove=nMove; // stores winning move as next move
break;
cBoardCopy[x][y]=' '; // reset board
}
/* this next section hangs up the program
for(l=0; l1000) {cout << "\nError 5"; break;}
count2++;
}
// descides if there is a win
nWin = win_check(cBoardCopy);
if (nWin == 1) {nOutcome[nMove-1][0]++;break;} // computer wins
if (nWin == 2) {nOutcome[nMove-1][1]++;break;} // user wins
if (nWin == 3) {break;} // a draw
// simulates computers move
while(1) // picks an empty place on the board
{
x=int(rand()%3);
y=int(rand()%3);
if (cBoardCopy[x][y]==' ') {cBoardCopy[x][y]='X'; break;}
int count3 = 0;
if (count3>1000) {cout << "\nError 6"; break;}
count3++;
}
// descides if there is a win
nWin = win_check(cBoardCopy);
if (nWin == 1) {nOutcome[nMove-1][0]++;break;} // computer wins
if (nWin == 2) {nOutcome[nMove-1][1]++;break;} // user wins
if (nWin == 3) {break;} // a draw
} // close look ahead loop
//cout << "\n" << nMove;
//for (j=0; j<9; j++)
//{
// cout << " " << nOutcome[j][0];
//}
*/
// reset board
for (k=0; k<3; k++)
{
for (j=0; j<3; j++)
{
cBoardCopy[k][j]=cBoard[k][j];
}
}
} // close replicate loop
if (nNextMove == 0) // if no wins or losses picks randomly
{
while(1) // picks an empty place on the board
{
x=int(rand()%3);
y=int(rand()%3);
if (cBoardCopy[x][y]==' ') {cBoardCopy[x][y]='X'; break;}
}
// sorts out position code
if (x==0)
{
if (y==0) {nMove=1;}
if (y==1) {nMove=2;}
if (y==2) {nMove=3;}
}
if (x==1)
{
if (y==0) {nMove=4;}
if (y==1) {nMove=5;}
if (y==2) {nMove=6;}
}
if (x==2)
{
if (y==0) {nMove=7;}
if (y==1) {nMove=8;}
if (y==2) {nMove=9;}
}
nNextMove=nMove;
}
return nNextMove;
}
C Programming | Floyd's Home | MountainSmoke.com
Copyright: © Floyd A. Reed 1996-2003, all rights reserved.
URL: http://www.mountainsmoke.com/floyd/pi.htm
Contact: floyd@mountainsmoke.com
Revised: Thursday February 13, 2003