Public Group

# Tic Tac Toe

This topic is 4614 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I stopped programming for a while and I'm now starting again. I forgot some of C++ so I decided to make a 2 player tic tac toe game to try to remember some things. I would appreciate it if you commented about the code. Thanks.
#include <iostream>

using namespace std;

char Board[9]={'1','2','3','4','5','6','7','8','9'};
int Move=1;

void ResetBoard()
{
Board[0]='1';
Board[1]='2';
Board[2]='3';
Board[3]='4';
Board[4]='5';
Board[5]='6';
Board[6]='7';
Board[7]='8';
Board[8]='9';

system("CLS");
}

void DrawBoard()
{
cout<<"\n\n "<<Board[0]<<" | "<<Board[1]<<" | "<<Board[2]<<endl;
cout<<"---+---+---"<<endl;
cout<<" "<<Board[3]<<" | "<<Board[4]<<" | "<<Board[5]<<endl;
cout<<"---+---+---"<<endl;
cout<<" "<<Board[6]<<" | "<<Board[7]<<" | "<<Board[8]<<endl;

}

void PlayAgain()
{
char Again;
cout<<"Do you want to play again? (Y or N)";
cin>>Again;
if(Again=='y' || Again=='Y')
{
Move=1;
ResetBoard();
DrawBoard();
}
else if(Again=='n' || Again=='N')
exit(0);

else
PlayAgain();
}

void CheckBoard() //checks to see if someone has won
{
if(Board[0]=='X'&&Board[1]=='X'&&Board[2]=='X'||
Board[0]=='X'&&Board[3]=='X'&&Board[6]=='X'||
Board[0]=='X'&&Board[4]=='X'&&Board[8]=='X'||
Board[1]=='X'&&Board[4]=='X'&&Board[7]=='X'||
Board[6]=='X'&&Board[7]=='X'&&Board[8]=='X'||
Board[2]=='X'&&Board[5]=='X'&&Board[8]=='X'||
Board[6]=='X'&&Board[4]=='X'&&Board[2]=='X'||
Board[3]=='X'&&Board[4]=='X'&&Board[5]=='X')
{
cout<<"Congratulations Player 1!"<<endl;
PlayAgain();
}
else if(Board[0]=='O'&&Board[1]=='O'&&Board[2]=='O'||
Board[0]=='O'&&Board[3]=='O'&&Board[6]=='O'||
Board[1]=='O'&&Board[4]=='O'&&Board[7]=='O'||
Board[0]=='O'&&Board[4]=='O'&&Board[8]=='O'||
Board[6]=='O'&&Board[7]=='O'&&Board[8]=='O'||
Board[2]=='O'&&Board[5]=='O'&&Board[8]=='O'||
Board[6]=='O'&&Board[4]=='O'&&Board[2]=='O'||
Board[3]=='O'&&Board[4]=='O'&&Board[5]=='O')
{
cout<<"Congratulations Player 2!"<<endl;
PlayAgain();
}

else if(Move==10)
{
cout<<"It's a tie!"<<endl;
PlayAgain();
}

}

void MainGame2()
{
int move;

CheckBoard();
cout<<"\nPlayer 2: ";
cin>>move;
if(move>0 && move<10 && Board[move-1]!='X' && Board[move-1]!='O')
{
Board[move-1]='O';

system("CLS");

DrawBoard();
Move++;
CheckBoard();

}
else
MainGame2();

}

void MainGame()
{

int move2;

CheckBoard();
cout<<"\nPlayer 1: ";
cin>>move2;
if(move2>0 && move2<10 && Board[move2-1]!='X' && Board[move2-1]!='O')
{
Board[move2-1]='X';

system("CLS");
DrawBoard();
Move++;
CheckBoard();

MainGame2();

}

else
MainGame();

}

int main()
{
DrawBoard();
while(Move>0 && Move<10)
{
MainGame();
}

return 0;

}



##### Share on other sites

