Thread: My first "real" C++ program! (Tic Tac Toe)

  1. #1
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84

    My first "real" C++ program! (Tic Tac Toe)

    This is my very first game in C++. I am pretty proud of it even though it only took me about an hour and a half to do. My supposed AI isn't very good. I essentially generate a random number for the row and column and check to see if that position is open. If it is, then I make my move there. If not, then I generate another position and see if it's open. Not too bright, huh?.

    Anyway, I was kind of looking for ways to improve this game. With respect to my AI, is there an easier way to figure out my moves other than brute force (ie, go through every scenario explicitly stating what my AI should do in each instance?) That would just get really tedious.

    I am looking for any constructive criticisms you may have. Thanks in advance.

    Oh, and if you happen to try to run this game and in the middle it seems to freeze, it's really not. It's probably the AI trying to figure out where to go.

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <time.h>
    
    using namespace std;
    int option, test, row, col, turn, option2 = 0;
    char board[3][3];
    
    //print the board to the screen 
    void drawBoard()
    {
         cout<<"\n";
         for(int i = 0; i < 3; i++)
         {
             for(int j = 0; j < 3; j++)
             {
                     cout<<"|"<<board[i][j]<<"|  ";
             }        
             cout<<"\n-------------\n";
         }        
    }     
    
    //this method returns a 0 if there's no winner, 1 if X wins, 2 if O wins, 3 if tie
    int checkWinner()
    {
    //check to see if X won    
            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;  
    //check to see if O won
            if(board[0][0] == 'O' && board[0][1] == 'O' && board[0][2] == 'O')
              return 0;
            if(board[1][0] == 'O' && board[1][1] == 'O' && board[1][2] == 'O')
              return 0;     
            if(board[2][0] == 'O' && board[2][1] == 'O' && board[2][2] == 'O')
              return 0;  
                           
            if(board[0][0] == 'O' && board[1][0] == 'O' && board[2][0] == 'O')
              return 0;  
            if(board[0][1] == 'O' && board[1][1] == 'O' && board[2][1] == 'O')
              return 0; 
            if(board[0][2] == 'O' && board[1][2] == 'O' && board[2][2] == 'O')
              return 0;           
    
            if(board[0][0] == 'O' && board[1][1] == 'O' && board[2][2] == 'O')
              return 0;   
            if(board[2][0] == 'O' && board[1][1] == 'O' && board[0][2] == 'O')
              return 0;                                               
    }        
    //AI. generate a random move and see if it's available. if it is, then make it
    //if it isn't then generate another random move
    void AI()
    {
         col = -1;
         row = -1;
         while(col == -1 || row == -1)
         {
            time_t seconds;
            time(&seconds);
            srand((unsigned int) seconds);  
            col = rand()%3;
            row = rand()%3;
            if(board[row][col] != ' ')
            {
                col = -1;
                row = -1; 
            }
            board[row][col] = 'O';                        
         }           
         
    }     
    int main()
    {
    
        do
        {
          option2 = 0; //so we can play multiple times
          cout<<"Enter a menu option:\n";
          cout<<"-----------------------------\n\n";
          cout<<"1. Play Tic Tac Toe\n";
          cout<<"2. Quit\n";
          cin>>option;
           for(int i = 0; i < 3; i++)
           {
               for(int j = 0; j < 3; j++)
               {
                       board[i][j] = ' ';
               }        
           }    
          if(option !=2)
          {
            while(option2 != -1)
            {         
                if(turn%2 == 0)//if it's even then it's X's turn
                {
                    bool condition = true;
                    while(condition == true) 
                    {     
                        cout<<"\n\nEnter a move:\n";
                        cout<<"Enter the row you wish to make your move on (0,1,2)\n";
                        cin>>row;
                        cout<<"Enter the column you wish to make your move on (0,1,2)\n";
                        cin>>col;  
                        if(board[row][col] == ' ')
                        {   
                            board[row][col] = 'X';
                            turn++;
                            condition = false;
                        }    
                        else
                            cout<<"Invalid move!\n";
                    }    
                }    
                else //AI must do something
                {
                    AI();                   
                    turn++;
                }
                              
                if(checkWinner() == 1) //X wins
                {
                    cout<<"Congratulations! X won!\n\n";
                    option2 = -1;
                }               
                else if(checkWinner() == 2) //X wins
                {
                    cout<<"Congratulations! O won!\n\n";
                    option2 = -1;
                }               
                drawBoard();
            }  
            
          }  
          
        }while(option != 2);
          cout<<"\n\n\n\nEnter anything to quit.";
          cin>>test;
    }

  2. #2
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84
    I just did a search and there's a lot of info on the Tic Tac Toe AI. I guess any constructive criticism on my actually coding is really what I need then. Thanks in advance.

  3. #3
    Registered User major_small's Avatar
    Join Date
    May 2003
    Posts
    2,787
    here are quite a few pointers--admitedly they're mostly issues that don't matter very much, like things that will save a few processor cycles, but they're good habits to get into in case you ever need teh skills.

    just from the very top:
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <ctime>  //replacing <time.h>
    
    using namespace std;
    int option, test, row, col, turn, option2 = 0;  //try not to use global variables if you don't have to
    char board[3][3];
    from the very bottom:
    Code:
          cout<<"\n\n\n\nEnter anything to quit.";
          cin>>test;
    this would probably serve you better:
    Code:
      cout<<"\n\n\n\nPress ENTER to quit";
      cin.get();
    I'm not sure if you already covered this one somewhere else in your code:
    Code:
            if(board[row][col] != ' ')  //does this mean it can take a spot X already has?
            {
                col = -1;
                row = -1; 
            }
            board[row][col] = 'O';
    I don't think you have the 'tie' case done yet - I finished a game with no winner an it was stuck asking me for my move:
    Code:
    //this method returns a 0 if there's no winner, 1 if X wins, 2 if O wins, 3 if tie
    int checkWinner()
    {
    //check to see if X won    
    ...
    //check to see if O won
    ...
    }
    and here is a similar issue (I also found an error in one of your comments):
    Code:
          //try not to call checkWinner() two times - use a variable like this:
          winner=checkWinner();
                if(winner==1) //X wins
                {
                    cout<<"Congratulations! X won!\n\n";
                    option2 = -1;
                }               
                else if(winner==2) //O wins <-- an error in your comment
                {
                    cout<<"Congratulations! O won!\n\n";
                    option2 = -1;
                }               
          else if(winner==3)  //nobody wins
                {
        cout<<"It's a Draw\n\n";
               option2 = -1;
                }
                drawBoard();
    here's something involving your randomness code:
    Code:
      /*
      instead of this method:
    
            time_t seconds;
            time(&seconds);
            srand((unsigned int) seconds);
    
      you can use this method, which eliminates the need for a variable:
      */
    
      srand((unsigned int)time(0));
    Last edited by major_small; 03-09-2005 at 03:39 AM. Reason: more More MORE
    Join is in our Unofficial Cprog IRC channel
    Server: irc.phoenixradio.org
    Channel: #Tech


    Team Cprog Folding@Home: Team #43476
    Download it Here
    Detailed Stats Here
    More Detailed Stats
    52 Members so far, are YOU a member?
    Current team score: 1223226 (ranked 374 of 45152)

    The CBoard team is doing better than 99.16% of the other teams
    Top 5 Members: Xterria(518175), pianorain(118517), Bennet(64957), JaWiB(55610), alphaoide(44374)

    Last Updated on: Wed, 30 Aug, 2006 @ 2:30 PM EDT

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    With respect to my AI, is there an easier way to figure out my moves other than brute force (ie, go through every scenario explicitly stating what my AI should do in each instance?) That would just get really tedious.
    For something as small as tic-tac-toe, pre-calculation probably is the best, especially since there are only a few variations, the rest just need the board to be rotated.

    On the other hand, a simple rule of thumb would be "if opponent starts in the centre, reply in the corner; else reply in the centre".
    This wouldnt help your program recognise wins, but it'll help your program avoid losing, unless the player makes a quiet 2nd move, forcing the random choice, which may be the choice of a lost variation.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84
    Thank you for the help guys. I really appreciate the suggestions.

  6. #6
    email for MystWind avatar MystWind's Avatar
    Join Date
    Feb 2005
    Location
    Holland , The Hague
    Posts
    88
    good luck on further projects : if you make a version 2 , show us !
    PLay MystWind beta , within two years

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > time_t seconds;
    > time(&seconds);
    > srand((unsigned int) seconds);
    This should be in main(). Otherwise you're seeding the random number generator every time you make a move.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Check tic tac toe winner
    By cjmdjm in forum C++ Programming
    Replies: 3
    Last Post: 11-04-2005, 12:41 PM
  2. Tic Tac Toe AI help please...
    By Rune Hunter in forum Game Programming
    Replies: 12
    Last Post: 11-05-2004, 04:24 PM
  3. tic tac toe
    By holden in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 05-09-2004, 09:59 AM
  4. tic tac toe (arggg, I really need help!)
    By Leeman_s in forum Game Programming
    Replies: 3
    Last Post: 10-14-2001, 04:03 PM
  5. tic tac toe (arggg, I really need help!)
    By Leeman_s in forum C++ Programming
    Replies: 1
    Last Post: 10-11-2001, 12:10 PM