我正在尝试实现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。
答案 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编码:)