For one, you need to take all of your recursive calls out of the code. You do this in MainGame(), MainGame2() and PlayAgain(). In MainGame(), if the player inputs a bad square, you call MainGame() again. This is called recursion and is not good logic (linear) flow. Instead, do a bool valid_move = false; while( valid_move == false ) { /**/ } to check for valid input. Same situation with MainGame2() and PlayAgain(). You should always have your functions return instead of calling other functions (that themselves call the same functions).

As for code structure, I'd recommend keeping a current_player flag, and combining MainGame() and MainGame2(). Also, have CheckBoard() tell you who won, instead of calling yet more functions. You can do this by having CheckBoard return a 0, 1, 2 or 3 for nobody, player 1, player 2 and tie respectively.

As well, your MainGame() should return a still_playing condition, replacing the current valid move conditional in main().

Some clearer variable names would help, too, like p1_movecount. Or, better still, you can get rid of both of those and just rely on CheckBoard() for end of game, ie., you don't need to keep track of a player's move count, as CheckBoard() will decide if there's a winner or all squares are filled anyway.

Other than that it looks good. Keep up the good work! [smile]

##### Share on other sites
Quote:
 Original post by stylinA few comments:For one, you need to take all of your recursive calls out of the code. You do this in MainGame(), MainGame2() and PlayAgain(). In MainGame(), if the player inputs a bad square, you call MainGame() again. This is called recursion and is not good logic (linear) flow. Instead, do a bool valid_move = false; while( valid_move == false ) { /**/ } to check for valid input. Same situation with MainGame2() and PlayAgain(). You should always have your functions return instead of calling other functions (that themselves call the same functions).As for code structure, I'd recommend keeping a current_player flag, and combining MainGame() and MainGame2(). Also, have CheckBoard() tell you who won, instead of calling yet more functions. You can do this by having CheckBoard return a 0, 1, 2 or 3 for nobody, player 1, player 2 and tie respectively.As well, your MainGame() should return a still_playing condition, replacing the current valid move conditional in main().Some clearer variable names would help, too, like p1_movecount. Or, better still, you can get rid of both of those and just rely on CheckBoard() for end of game, ie., you don't need to keep track of a player's move count, as CheckBoard() will decide if there's a winner or all squares are filled anyway.Other than that it looks good. Keep up the good work! [smile]

Just a clarification. While recursion isn't a good choice in this particular case, it is a powerful tool in the right situation. Tree and graph traversal come to mind. [smile]

##### Share on other sites
Also, if you're interested in form, I find it very interesting how you write it out. It seems very cluttered, doesn't seem to have a solid, noticable structure. There seems to be no spaces where ever they can be spared, etc. I suppose if it's not an important thing to you to have your code be accessable by a third party, it's fine. Just my two cents.

-IV

##### Share on other sites
Building on what IV said, the code will become a lot more readable if you add comments. You might think that it is fairly simple and so doesn't need them, but I think that all code needs comments. I even put them in Hello World [smile]

##### Share on other sites
Why do you fill the Board array with these numbers? I don't get it.
char Board[9]={'1','2','3','4','5','6','7','8','9'};void ResetBoard() {    Board[0]='1';    Board[1]='2';    Board[2]='3';    Board[3]='4';    Board[4]='5';    Board[5]='6';    Board[6]='7';    Board[7]='8';    Board[8]='9';}

##### Share on other sites
It seems like a reasonable thing to do so the players know what number to input for what square.

To the OP: Out of curiosity, did you come from a background programming in a BASIC like language? I have a friend who did, and he used recursion just like they were goto's, like in your code.

##### Share on other sites

bjle, you are correct, I started programming in BASIC, but I'm getting better at not using goto's. I just couldn't think of what to use other than goto's, but then I thought of recursion and so I used it.

• 10
• 17
• 9
• 14
• 41
• ### Forum Statistics

• Total Topics
631067
• Total Posts
2997738
×