Thread: C++ Tic Tac Toe - A draw?

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    2

    Question 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!

  2. #2
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    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.

    Regarding your coding style:
    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.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  3. #3
    Registered User
    Join Date
    Apr 2012
    Posts
    2
    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!

  4. #4
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    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.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  5. #5
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Draw on top of everything.
    By DDAZZA in forum C++ Programming
    Replies: 5
    Last Post: 06-04-2009, 11:50 PM
  2. How Can I draw What I want?
    By CChakra in forum Game Programming
    Replies: 22
    Last Post: 09-11-2008, 08:38 AM
  3. Which is the better way to draw?
    By g4j31a5 in forum Game Programming
    Replies: 16
    Last Post: 01-22-2007, 11:56 PM
  4. Draw dot by dot?
    By fiska in forum C# Programming
    Replies: 3
    Last Post: 10-11-2006, 09:38 AM
  5. draw
    By loki_cmr in forum C++ Programming
    Replies: 7
    Last Post: 11-30-2002, 10:34 AM

Tags for this Thread