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的单步评估。

相关推荐
叼烟扛炮4 分钟前
[LangChain] 学习笔记(08):工具调用底层闭环与第三方搜索(Tavily)实战
人工智能·笔记·学习·langchain
DQQzero13 分钟前
0.16 元/秒的短剧流水线:即梦短剧工作室把 AI 视频生产改成了什么样
人工智能·ai·aigc·视频生成
@追求卓越21 分钟前
深度学习记录
人工智能·深度学习
武子康1 小时前
H3-World 为何在加载 LoRA 前,先检查导入的代码?
人工智能·深度学习·算法
装不满的克莱因瓶1 小时前
【SpringAI Alibaba】ReactAgent结构化输出OutputType与OutputSchema实战
java·人工智能·ai·springai·springaialibaba
楚山之石2 小时前
【Radiology】影像组学的标准化与可重复性:IBSI 卷积滤波器共识及其未能覆盖的环节
人工智能·学习·机器学习·mri
东姬AI2 小时前
挖出948个内核漏洞、自动写补丁:GPT-6 Cyber把AI推进“实战岗“,内容行业还卡在哪一关?
人工智能·网络安全·openai·gpt-6
用户2991422196802 小时前
GitHub 热榜项目:日榜(2026-11-10)
人工智能·开源·github
用户2991422196802 小时前
AI 日报(2026年11月10日)
人工智能
秋天的怀念_David2 小时前
算法一千零一夜 · 第二十八夜 注册
java·程序人生·算法