【问题标题】:Tic-Tac-Toe MiniMax implementation always returns first free spotTic-Tac-Toe MiniMax 实施总是返回第一个空闲位置
【发布时间】:2020-01-13 21:03:17
【问题描述】:

我正在尝试实现 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。

【问题讨论】:

    标签: javascript minimax


    【解决方案1】:

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

    '1.在您的极小极大函数中,您将遍历每个方格以找到最佳移动。但是,您只返回分数,而不是最佳移动。如果你发现了一个获胜的举动,那么写下这个:

    return None, 1
    

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

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

    在底部返回你写:

    return bestMove, bestScore
    

    在您决定 bestScore 的地方,您还需要更新 bestMove,仅当最高/最低分数发生变化时。类似于你在 bestMove 函数中所做的。

    '2.在您的 bestMove 函数中,您将再次遍历所有方块。这就是让它一遍又一遍地返回同一个方块的原因。由于您的极小极大会找到最佳移动,因此您只需进行初始调用:

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

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

    希望我能说得通,英语不是我的母语,我只习惯用 Python 编码 :)

    【讨论】:

    • 感谢您抽出宝贵时间回答!你说的我试过了,改了minimax函数,也没用bestMove函数,还是不行。现在它返回 0,0 然后 1,0 然后 0,1 然后 2,0 然后 0,2。我做错了什么?
    • 我无法在评论中写...我将编辑我的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多