Thread: tic tac toe AI roadblock >:-(|)

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    4

    tic tac toe AI roadblock >:-(|)

    this is what i have for a tic tac toe game. right now its really sloppy and well..... its not what i usually do but its my first game so its bound to be this ugly when you dont know what to do. i am having a problem with the ai. i figured that i should us else if statements instead of using alot of if statements because of the fact that the ai would cheat and make two moves the next turn. i had the idea that if i could make it make only one turn and then "turn off" till next turn then it would solve this problem. i used first an increment to do this but didnt work. then i used a bool statement and it fail so now i am wondering if i should just try and go for a random move generator. any thoughts? oh and i have completed a multiplayer version of this if you want that code to help. its abit more clean to an extent.... well yeah just give me your thoughts and if you can explain how and why its doing things cause i like to learn things logically. thanks. oh and dont mind the notes in the code those are old and are just foot marks of what was to be a mathmatically powered ai. too hard to figure out.
    Code:
    #include <iostream>
    #include <cstdlib>
    #include <time.h>
    
    const char playericon = 'X';
    const char compicon = 'O';
    //currently a constant only for now
    //changes will occur when ai is complete
    //when game is complete changes to:
    //allow player to pick who goes first
    //mini menu
    //clear gameboard
    //improve gamecode to allow better readability
    using namespace std;
    
    int main()
    {
    char arr[3][3]={{'.','.','.'},{'.','.','.'},
    {'.','.','.'}};
    
    int x;
    int y=0;
    int compturn = 0;
    
    int playeroutput;
    //////c1 c2 c3
    //row1 1  |2  |3  =6 {1,2,3,3,5,4}
    //     ----------
    //row2 4  |5  |6  =15 {4,5,6,9,10,11}
    //     ----------
    //row3 7  |8  |9  =24 {7,8,9,15,16,17}
    //15/  12 15 18\ 15
    // /DL{3,5,7,8,10,12}
    // \DR{1,5,9,6,10,14}
    // C1{1,4,7,5,8,11}
    cout<<"*************************************************************************"<<endl;
    cout<<"*************************************************************************"<<endl;
    cout<<"************************Dark_Rocket's TIC TAC TOE************************"<<endl;
    cout<<"*************************************************************************"<<endl;
    cout<<"*************************************************************************\n\n\n\n\n"<<endl;
    
    
    
    
    cout<<"please make a move by pressing any number 1-9\n"<<endl;
      cout<<"\n"<<endl;
      cout<<"1 "<<arr[0][0]<<" |2 "<<arr[0][1]<<" |3 "<<arr[0][2]<<" "<<endl;
      cout<<"-----------------"<<endl;
      cout<<"4 "<<arr[1][0]<<" |5 "<<arr[1][1]<<" |6 "<<arr[1][2]<<" "<<endl;  
      cout<<"-----------------"<<endl;
      cout<<"7 "<<arr[2][0]<<" |8 "<<arr[2][1]<<" |9 "<<arr[2][2]<<" "<<endl;
      cout<<"\n"<<endl;
      
    //the above is our tic tac toe board. its based off an array
    
    
    for(x=1;x<100;x++)
    {
    //put a function to allow a check for a win.
      if(x % 2 !=0)
      {
      cin>>playeroutput;
    //this gets our input to let the player decide where to place the X.
      switch(playeroutput)
      {
            case 1:
        if(arr[0][0]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[0][0]==compicon;
        x--;
        } 
        else if(arr[0][0]!=compicon)
        {
        arr[0][0]= playericon;
        } 
        break;
        
            case 2: 
        if(arr[0][1]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[0][1]==compicon;
        x--;
        }
        else if(arr[0][1]!=compicon)
        {
        arr[0][1]= playericon; 
        }
        break;
        
            case 3: 
        if(arr[0][2]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[0][2]==compicon;
        x--;
        } 
        else if(arr[0][2]!=compicon)
        {
        arr[0][2]= playericon;
        } 
        break;
        
            case 4:
        if(arr[1][0]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[1][0]==compicon;
        x--;
        } 
        else if(arr[1][0]!=compicon)
        {
        arr[1][0]= playericon;
        } 
        break;
        
            case 5:
        if(arr[1][1]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[1][1]==compicon;
        x--;
        } 
        else if(arr[1][1]!=compicon)
        {
        arr[1][1]= playericon;
        } 
        break;
        
            case 6:
        if(arr[1][2]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[1][2]==compicon;
        x--;
        } 
        else if(arr[1][2]!=compicon)
        {
        arr[1][2]= playericon;
        } 
        break;
        
            case 7:
        if(arr[2][0]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[2][0]==compicon;
        x--;
        } 
        else if(arr[2][0]!=compicon)
        {
        arr[2][0]= playericon;
        } 
        break;
        
            case 8: 
        if(arr[2][1]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[2][1]==compicon;
        x--;
        } 
        else if(arr[2][1]!=compicon)
        {
        arr[2][1]= playericon;
        } 
        break;
        
            case 9: 
        if(arr[2][2]==compicon)
        {
        cout<<"im sorry you can not make that move. please make another move."<<endl;
        arr[2][2]==compicon;
        x--;
        } 
        else if(arr[2][2]!=compicon)
        {
        arr[2][2]= playericon;
        } 
        break;
        
        default: break;
      }
    
        if((arr[0][0]==playericon)&&(arr[0][1]==playericon)&&(arr[0][2]==playericon))
        {
        cout<<"You filled the top row! You win."<<endl;
    system("PAUSE");
        return 0;
        ////toprow
        }
        
        
        else if((arr[1][0]==playericon)&&(arr[1][1]==playericon)&&(arr[1][2]==playericon))
        {
        cout<<"you filled the middle row! You win"<<endl;
        system("PAUSE");    
        return 0;
        }
        
            else if((arr[2][0]==playericon)&&(arr[2][1]==playericon)&&(arr[2][2]==playericon))
        {
        cout<<"you filled the bottom row! You win"<<endl;
        system("PAUSE");
        return 0;
        }
        
            else if((arr[0][0]==playericon)&&(arr[1][0]==playericon)&&(arr[2][0]==playericon))
        {
        cout<<"you filled the 1st colum! You win"<<endl;
        system("PAUSE");
        return 0;
        }
        
            else if((arr[0][1]==playericon)&&(arr[1][1]==playericon)&&(arr[2][1]==playericon))
        {
        cout<<"you filled the 2nd colum! You win"<<endl;
        system("PAUSE");    
        return 0;
        }
        
            else if((arr[0][2]==playericon)&&(arr[1][2]==playericon)&&(arr[2][2]==playericon))
        {
        cout<<"you filled the 3rd colum! You win"<<endl;
        system("PAUSE");    
        return 0;
        }
        
            else if((arr[0][0]==playericon)&&(arr[1][1]==playericon)&&(arr[2][2]==playericon))
        {
        cout<<"you filled up the row diagonally downward! You win"<<endl;
        system("PAUSE");
        return 0;
        }
        
            else if((arr[0][2]==playericon)&&(arr[1][1]==playericon)&&(arr[2][0]==playericon))
        {
        cout<<"you filled up the row diagonally upward! You win"<<endl;
        system("PAUSE");
        return 0;
        }   
        
          cout<<"\n"<<endl;
      cout<<"1 "<<arr[0][0]<<" |2 "<<arr[0][1]<<" |3 "<<arr[0][2]<<" "<<endl;
      cout<<"-----------------"<<endl;
      cout<<"4 "<<arr[1][0]<<" |5 "<<arr[1][1]<<" |6 "<<arr[1][2]<<" "<<endl;  
      cout<<"-----------------"<<endl;
      cout<<"7 "<<arr[2][0]<<" |8 "<<arr[2][1]<<" |9 "<<arr[2][2]<<" "<<endl;
      cout<<"\n"<<endl;
    }
        else if(x % 2 ==0)
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    
    /*
    ok this is the code you have to input by moving the brackets to their proper 
    positions. remember nothing here is in order so you have to remember that. the
    next thing you will have to do is remove any contridicting code because 
    apparently this is some. next remember you also have to find a better way to get
    input from the user so that a character does not cause an endless loop. after 
    that you can finally work on the other mini game to decide who will go first.
    */
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    
        {
        if(arr[0][0]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=playericon)
            {
                arr[1][1]=compicon;
            }
    
        }
        else if(arr[0][1]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
                    arr[1][1]=compicon;
            }
         
        }
        else if(arr[0][2]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
            arr[1][1]=compicon;
            }
           
        }
        else if(arr[1][0]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
            arr[1][1]=compicon;
            }
        
        }
        else if(arr[1][1]==playericon)
        {
            if(arr[1][2]!=playericon && arr[1][2]!=compicon)
            {
            arr[1][2]=compicon;
            }
         
        }
        else if(arr[1][2]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
            arr[1][1]=compicon;
            }
         
        }
        else if(arr[2][0]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
            arr[2][1]=compicon;
            }
           
        }
        else if(arr[2][1]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
            arr[1][1]=compicon;
            }
      
        }
        else if(arr[2][2]==playericon)
        {
            if(arr[1][1]!=playericon && arr[1][1]!=compicon)
            {
            arr[1][1]=compicon;
            }
          
        }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////next moves////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
         if(arr[0][0]==playericon && arr[0][2]==playericon)
        {
          if(arr[0][1]!=playericon && arr[0][1]!=compicon)
          {
          arr[0][1]=compicon;  
          }
       
        }
        else if(arr[1][0]==playericon && arr[1][2]==playericon)
        {
          if(arr[1][1]!=playericon && arr[1][1]!=compicon)
          {
          arr[1][1]=compicon;
          }
       
        }
        else if(arr[2][0]==playericon && arr[2][2]==playericon)
        {
          if(arr[2][1]!=playericon && arr[2][1]!=compicon)
          {
          arr[2][1]=compicon;
          }
        
        }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    //horizontal checks above///////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    
        else if(arr[0][0]==playericon && arr[2][0]==playericon)
        {
          if(arr[1][0]!=playericon && arr[1][0]!=compicon)
          {
          arr[1][0]=compicon;
          }
         
        }
        else if(arr[0][1]==playericon && arr[2][1]==playericon)
        {
          if(arr[1][1]!=playericon && arr[1][1]!=compicon)
          {
          arr[1][1]=compicon;
          }
       
        }
        else if(arr[2][0]==playericon && arr[2][2]==playericon)
        {
          if(arr[2][1]!=playericon && arr[2][1]!=compicon)
          {
          arr[2][1]=compicon;
          }
      
        }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    //vertical checks above/////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    
        else if(arr[0][0]==playericon && arr[2][2]==playericon)
        {
          if(arr[1][1]!=playericon && arr[1][1]!=compicon)
          {
          arr[1][1]==compicon;
          }
       
        }
        else if(arr[0][2]==playericon && arr[2][0]==playericon)
        {
          if(arr[1][1]!=playericon && arr[1][1]!=compicon)
          {
          arr[1][1]=compicon;
          }
        
        }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    //diag. checks above////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
        
        
        else if(arr[0][0]==playericon && arr[0][1]==playericon)
        {
        if(arr[0][2]!=playericon && arr[0][2]!=compicon)
          {
            arr[0][2]=compicon;
          }
         
        }
        
        else if(arr[0][1]==playericon && arr[0][2]==playericon)
        {
        if(arr[0][0]!=playericon && arr[0][0]!=compicon)
          {
            arr[0][0]=compicon;
          }
         
        }
        
        
        
        else if(arr[1][0]==playericon && arr[1][1]==playericon)
        {
        if(arr[1][2]!=playericon && arr[1][2]!=compicon)
          {
            arr[1][2]=compicon;
          }
       
        }
        
        else if(arr[1][1]==playericon && arr[1][2]==playericon)
        {
        if(arr[1][0]!=playericon && arr[1][0]!=compicon)
          {
            arr[1][0]=compicon;
          }
         
        }
        
        else if(arr[2][0]==playericon && arr[2][1]==playericon)
        {
        if(arr[2][2]!=playericon && arr[2][2]!=compicon)
          {
            arr[2][2]=compicon;
          }
      
        }
        
        else if(arr[2][1]==playericon && arr[2][2]==playericon)
        {
        if(arr[2][0]!=playericon && arr[2][0]!=compicon)
          {
            arr[2][0]=compicon;
          }
        
        }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    //horizontal check special input
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
        else if(arr[0][0]==playericon && arr[1][0]==playericon)
        {
        if(arr[2][0]!=playericon && arr[2][0]!=compicon)
          {
            arr[2][0]=compicon;
          }
        
        }
        
        else if(arr[1][0]==playericon && arr[2][0]==playericon)
        {
        if(arr[0][0]!=playericon && arr[0][0]!=compicon)
          {
            arr[0][0]=compicon;
          }
     
        }
        
        else if(arr[0][1]==playericon && arr[1][1]==playericon)
        {
        if(arr[2][1]!=playericon && arr[2][1]!=compicon)
          {
            arr[2][1]=compicon;
          }
        
        }
        
        else if(arr[1][1]==playericon && arr[2][1]==playericon)
        {
        if(arr[0][1]!=playericon && arr[0][1]!=compicon)
          {
            arr[0][1]=compicon;
          }
    
        }
        
        else if(arr[0][2]==playericon && arr[1][2]==playericon)
        {
        if(arr[2][2]!=playericon && arr[2][2]!=compicon)
          {
            arr[2][2]=compicon;
          }
    
        }
        
        else if(arr[1][2]==playericon && arr[2][2]==playericon)
        {
        if(arr[0][2]!=playericon && arr[0][2]!=compicon)
          {
            arr[0][2]=compicon;
          }
    
        }
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    //diag checks special///////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
        
        else if(arr[0][0]==playericon && arr[1][1]==playericon)
        {
        if(arr[2][2]!=playericon && arr[2][2]!=compicon)
          {
            arr[2][2]=compicon;
          }
    
        }
        
        else if(arr[1][1]==playericon && arr[2][2]==playericon)
        {
        if(arr[0][0]!=playericon && arr[0][0]!=compicon)
          {
            arr[0][0]=compicon;
          }
    
        }
        
       else if(arr[2][0]==playericon && arr[1][1]==playericon)
        {
        if(arr[0][2]!=playericon && arr[0][2]!=compicon)
          {
            arr[0][2]=compicon;
          }
    
        }
        
        else if(arr[1][1]==playericon && arr[0][2]==playericon)
        {
        if(arr[2][0]!=playericon && arr[2][0]!=compicon)
          {
            arr[2][0]=compicon;
          }
    
        }
        else if(arr[0][1]==compicon && arr[1][1]==compicon)
        {
        if(arr[2][1]!=playericon && arr[2][1]!=compicon)
          {
            arr[2][1]=compicon;
          }
          cout<<"you lose the comp has won...."<<endl;
        }
        
    
    
      cout<<"\n"<<endl;
      cout<<"1 "<<arr[0][0]<<" |2 "<<arr[0][1]<<" |3 "<<arr[0][2]<<" "<<endl;
      cout<<"-----------------"<<endl;
      cout<<"4 "<<arr[1][0]<<" |5 "<<arr[1][1]<<" |6 "<<arr[1][2]<<" "<<endl;  
      cout<<"-----------------"<<endl;
      cout<<"7 "<<arr[2][0]<<" |8 "<<arr[2][1]<<" |9 "<<arr[2][2]<<" "<<endl;
      cout<<"\n"<<endl;
        }
    
    
    }
    
    
    system("PAUSE");
    return 0;
    }

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    You may want to take a look at FSMs for an easy AI solution that can be applied on most game models.

    Even if the simplest of AI models, it is probably still unecessary for a tic-tac-toe game. you may want to check a more direct approach to the tic-tac-toe solution.

    One advise... AI not built around generic methods (like the second link) is usually achieved by decomposing the thought process. Try to look at the board. Play a game against yourself and just after every move your other-half does, stop and put down on paper every thught step that made you do that move.

    If you do this systematically, you will soon find the thought patterns that will allow to construct the rules for your AI. Examine the authors solution... how he decomposed the board, its elements and how they interact in order to guarante either a tie or win.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    4
    thanks i'll look into the info you provided. hopefully i'll find what im looking for.

  4. #4
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    You repeat code way too much in your program and it makes it way more bulky than it should be. Your entire player output switch case is wasteful, you can easily convert the number input to the array index.
    Code:
     cin >> playeroutput;  // A number from 1 - 9
        if(arr[(playeroutput - 1) / 3][(playeroutput - 1) % 3] == compicon) {
            cout << "im sorry you can not make that move. please make another move." << endl;  
            // Please at least attempt to use good grammer in your output
            arr[(playeroutput - 1) / 3][(playeroutput - 1) % 3] == compicon;  // This is a comparison not an assignment
            x--;
        } 
        else if(arr[(playeroutput - 1) / 3][(playeroutput - 1) % 3] != compicon)
           arr[(playeroutput - 1) / 3][(playeroutput - 1) % 3] = playericon;
        // Where is the check to see if the player icon is already placed in the spot?
        // You letting them overwrite their own moves?
    Last edited by SlyMaelstrom; 06-11-2006 at 04:15 PM.
    Sent from my iPadŽ

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    4
    i did that in the multiplayer game. its something that i havent tried to fix since im more focused on the AI. i think i need to reread the whole tutorial again... thanks for the info though. i see what you mean now. i guess i was too focused on other things. maybe i should think out of the box now huh? again thanks for the info.
    Last edited by dark_rocket; 06-11-2006 at 11:59 PM.

  6. #6
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    It's no big deal. It's part of the learning process. Sometimes it takes a few programs for some things to logically click. It's tough to be optimal when you're just trying to be correct.
    Sent from my iPadŽ

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help me with my simple Tic tac toe prog
    By maybnxtseasn in forum C Programming
    Replies: 2
    Last Post: 04-04-2009, 06:25 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 AI
    By Isamo in forum C++ Programming
    Replies: 9
    Last Post: 01-01-2004, 11:32 AM
  4. tic tac toe AI
    By abrege in forum C++ Programming
    Replies: 4
    Last Post: 12-05-2002, 07:10 AM
  5. not 3x3 tic tac toe game AI
    By Unregistered in forum Game Programming
    Replies: 9
    Last Post: 08-29-2001, 04:02 AM