Search code examples
javaartificial-intelligencetic-tac-toe

Java Tic Tac Toe AI not working


My AI code for a computer player is not working as expected. I want it to play a random move, but block an opponent's incoming winning turn. However, it sometimes stops working altogether, and other times plays a specific move even though there is no incoming win combo. My computer AI code is below.

public void compturn()
    {


        count++ ;

        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
        if (b1.getText() == b2.getText() && b2.getText() != "" && b3.getText() == "")
            {
                b3.setText(letter);
                b3bool = false ;
            }
            else if (b4.getText() == b5.getText()  && b6.getText() == "")
            {
                b6.setText(letter);
                b6bool = false ;
            }
            else if (b7.getText() == b8.getText() && b9.getText() == "")
            {
                b9.setText(letter);
                b9bool = false ;
            }
            else if (b1.getText() == b4.getText() && b4.getText() != "" && b7.getText() == "")
            {
                b7.setText(letter);
                b7bool = false ;
            }
            else if (b2.getText() == b5.getText() && b8.getText() == "")
            {
                b8.setText(letter);
                b8bool = false ;
            }
            else if (b3.getText() == b6.getText() && b9.getText() == "")
            {
                b9.setText(letter);
                b9bool = false ;
            }
            else if (b1.getText() == b5.getText() && b5.getText() != "" && b9.getText() == "")
            {
                b9.setText(letter) ;
                b9bool = false ;
            }
            else if (b3.getText() == b5.getText() && b7.getText() == "")
            {
               b7.setText(letter);
               b7bool = false ;
            }
            else
            {
                randomMove();
            }
        }


    public void randomMove()
    {
       int randomnum = (int)(Math.random() * 10);
        if(randomnum == 1 )
        {
            if(b1.getText().equals("X") || b1.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b1.setText(letter);
            }
        }
        if(randomnum == 2 )
        {
            if(b2.getText().equals("X") || b2.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b2.setText(letter);
            }
        }
        if(randomnum == 3 )
        {
            if(b3.getText().equals("X") || b3.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b3.setText(letter);
            }
        }
        if(randomnum == 4 )
        {
            if(b4.getText().equals("X") || b4.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b4.setText(letter);
            }
        }
        if(randomnum == 5 )
        {
            if(b5.getText().equals("X") || b5.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b5.setText(letter);
            }
        }
        if(randomnum == 6 )
        {
            if(b6.getText().equals("X") || b6.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b6.setText(letter);
            }
        }
        if(randomnum == 7 )
        {
            if(b7.getText().equals("X") || b7.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b7.setText(letter);
            }
        }
        if(randomnum == 8 )
        {
            if(b8.getText().equals("X") || b8.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b8.setText(letter);
            }
        }
        if(randomnum == 9 )
        {
            if(b9.getText().equals("X") || b9.getText().equals("O"))
            {
                randomMove();
            }
            else 
            {
                b9.setText(letter);
            }
        }


     }

