HarmonyOS 小游戏《对战五子棋》开发第14篇 - 困难AI实现:Minimax算法原理详解

向前看两步------Minimax让AI学会"换位思考"

设计截图如下:

为什么需要Minimax

普通AI的局限:只看当前一步,不考虑对手的反击。

场景:AI可以选择形成活三(8000分)或冲四(10000分)。普通AI选冲四,但对手下一步会堵住冲四,AI的活三机会丢失了。

Minimax的核心思想:假设对手也会做出最优选择,选择对自己最不坏的结果

Minimax算法原理

复制代码
        AI选择(最大化)
       /    |    \
     候选1  候选2  候选3
     / \    / \    / \
   对手选择(最小化)
   ↓   ↓  ↓   ↓  ↓   ↓
  评估 评估 评估 评估 评估 评估
  • Max层(AI回合):选择分数最高的走法
  • Min层(对手回合):选择分数最低的走法(对AI最不利)
  • 叶节点:用评估函数计算当前局面的分数

代码实现

typescript 复制代码
private getHardMove(board: number[][]): Move {
  const candidates = this.getSortedCandidates(board);
  const maxCandidates = Math.min(12, candidates.length);
  let bestMove: Move = candidates[0];
  let bestScore: number = -Infinity;
  let alpha: number = -Infinity;
  const beta: number = Infinity;

  for (let i = 0; i < maxCandidates; i++) {
    const move = candidates[i];
    board[move.row][move.col] = this.aiColor;

    // 如果直接获胜,立即返回
    if (this.checkWin(board, move.row, move.col, this.aiColor)) {
      board[move.row][move.col] = EMPTY;
      return move;
    }

    // Minimax递归(对手回合,最小化)
    const score = this.minimax(board, 2, alpha, beta, false);
    board[move.row][move.col] = EMPTY;

    if (score > bestScore) {
      bestScore = score;
      bestMove = move;
    }
    alpha = Math.max(alpha, score);
  }
  return bestMove;
}

minimax递归函数

typescript 复制代码
private minimax(board: number[][], depth: number, alpha: number, beta: number,
  isMaximizing: boolean): number {
  // 终止条件:深度为0时评估局面
  if (depth === 0) {
    return this.evaluateBoard(board);
  }

  const candidates = this.getSortedCandidates(board);
  const maxCandidates = Math.min(8, candidates.length);

  if (isMaximizing) {
    // AI回合:找最大值
    let maxEval: number = -Infinity;
    for (let i = 0; i < maxCandidates; i++) {
      const move = candidates[i];
      board[move.row][move.col] = this.aiColor;

      if (this.checkWin(board, move.row, move.col, this.aiColor)) {
        board[move.row][move.col] = EMPTY;
        return SCORE_FIVE;  // AI获胜
      }

      const evalScore = this.minimax(board, depth - 1, alpha, beta, false);
      board[move.row][move.col] = EMPTY;

      maxEval = Math.max(maxEval, evalScore);
      alpha = Math.max(alpha, evalScore);
      if (beta <= alpha) break;  // Alpha-Beta剪枝
    }
    return maxEval;
  } else {
    // 对手回合:找最小值
    let minEval: number = Infinity;
    for (let i = 0; i < maxCandidates; i++) {
      const move = candidates[i];
      board[move.row][move.col] = this.humanColor;

      if (this.checkWin(board, move.row, move.col, this.humanColor)) {
        board[move.row][move.col] = EMPTY;
        return -SCORE_FIVE;  // 对手获胜(对AI最不利)
      }

      const evalScore = this.minimax(board, depth - 1, alpha, beta, true);
      board[move.row][move.col] = EMPTY;

      minEval = Math.min(minEval, evalScore);
      beta = Math.min(beta, evalScore);
      if (beta <= alpha) break;  // Alpha-Beta剪枝
    }
    return minEval;
  }
}

搜索树图解

假设AI在搜索深度2,候选3个:

复制代码
深度2           AI选择(MAX)
              /     |      \
深度1       对手(MIN) 对手(MIN) 对手(MIN)
           /  \     /  \     /  \
深度0    评估  评估  评估  评估  评估  评估
          80   50   60   30   90   70

自底向上计算:
  深度1: min(80,50)=50  min(60,30)=30  min(90,70)=70
  深度2: max(50,30,70)=70 → 选择候选1

关键设计决策

1. 深度2的选择

typescript 复制代码
const score = this.minimax(board, 2, alpha, beta, false);
  • 深度1:只看对手反应------不够
  • 深度2:看AI→对手→AI------合理
  • 深度3:AI→对手→AI→对手------更好但计算量大

移动端选择深度2是性能与棋力的平衡。

2. 候选数量限制

typescript 复制代码
// 顶层:12个候选
const maxCandidates = Math.min(12, candidates.length);
// 递归层:8个候选
const maxCandidates = Math.min(8, candidates.length);

搜索树大小 = 12 × 8 × 8 = 768,在移动端可接受。

3. 立即获胜检查

typescript 复制代码
if (this.checkWin(board, move.row, move.col, this.aiColor)) {
  board[move.row][move.col] = EMPTY;
  return move;  // 不需要继续搜索
}

找到必胜走法立即返回,避免不必要的搜索。

4. 评估函数的差异

困难模式使用evaluateBoard(全盘评估),而非普通模式的evaluatePosition(单点评估):

typescript 复制代码
private evaluateBoard(board: number[][]): number {
  let aiScore: number = 0;
  let humanScore: number = 0;
  aiScore += this.evaluateLines(board, this.aiColor);
  humanScore += this.evaluateLines(board, this.humanColor);
  return aiScore - humanScore * 1.1;
}

总结

Minimax算法是博弈树搜索的经典方法:

  1. 换位思考:假设对手做出最优选择
  2. 最大最小:AI最大化,对手最小化
  3. 递归搜索:从叶节点向上回传
  4. 深度控制:平衡棋力与性能

困难模式通过深度2的Minimax搜索,能预见2步之后的局面变化,显著强于普通AI的单步评估。

相关推荐
YOLO数据集集合1 小时前
机雾天航拍挑战:11,600张雾霾场景目标检测数据集全解析
人工智能·目标检测·目标跟踪
图特摩斯科技1 小时前
从Palantir本体论角度对广西洪水的一点思考:如果有 OntoFlow 这类本体平台,应急管理能够做到什么?
人工智能·abutiongraph·palantir·ontology·ontoflow·ontoos
码云之上1 小时前
项目团队从 5 人扩到 15 人,我写了个 CLI 让 IDE 共享 AI 规则
前端·人工智能·后端
2601_956865771 小时前
# 2026年AI API中转平台选型指南:高并发能力、协议兼容与白盒计费体系深度解析
人工智能·api
格子软件1 小时前
GEO系统深度实战:多引擎自适应算法与去中心化流控
人工智能·算法·去中心化·区块链
触底反弹1 小时前
面试被问 RAG 只能说出六个字?这篇用 100 行 Node.js 代码帮你彻底搞懂
javascript·人工智能·面试
小白跃升坊1 小时前
1Panel企业版+AI门户|从零构建企业专属AI门户
人工智能·ai·1panel·skills·ai运维·ai门户
写代码像蔡徐抻1 小时前
三年了,为什么 AI 应用还没爆发?
人工智能
宝贝儿好1 小时前
【LLM】第三章:BERT讲解+情感分析案例
人工智能·深度学习·神经网络·算法·自然语言处理·bert