井字游戏MiniMax实现始终返回第一个空位

时间:2020-01-13 21:03:17

标签: javascript minimax

我正在尝试实现Minimax,以在js的井字游戏中找到每一转的最佳动作。

但是,它总是返回第一个空闲点:0,0,当该点取为0.1时,依此类推。 事实证明miniMax函数始终返回1。

let board = [
    ['', '', ''],
    ['', '', ''],
    ['', '', '']
];

const scores = {
    'X': 1,
    'O': -1
}

function miniMax(board, isMaximizing, player, turns) {
    let winner = checkForWinner(board);
    if (winner != null)
        return scores[winner];
    if (turns > 9)
        return 0;

    let bestScore = isMaximizing ? -Infinity : Infinity;
    let score;

    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            if (board[i][j] == '') {
                board[i][j] = player;
                score = miniMax(board, !isMaximizing, isMaximizing ? p2 : p1, turns + 1)[1];
                board[i][j] = '';
                if (isMaximizing) {
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove = [i, j];
                    }
                }
                else {
                    if (score < bestScore) {
                        bestScore = score;
                        bestMove = [i, j];
                    }
                }
            }
        }
    }

    return [bestMove, bestScore];
}

我尝试查看其他人对井字游戏的Minimax的实现,但我不明白是什么使我的失败。

我做错了什么?

编辑:我已经更新了代码,但现在返回的是0、0、1,0、0、1、2、0、0、2。

1 个答案:

答案 0 :(得分:1)

我发现您的minimax(negamax)代码有2个问题:

'1。在您的minimax函数中,您正在遍历每个正方形,以找到最佳移动方式。但是,您只返回分数,而不是最佳动作。如果您发现获胜的举动,请写下:

return None, 1

然后在您的minimax递归调用中编写:

miniMax(board, !isMaximizing, isMaximizing ? p2 : p1, turns + 1)[1]

在底部的返回处,您将写:

return bestMove, bestScore

仅当最大/最小得分发生变化时,您才需要在确定bestScore的同时更新bestMove。与在bestMove函数中执行的操作类似。

'2。在bestMove函数中,您将再次遍历所有正方形。这就是使它一遍又一遍返回相同平方的原因。由于您的minimax会找到最好的举动,因此您只需拨打初始电话即可:

bestMove, bestScore = miniMax(board, !isMaximizing, isMaximizing ? p2 : p1, turns + 1)

否则,它将移动到第一个方块并进行完整的最小极大值,因此找到该位置的最佳移动(无论起始移动如何)。由于永远不会找到比最佳移动更好的移动,因此不会将bestMove更新为除第一个可能的平方以外的任何其他值。

希望我有任何意义,英语不是我的母语,并且我只习惯于使用Python编码:)