首页 > 解决方案 > Java中的miniMax算法

问题描述

我目前对我正在编程的 AI 不满意。AI 应该在 3x3 棋盘 (TicTacToe) 中的每一步都获得最高分。

可能的分数是 -1(输)、0(平)和 1(赢)。

首先makeTurn()调用方法,然后调用包含 miniMax 算法的方法。

public void makeTurn(Button[][] currentBoard) {                                                 // Calculating best move using miniMax algorithm
        AIcheck = new Check(currentBoard);
        int bestScore = Integer.MIN_VALUE;
        int[] bestMove = new int[2];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (currentBoard[i][j].getText().equals("")) {
                    currentBoard[i][j].setText("O");
                    int score = calcScore(currentBoard, 0, false);
                    System.out.println(score);
                    currentBoard[i][j].setText("");
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove = new int[]{i, j};

                    }
                }
            }
        }
        Board.getInstance().getField(bestMove[0], bestMove[1]).performClick();
    }

private int calcScore(Button[][] currentBoard, int depth, boolean isMax) {                      // MiniMax Algorithm, calculating score for each branch via recursive execution
        int score;
        if (AIcheck.checkWin()) {
            return (Util.getInstance().getTurnCounter() % 2) == 0 ? 1 : -1;
        } else if (AIcheck.checkTie()) {
            return 0;
        }
        int bestScore = isMax ? Integer.MIN_VALUE : Integer.MAX_VALUE;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (currentBoard[i][j].getText().equals("")) {
                    if (isMax) {
                        currentBoard[i][j].setText("O");
                    } else {
                        currentBoard[i][j].setText("X");
                    }
                    score = calcScore(currentBoard, depth + 1, !isMax);
                    currentBoard[i][j].setText("");
                    bestScore = isMax ? Math.max(bestScore, score) : Math.min(bestScore, score);
                }
            }
        }
        return bestScore;
    }

isMax用来确定是否轮到最大化器,也turnCounter % 2用于确定轮到哪个玩家,因为他们轮流。

然而,人工智能并没有阻止我的胜利,它更像是从一个领域到下一个领域,而不是选择最佳领域。我怎样才能正确实现 miniMax 算法?非常感谢!

例子:

[]|[]|[]

[]|[]|[]

[X]|[]|[]


[O]|[]|[]

[]|[]|[]

[X]|[]|[]


[O]|[]|[]

[]|[]|[]

[X]|[]|[X]


[O]|[O]|[]

[]|[]|[]

[X]|[]|[X]


[O]|[O]|[X]

[]|[]|[]

[X]|[]|[X]


[O]|[O]|[X]

[O]|[]|[]

[X]|[]|[X]


[O]|[O]|[X]

[O]|[X]|[] 我赢了,这也显示了 AI 似乎只是占据了下一个位置(从左到右)

[X]|[]|[X]

标签: javarecursionartificial-intelligencetic-tac-toeminimax

解决方案


我认为问题在于你如何确定谁赢了calcScore。您使用Util.getInstance().getTurnCounter(),但您似乎没有在递归调用中更新计数器。您可以改为使用depth % 2or isMax

if (AIcheck.checkWin()) {
    return isMax ? -1 : 1;
}

推荐阅读