You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

井字棋Negamax算法输出错误求排查:已实现Minimax但走法异常

井字棋Negamax算法错误排查与修复

核心问题分析

你的代码存在两个关键逻辑错误,导致Negamax输出错误走法:

  1. 终止条件的得分处理错误
    Negamax的核心是递归时通过对得分取反来切换玩家视角,因此终止节点的得分不需要再根据maximizingPlayer取反。你的代码里在游戏结束时返回maxmizingPlayer? score : -score,这会导致得分视角混乱,最终计算出错误的最优解。

  2. Alpha-Beta剪枝的alpha更新逻辑错误
    当前代码用bestMove.score更新alpha,但正确的做法应该是用当前遍历的move.score来更新,因为bestMove是累计的最优值,而alpha需要反映当前分支能获得的最大下界,用当前move的得分才符合剪枝逻辑。

修正后的代码

static negamax(board, alpha, beta, maximizingPlayer) {
    const emptyCells = this.getEmptyCells(board);
    if (this.isGameOver(board) || emptyCells.length === 0) {
      // 直接返回评估得分,无需根据玩家取反
      return { score: this.evaluate(board) };
    }
    let bestMove = { score: -Infinity };
    for (let i = 0; i < emptyCells.length; ++i) {
      const { x, y } = emptyCells[i];
      board[y][x] = maximizingPlayer ? this.mySymbol : this.opSymbol;
      // Negamax递归:取反得分和alpha/beta值,切换玩家
      const childMove = this.negamax(board, -beta, -alpha, !maximizingPlayer);
      const move = {
        score: -childMove.score,
        x,
        y
      };
      board[y][x] = this.emptySymbol;
      
      // 更新最优走法
      if (move.score > bestMove.score) {
        bestMove = move;
      }
      // 用当前move的得分更新alpha,而非bestMove的得分
      alpha = Math.max(alpha, move.score);
      if (beta <= alpha) {
        break;
      }
    }
    return bestMove;
  }

static evaluate(board) {
    if (this.isWinning(board, this.mySymbol)) { // 修正原代码拼写错误:isWining → isWinning
      return Infinity;
    }
    if (this.isWinning(board, this.opSymbol)) {
      return -Infinity;
    }
    return 0;
  }

额外注意点

  • 原代码中isWining是拼写错误,修正为isWinning,避免函数调用失败。
  • 递归调用时直接获取子节点的返回值再取反得分,代码结构更清晰。

内容的提问来源于stack exchange,提问作者saltdream

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:55:08