reactjs 递归在我的极大极小实现中似乎不起作用

8iwquhpp  于 12个月前  发布在  React
关注(0)|答案(1)|浏览(94)

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行输出,好像递归不起作用,没有进入每一个可能的选项。
我找了几天窃听器。。这个实现有什么问题?

yduiuuwa

yduiuuwa1#

但问题是,所采取的行动并没有被收回。该函数按预期递归调用,但随后板已满,此后它永远不会更改。因此,empty.length对于所有执行上下文都将为0,并且递归将展开而不进行其他移动。
要解决这个问题,请在push之后添加以下行:

gameLayout[empty[i]] = ''; // take back

相关问题