And my complete code for the main game is here

        public int oneplayergame()
        {
            // ----=---------------------- CREATING ALL JBUTTONS ON THE GAME SCREEN AND ADDING ACTION LISTENERS AND REACTIONS -----------------------------------------

            b1 = new JButton("");
            b1.setToolTipText("Mark this box");
            b1.setFont(TToeFont);
            b1.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                   if (b1bool == true){ count++;
                    if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                b1.setText(letter);
                b1bool = false ;
                calculatevictory();
                compturn();                    
                processturn();

            }}});

            b2 = new JButton("");
            b2.setFont(TToeFont);
            b2.setToolTipText("Mark this box");
            b2.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                   if (b2bool == true){ count++;
                    if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                b2.setText(letter);
                b2bool = false ;
                calculatevictory();
                compturn();                    
                processturn();
            }}
                });


            b3 = new JButton("");
            b3.setToolTipText("Mark this box");
            b3.setFont(TToeFont);
            b3.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                     if(b3bool == true){
                         count++;
                    if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                b3.setText(letter);
                b3bool = false ;
                calculatevictory();
                compturn();                    
                processturn();
            }}

            });

            b4 = new JButton("");
            b4.setToolTipText("Mark this box");
            b4.setFont(TToeFont);
            b4.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                    if(b4bool == true){

                    count++;
                        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                    b4.setText(letter);
                    b4bool = false ;
                    calculatevictory();
                    compturn();                    
                    processturn();
                }}
            });

            b5 = new JButton("");
            b5.setToolTipText("Mark this box");
            b5.setFont(TToeFont);
            b5.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                    if (b5bool == true){
                        count++;
                        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                    b5.setText(letter);
                    b5bool = false ;
                    calculatevictory();
                    compturn();                    
                    processturn();
                }}
            });

            b6 = new JButton("");
            b6.setToolTipText("Mark this box");
            b6.setFont(TToeFont);
            b6.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                    if (b6bool == true){
                        count++;
                        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                    b6.setText(letter);
                    b6bool = false ;
                    calculatevictory();
                    compturn();                    
                    processturn();
                }}
            });

            b7 = new JButton("");
            b7.setToolTipText("Mark this box");
            b7.setFont(TToeFont);
            b7.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                    if (b7bool == true){
                        count++;
                        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                    b7.setText(letter);
                    b7bool = false ;
                    calculatevictory();
                    compturn();                    
                    processturn();
                }}
            });

            b8 = new JButton("");
            b8.setToolTipText("Mark this box");
            b8.setFont(TToeFont);
            b8.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                    if(b8bool == true){
                        count++;
                        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                    b8.setText(letter);
                    b8bool = false ;
                    calculatevictory();
                    compturn();                    
                    processturn();
                }}
            });

            b9 = new JButton("");
            b9.setToolTipText("Mark this box");
            b9.setFont(TToeFont);
            b9.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent onclickb1)
                {
                   if(b9bool == true){
                       count++;
                        if(count == 1||count == 3 || count == 5 || count == 7 || count == 9 || count == 11)
                    {
                      letter = "O" ;

                }
                else if ( count == 2 || count == 4 || count == 6 || count == 8 || count == 10)
                {
                    letter = "X" ;                  

                }
                    b9.setText(letter);
                    b9bool = false ;
                    calculatevictory();
                    compturn();
                    processturn();
                }}
            });

            //CREATING GAME SCREEN LAYOUT


            //CREAING GAME SCREEN CONTENT PANE AND ADDING BUTTONS TO IT



        // This method checks if someone won the game every time you click a button 

        public void calculatevictory(){
            if (b1.getText() == b2.getText() && b2.getText() == b3.getText() && b1.getText() != "")
            {
                win = true ;
            }
            else if (b4.getText() == b5.getText() && b5.getText() == b6.getText() && b4.getText() != "")
            {
                win = true ;
            }
            else if (b7.getText() == b8.getText() && b8.getText() == b9.getText() && b7.getText() != "")
            {
                win = true ;
            }
            else if (b1.getText() == b4.getText() && b4.getText() == b7.getText() && b1.getText() != "")
            {
                win = true ;
            }
            else if (b2.getText() == b5.getText() && b5.getText() == b8.getText() && b2.getText() != "")
            {
                win = true ;
            }
            else if (b3.getText() == b6.getText() && b6.getText() == b9.getText() && b3.getText() != "")
            {
                win = true ;
            }
            else if (b1.getText() == b5.getText() && b5.getText() == b9.getText() && b1.getText() != "")
            {
                win = true ;
            }
            else if (b3.getText() == b5.getText() && b5.getText() == b7.getText() && b3.getText() != "")
            {
                win = true ;
            }
            else 
            {
                win = false ;
            }
        }

        // This method sends the win message




            public void processturn()

        }
         // This method resets all game variables 

        public void resetgame()
        {
         count = 1 ; 

         b1bool = true ;
         b2bool = true ;
         b3bool = true ;
         b4bool = true ;
         b5bool = true ;
         b6bool = true ;
         b7bool = true ;
         b8bool = true ;
         b9bool = true ;
         win = false ;
         gameinit = true ;
         b1.setText("");
         b2.setText("");
         b3.setText("");
         b4.setText("");
         b5.setText("");
         b6.setText("");
         b7.setText("");
         b8.setText("");
         b9.setText("");
        }


    public void compturn()
    {
        }


    public void randomMove()
    {























     }
}

Solution

  • Welcome to AI... there are numerous ways you can do this. I'll give you a few tips.

    I assume count is used to determine who's turn it is. I'd suggest you rather create an integer 'turn' and then simply do this:

    turn = 1 -turn
    

    ...where you currently increment count. If it's 0 than it's o's turn, else x's. You can then remove those two long if statements. (You can also use a boolean flag and just not it each time, like so turn = !turn.)

    Now the rest... I see you have no arrays. Are you comfortable using them?

    If so, rather define, winning sequences. For example:

    int[][] win = new int[][]{{1,2,3}, {4,5,6}, {7,8,9}, {1,4,7}, ...}
    

    Then all you do to determine if you can win, go is to see if you have two of your tokens in spot win[i][0], win[i][1] or win[i][2]. If the third spot it empty, you can win and should move there,

    If you can't win, repeat the above process to defend.

    If you do not have to defend and you cannot win, move in the centre. If the centre is taken, take a corner, else move random.

    This will give you an AI that can still lose sometimes, but will show some intelligence. If you really want to build something unbeatable have a look at the minimax search algorithm.

    Good luck!