3

I am currently trying to implement a Minimax algorithm for Tic Tac Toe. With the current version, there are some cases, where the computer screws up, and I am not quite sure why. For example if I (as the human player) start with an x in the upper left corner, the computer reacts with a o in the lower left corner (Which, of course, is equal to him losing) The whole program is in MVC-Design.

Question: Did I correct the Minimax Algorithm correctly or (if not) what causes the "bad" moves?

Here's the code: (I left out the code for some methods I have tested to be correct)

 package tictactoe;

    import java.util.*;

    public class AIMinimax {

        Game game;
        Cell[][] cell = new Cell[3][3];
        int[] bestMove;
        public AIMinimax(Game game) {
              this.game=game;
              for(int i=0;i<3;i++)
              {
                  for(int j=0;j<3;j++)
                  {
                      cell[i][j]=game.getCell(i,j);
                  }
              }
           }

        //Calculates the best move.
        private int minimax(Cell player)
        {
            //Computer tries to maximize the bestscore, Player tries to minimize the bestscore.

            int bestScore = 0;
            if(player==Cell.CIRCLE) bestScore=-1; 
            if(player==Cell.CROSS) bestScore=+1;


            int currentScore;
            List<int[]> moves = identifyMoves();
            if(moves.isEmpty() || hasWon(Cell.CROSS) || hasWon(Cell.CIRCLE))
            {
                //System.out.println(hasWon(Cell.CROSS));
                //System.out.println(hasWon(Cell.CIRCLE));
                //System.out.println(moves.isEmpty());
                currentScore=evaluate();
                bestScore=currentScore;
            }
            else
            {
                for (int[] move : moves) {
                    if (player==Cell.CIRCLE)
                    {
                        cell[move[0]][move[1]]=Cell.CIRCLE;
                        currentScore=minimax(Cell.CROSS);
                        if(currentScore>bestScore)
                {
                    bestScore=currentScore;
                    bestMove = move;
                }
            }
            else if(player==Cell.CROSS)
            {
                cell[move[0]][move[1]]=Cell.CROSS;
                currentScore=minimax(Cell.CIRCLE);


                if(currentScore<bestScore  )
                {

                    bestScore=currentScore;
                    bestMove=move;
                }
            }   

            cell[move[0]][move[1]]=Cell.EMPTY;
            if((player==Cell.CIRCLE&&bestScore==1)||(player==Cell.CROSS&&bestScore==-1))
            {
                return bestScore;
            }
        }
        }
                System.out.println(bestScore);
        return bestScore;
        }



    //Compute all possible next moves.
    //@return List of int[2] arrays where int[0] indicates the column and int [1] indicates the row.
    private List<int[]> identifyMoves(){}


    //Evaluates the current board. 
    // -1 if the player wins, +1 if the computer wins, 0 for a draw
    //No other values needed as the depth of the minimax algorithm is maximal.


    private int evaluate() {
        int result=0;
        if(hasWon(Cell.CIRCLE)) result=1;
        if(hasWon(Cell.CROSS)) result=-1;

        return result;
    }
    //return true if the player has won and false if the other player won or there is
    // a draw.


    public boolean hasWon(Cell player){}

    //Returns the next move for the computer as a int[2] where int[0] indicates the column and 
    //int[1] indicates the row.
    public int[] nextMove(Cell player)
    {
        int minimaxResult= minimax(player);

        return bestMove

    }


}

    package tictactoe;


    public enum Cell {

        EMPTY,
        CROSS,
        CIRCLE;

    }

The game class represents the filed in a Cell[][] array (the same way as AIMinimax) and creates an instance of AIMinimax and calls nextMove on this, to generate the next Move the Computer makes. By default the Human Player always starts.

Thank you in advance!

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user1823479
  • 39
  • 1
  • 3

0 Answers0