#include <iostream>
usingnamespace std;
class TicTacToe{
private:
char theBoard [3][3];
public:
TicTacToe(void);
void playOneGame(void);
void switchPlayer(char &);
void showBoard(void);
void postMove(int, int, char);
char determineWinner(void);
};
int main (void){
//test the class by playing one game
TicTacToe Game1;
Game1.playOneGame();
}
void TicTacToe::playOneGame(void){
//start a game and play until someone wins or a draw occurs...
constint MaxMoves = 9;
char currentPlayer = 'O';
int row = 0;
int clmn = 0;
char theWinner = ' ';
int nmbrOfMoves = 0; //keep track of the number of moves max is 9
do {
switchPlayer(currentPlayer); //change player from x to o or vice versa
showBoard();
cout << "\n\nPlayer " << currentPlayer << endl; //get the players move
cout << "Enter row of move (1, 2, 3): ";
cin >> row;
cout << "Enter column of move (1, 2, 3): ";
cin >> clmn;
postMove(row -1, clmn -1, currentPlayer); //post the move to the board
theWinner = determineWinner(); //see if anyone won the game
nmbrOfMoves++; //keep track of the number of moves
} while ((theWinner != 'D') && (nmbrOfMoves != MaxMoves));
showBoard(); //show the ending board
if (theWinner == 'D') //declare a winner
cout << "\n\nThe Game was a Draw" << endl;
else
cout << "\n\nThe Winner is player " << theWinner << endl;
}
TicTacToe::TicTacToe(void){
//intialize the array contents
for (int row = 0; row < 3; row++){
for (int clmn = 0; clmn < 3; clmn++){
theBoard[row][clmn] = '-';
}
}
}
void TicTacToe::switchPlayer(char ¤tPlayer){
//switches the current player
if (currentPlayer == 'O'){
currentPlayer = 'X';
}
else (currentPlayer = 'O');
}
void TicTacToe::showBoard(){
//displays the board
cout << endl;
for (int row=0; row<3; row++){
for (int clmn = 0; clmn < 3; clmn++){
cout << "["<< theBoard[row][clmn] << "]";
}
cout << endl;
}
cout << endl;
}
void TicTacToe::postMove(int row, int clmn, char value){
//gets the users move and posts it to the board
theBoard[row][clmn] = value;
}
char TicTacToe::determineWinner(void){
//analyzes the board to see if there is a winner
//returns a X, O indicating the winner
//if the game is a draw then D is returned
//check the rows
for (int i = 0; i < 3; i++){
if (theBoard[i][0] == theBoard[i][1]
&& theBoard[i][1] == theBoard[i][2]
&& theBoard[i][0] != ' '){
return theBoard[i][0];
}
}
//check the clmns
for (int i = 0; i < 3; i++){
if (theBoard[0][i] == theBoard[1][i]
&& theBoard[1][i] == theBoard[2][i]
&& theBoard[0][i] != ' '){
return theBoard[0][i];
}
}
//check the diagnals
if (theBoard[0][0] == theBoard[1][1]
&& theBoard[1][1] == theBoard[2][2]
&& theBoard[0][0] != ' ') {
return theBoard[0][0];
}
if (theBoard[2][0] == theBoard[1][1]
&& theBoard[1][1] == theBoard[0][2]
&& theBoard[2][0] != ' ') {
return theBoard[2][0];
}
return'D';
}
With this macro, you can access the elements of a linear array as if it was a rectangular matrix:
1 2 3 4 5
/*
If you have a an Array[12], but want to access it as if it was an Array[4][3]
(4 rows and 3 columns) you use ARRAY_TO_MATRIX(Array,1,2,3)
*/
#define ARRAY_TO_MATRIX(array,y,x,width) (array)[(x)+(y)*(width)]
What Zaita is saying is that you need to not only check to see if theWinner equal to D, but also check if it is equal to is X or O.
Let me explain in an example:
X beats O so you assign theWinner to X on line 40. Then line 40 will exectute then execution goes to line 43 where the line would evaluate to read:
while(("X' != 'D') && (nmbrOfMoves != MaxMoves));
assuming that you are not our of moves, X != D returns true thus the loop iterates again.
To fix this you must add a clause (another (___ != ___ ) || (____ !=____ ) statement) within the while conditional of the while loop on 43. HINT: it will look a lot like the first clause, but with diffrent letters)
Although. I would look at changing what your determineWinner function returns.
It should return ' ' if it cannot determine a winner. And should check if all spaces are filled, and be able to declare a draw. Then you could just have
You don't necessarily have to check every possible placement. Once you postMove( row, col, players_piece );
immediately check to see whether it was a winning move:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
bool TickTackToe::IsWinningMove( int row, int col )
{
int count[ 4 ] = { 0 };
char c = board[ row ][ col ];
for (int n = 0; n < 3; n++)
{
count[ 0 ] += board[ row ][ n ] == c;
count[ 1 ] += board[ n ][ col ] == c;
count[ 3 ] += board[ n ][ n ] == c;
count[ 4 ] += board[ 2-n ][ n ] == c;
}
for (int n = 0; n < 4; n++)
if (count[ n ] == 3) returntrue;
returnfalse;
}
To determine if the game is a draw, just keep track of the number of moves posted. If the ninth move doesn't provide a winner, then the game is a draw.