Tic Tac Toe with Minimax: Computer sometimes losing when Player goes first; works otherwise

好久不见. 提交于 2019-12-03 16:42:22

Let's look at something simpler - the board is 1x1, and the first player to place a mark there wins.

Now the computer starts, score=-1. There is no winning solution (the one winning set is checked, it is not a 1-in-a-row), and there is an available space. So we proceed by backtracking to try the one available position.

Now Mark=PLAYER, and the board has a winning solution. So the computer wins, score = -1.

Returning to the first call, the line "int nextScore = minimax( board, nextMark );" returns -1 again, and the final score is -1.

The same thing happens to you with the larger problem.

In a Tic Tac Toe game, there are 3 possibilities and not just 2: Player1 wins, Player2 wins, Nobody wins.

You should replace lines like this one:

int score = (currentMark == Mark2.COMPUTER) ? -1 : 1;

by something like this:

int score = (currentMark == Mark2.COMPUTER) ? -1 : ((currentMark == Mark2.PLAYER) ? 1 : 0);

After taking an extended break, and with the help of the response by @GuyAdini, I had an epiphany. I wrote a test to count the occurrence of the three possible scores returned by minimax(). It yielded nothing for 0 as a result, which clued me in to the fact that I needed 0 to be considered by the algorithm as a possible score.

I had originally changed the initialization of 'score' to be the lowest/highest possible results (-1/1) and compared against them. However, this prohibited the result from getting the lowest/highest value exclusively from the set of scores returned and instead also included the initialized value. This spoiled the results.

I added the following comparison to the conditional changing of 'score':

|| availableIndex == 0

This forced all remaining comparisons to be made against a value that belonged to the set of returned scores.

public class Minimax {
  public static int minimax( Board board, Mark2 currentMark ) {
    int score = 0;
    int[] availableSpaces = board.getAvailableSpaces();

    if ( board.hasWinningSolution() )
      score = (board.getWinningMark() == Mark2.COMPUTER) ? 1 : -1;
    else if ( availableSpaces.length != 0 ) {
      Mark2 nextMark = (currentMark == Mark2.COMPUTER) ? Mark2.PLAYER : Mark2.COMPUTER;

      for ( int availableIndex = 0; availableIndex < availableSpaces.length; availableIndex++ ) {
        board.addMark( availableSpaces[availableIndex], currentMark );
        int nextScore = minimax( board, nextMark );
        board.eraseMark( availableSpaces[availableIndex] );

        if ( currentMark == Mark2.COMPUTER && nextScore > score
            || currentMark == Mark2.PLAYER && nextScore < score
            || availableIndex == 0 )
          score = nextScore;
      }
    }

    return score;
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!