-
OO Tic-Tac-Toe
My assignment was to create and OOP in C++ that would play against the user, but didn't necessarily need to use "AI"; it could randomly choose a tile. This is my third complete rewrite of the program, because I had too many objects before and didn't understand some of the concepts, but it still doesn't work correctly.
The problem, I believe, lies in the "makeMove()" method. In one compilation, it actually worked as intended (I thought...), but now, no X's or O's are actually placed in the board, and no one ever "wins".
Any help or tracking down my errors is appreciated; this program is already past-due, so I will be up for the next 6-8 hours reading line-by-line. Thanks in advance for any help...
Code:
#include <iostream>
class TicTacToe {
public:
char space[3][3]; // [row][col]
char turn; // X or O
char winner; //X O C or empty space
TicTacToe() { //constructor
int iTurn;
iTurn = (rand() % 2) + 1;
turn = (iTurn = 1) ? 'X' : 'O';
winner = ' ';
int i,j;
for (i=0; i<=2; i++) {
for (j=0; j<=2; j++) {
space[i][j] = ' ';
}
}
} //end constructor
void drawBoard(void);
void checkWin(void);
int userMove(void);
int AIMove(void);
int makeMove(int, char);
} ; //end class TicTacToe
void TicTacToe::drawBoard(void) {
using namespace std;
system("cls");
cout << "\n\n\t\t\t|\t|\t\n" ;
cout << "\t\t " << space[0][0] << "\t| " << space[0][1] << "\t| " << space[0][2] << endl;
cout << "\t\t\t|\t|\n" ;
cout << "\t\t--------|-------|--------\n" ;
cout << "\t\t\t|\t|\n" ;
cout << "\t\t " << space[1][0] << "\t| " << space[1][1] << "\t| " << space[1][2] << endl;
cout << "\t\t\t|\t|\n" ;
cout << "\t\t--------|-------|--------\n" ;
cout << "\t\t\t|\t|\n" ;
cout << "\t\t " << space[2][0] << "\t| " << space[2][1] << "\t| " << space[2][2] << endl;
cout << "\t\t\t|\t|\n" ;
} //end def drawBoard
void TicTacToe::checkWin(void) {
char returnValue = ' ';
//test for X or O win
//test rows
if ( (space[0][0] == space[0][1]) && (space[0][0] == space[0][2]) )
returnValue = space[0][0];
else if ( (space[1][0] == space[1][1]) && (space[1][0] == space[1][2]) )
returnValue = space[1][0];
else if ( (space[2][0] == space[2][1]) && (space[2][0] == space[2][2]) )
returnValue = space[2][0];
//test columns
else if ( (space[0][0] == space[1][0]) && (space[0][0] == space[2][0]) )
returnValue = space[0][0];
else if ( (space[0][1] == space[1][1]) && (space[0][1] == space[2][1]) )
returnValue = space[0][1];
else if ( (space[0][2] == space[1][2]) && (space[0][2] == space[2][2]) )
returnValue = space[0][2];
//test diagonals
else if ( (space[0][0] == space[1][1]) && (space[0][0] == space[2][2]) )
returnValue = space[0][0];
else if ( (space[0][2] == space[1][1]) && (space[0][2] == space[2][0]) )
returnValue = space[0][2];
if ( returnValue != ' ' ) { //then test for cat
int i, j, catCheck=0;
for (i=0; i<=2; i++) {
for (j=0; j<=2; j++) {
if ( space[i][j] == ' ' )
catCheck++;
}
}
if ( catCheck == 0 )
returnValue = 'C';
}
winner = returnValue;
} //end def checkWin
int TicTacToe::userMove(void) {
using namespace std;
int userChoice=0;
while ( userChoice < 1 || userChoice > 9 ) {
cout << "\n\nEnter a square [1-9]: ";
cin >> userChoice;
} //end while
} //end def userMove
int TicTacToe::AIMove(void) {
int returnValue = rand() * 9 + 1;
return returnValue;
} //end def AIMove
int TicTacToe::makeMove(int intSpace, char player) {
int returnValue;
switch (intSpace) {
case 1:
if ( space[0][0] == ' ' ) {
space[0][0] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 2:
if ( space[0][1] == ' ' ) {
space[0][1] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 3:
if ( space[0][2] == ' ' ) {
space[0][2] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 4:
if ( space[1][0] == ' ' ) {
space[1][0] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 5:
if ( space[1][1] == ' ' ) {
space[1][1] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 6:
if ( space[1][2] == ' ' ) {
space[1][2] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 7:
if ( space[2][0] == ' ' ) {
space[2][0] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 8:
if ( space[2][1] == ' ' ) {
space[2][1] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 9:
if ( space[2][2] == ' ' ) {
space[2][2] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
} //end switch
return returnValue;
} //end def makeMove
main() {
using namespace std;
srand(time(NULL));
TicTacToe Game;
int intSpace;
while ( Game.winner == ' ' ) {
Game.drawBoard();
if ( Game.turn == 'X' ) {
doOver1:
intSpace = Game.AIMove();
if ( Game.makeMove(intSpace, 'X') == 0 )
goto doOver1;
Game.turn = 'O';
}
if ( Game.turn == 'O' ) {
doOver2:
intSpace = Game.userMove();
if ( Game.makeMove(intSpace, 'O') == 0 )
goto doOver2;
Game.turn = 'X';
}
Game.checkWin();
} //end while
if ( Game.winner != 'C' )
cout << "\n\n" << Game.winner << " wins!" << endl;
else
cout << "\n\n Cat wins!" << endl;
} //end def main
-
One problem (that the compiler might be able to point out if you enabled compiler warnings) is that userMove doesn't return a value.
Side note:
Code:
switch (intSpace) {
case 1:
if ( space[0][0] == ' ' ) {
space[0][0] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
case 2:
if ( space[0][1] == ' ' ) {
space[0][1] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
//...
case 9:
if ( space[2][2] == ' ' ) {
space[2][2] = player;
returnValue = 1;
}
else
returnValue = 0;
break;
} //end switch
You could observe that the first index is (intSpace - 1) / 3 and the second index is (intSpace - 1) % 3. ;)
-
Thank you! I found that one of my rand() function calls was being multiplied by 8 instead of % by it. Thanks for your response. I was trying to figure out a more efficient way of doing the array assignment with intSpace, but I needed to fix the rest of the program first and more importantly, so I just did it that way. But thanks for your help!