# C++ Tic Tac Toe - A draw?

• 04-28-2012
C++ Tic Tac Toe - A draw?
Helle everyone, doing a project in school and i'm quite bad at C++. I've made a game of Tic Tac Toe with some inspiration from the internet. Well, i've run into a problem which is most likely easily fixed (assuming you know what you're doing unlike me), regarding the detection of a draw. The program recognises if X or O wins, but not if it's a draw, and everytime i've attempted to fix it i've messed it up.

Suggestions on how to complete the code? And critique of my poor coding is also welcome :) (also, disregard the comments that are in danish)

This simply checks if there's a winner yet, if X has won it returns 1, if O wins it returns 2. The game ends correctly when the right values are returned, but i can't find a way of returning 3 when it's a draw without ruining the game (By making the program think if there's no winner it's a draw. That of course results in the program thinking it's a draw as soon as someone makes the first move without winning).

Code:

```int checkWinner() { //Checker om X har vundet            if(board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X')           return 1;         if(board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X')           return 1;            if(board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X')           return 1;                                  if(board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X')           return 1;          if(board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X')           return 1;         if(board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X')           return 1;                    if(board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X')           return 1;          if(board[2][0] == 'X' && board[1][1] == 'X' && board[0][2] == 'X')           return 1;  //Checker om O har vundet         if(board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O')           return 2;         if(board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O')           return 2;            if(board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O')           return 2;                                  if(board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O')           return 2;          if(board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O')           return 2;         if(board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O')           return 2;                    if(board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O')           return 2;          if(board[2][0] == 'O' && board[1][1] == 'O' && board[0][2] == 'O')           return 2;```
I'd like it to return 3 if there's a draw. Help plx?
Also i'm new to the forum. Hi everyone!
• 04-28-2012
Neo1
A draw in tic-tac-toe happens when the board is filled but none of the players have three in a row, right?

So you just need to extend the function, here is some pseudocode to get your rolling:
Code:

```int checkWinner() { //Checker om X har vundet            if(board[0][0] == 'X' && board[0][1] == 'X' && board[0][2] == 'X')           return 1;         if(board[1][0] == 'X' && board[1][1] == 'X' && board[1][2] == 'X')           return 1;            if(board[2][0] == 'X' && board[2][1] == 'X' && board[2][2] == 'X')           return 1;                                  if(board[0][0] == 'X' && board[1][0] == 'X' && board[2][0] == 'X')           return 1;          if(board[0][1] == 'X' && board[1][1] == 'X' && board[2][1] == 'X')           return 1;         if(board[0][2] == 'X' && board[1][2] == 'X' && board[2][2] == 'X')           return 1;                    if(board[0][0] == 'X' && board[1][1] == 'X' && board[2][2] == 'X')           return 1;          if(board[2][0] == 'X' && board[1][1] == 'X' && board[0][2] == 'X')           return 1;  //Checker om O har vundet         if(board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O')           return 2;         if(board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O')           return 2;            if(board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O')           return 2;                                  if(board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O')           return 2;          if(board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O')           return 2;         if(board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O')           return 2;                    if(board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O')           return 2;          if(board[2][0] == 'O' && board[1][1] == 'O' && board[0][2] == 'O')           return 2;         //When you reach this point, you know nobody has three in a row. So now you just need to check if the board is full. If it is, it's a draw. If the board is not full, that means the game is not over yet.         for i to 3             for j to 3                   if(board[i][j] == ' ') return 0; //There is an empty space here. The game is not over, return 0.         return 3; //No empty spaces found, the game is a draw.```
Does that make sense? Now you just need to implement this in C++, which shouldn't be too difficult.

Instead of just returning 0, 1, 2 or 3 from this function, why don't you return an enum with the different gamestates?
Code:

`enum GameState {X, Y, NONE, DRAW};`
This is a much clearer way of conveying the meaning of the return value of the function.
Also, it seems this function is not a member-function, and you are not passing the board[][] to it as a parameter, which basically means you have the board declared as a global? Is this correct? Globals are considered very poor coding practice. Declare your board inside main() and pass it to this function as a parameter. Or even better, make Board a class and have the array as a member variable, then you can have this function as a member-function.
• 05-03-2012
Thanks for the response :) I've never heard of enum so i'll probably be skipping that part. As regards to the solution adn other suggestions i'll be looking at that when i get the time/isn't drowning in other projects. Thanks again!
• 05-03-2012
Neo1
Well there's nothing downright wrong about your method, you just need to document the return value really well to make sure others know what's going on. By using an enumeration the code almost documents itself.
An enumeration is like a custom type, you can define which values it can have. You just declare your custom type like this somewhere in your program:

Code:

`enum GameState {X, Y, NONE, DRAW};`
Then you declare your function to return a "GameState" rather than just an int:

Code:

```GameState checkWinner() {     ....     return DRAW;     ....     return NONE; }```
And then you can call the function like this:
Code:

```GameState CurrentState = checkWinner(); if(CurrentState == DRAW) {     //Do stuff } if(CurrentState == X) {     //Do some other stuff }```
And so on. There is nothing hard or magical about it. Also you should probably use a switch/case to check the return value, it's much cleaner.

The really critical part of your code is the global variable board[][]. I can't imagine any halfway decent professor would not deduct points for that. Focus on that first imo.
• 05-03-2012
m37h0d
loop over the board and see if a single character occupies any row, column, or diagonal. if yes, that character is the winner. otherwise, if the number of turns == 9, then it's a draw.