miniMax
函数返回一个由索引和分数组成的对象,但它没有访问预期的那么多状态。
下面是代码:
const human = 'X'
const ai = 'O'
const winOptions = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
const emptyCells = (layout) => {
return layout.map((item, index) => {
return (item === '' ? index : null)
}).filter((item) => item !== null)
}
const checkWin = (layout) => {
for (let i = 0; i < winOptions.length; i += 1) {
const [a, b, c] = winOptions[i]
if (layout[a] === 'X' && layout[a] === layout[b] && layout[b] === layout[c]) {
return -1
}
if (layout[a] === 'O' && layout[a] === layout[b] && layout[b] === layout[c]) {
return 1
}
}
return false
}
function miniMax (gameLayout, player) {
const empty = emptyCells(gameLayout)
if (checkWin(gameLayout) === 1) {
return { score: 10 }
} else if (checkWin(gameLayout) === -1) {
return { score: -10 }
} else if (empty.length === 0) {
return { score: 0 }
}
const moves = []
for (let i = 0; i < empty.length; i++) {
const move = {}
move.index = empty[i]
player === 'O' ? gameLayout[empty[i]] = 'O' : gameLayout[empty[i]] = 'X'
player === 'O' ? move.score = miniMax(gameLayout, human).score : move.score = miniMax(gameLayout, ai).score
moves.push(move)
}
let bestMove
if (player === 'O') {
bestMove = moves.reduce((acc, curr, i) => moves[acc].score > curr.score ? acc : i, 0)
} else {
bestMove = moves.reduce((acc, curr, i) => moves[acc].score < curr.score ? acc : i, 0)
}
console.log(JSON.stringify(moves))
return moves[bestMove]
}
// Example run:
const layout = ["X", "", "" ,
"" , "", "" ,
"" , "", "O"]
miniMax(layout, "X")
下面是它的外观,上面的代码片段中生成了控制台输出:
很明显,我的井字游戏的极大极小实现并没有像预期的那样工作。控制台应该充满了输出,因为有许多枚举选项。但它只显示了6行输出,好像递归不起作用,没有进入每一个可能的选项。
我找了几天窃听器。。这个实现有什么问题?
1条答案
按热度按时间yduiuuwa1#
但问题是,所采取的行动并没有被收回。该函数按预期递归调用,但随后板已满,此后它永远不会更改。因此,
empty.length
对于所有执行上下文都将为0,并且递归将展开而不进行其他移动。要解决这个问题,请在
push
之后添加以下行: