当前位置: 首页 > news >正文

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

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

设计截图如下:

为什么需要Minimax

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

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

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

Minimax算法原理

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

代码实现

privategetHardMove(board:number[][]):Move{constcandidates=this.getSortedCandidates(board);constmaxCandidates=Math.min(12,candidates.length);letbestMove:Move=candidates[0];letbestScore:number=-Infinity;letalpha:number=-Infinity;constbeta:number=Infinity;for(leti=0;i<maxCandidates;i++){constmove=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;returnmove;}// Minimax递归(对手回合,最小化)constscore=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);}returnbestMove;}

minimax递归函数

privateminimax(board:number[][],depth:number,alpha:number,beta:number,isMaximizing:boolean):number{// 终止条件:深度为0时评估局面if(depth===0){returnthis.evaluateBoard(board);}constcandidates=this.getSortedCandidates(board);constmaxCandidates=Math.min(8,candidates.length);if(isMaximizing){// AI回合:找最大值letmaxEval:number=-Infinity;for(leti=0;i<maxCandidates;i++){constmove=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;returnSCORE_FIVE;// AI获胜}constevalScore=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剪枝}returnmaxEval;}else{// 对手回合:找最小值letminEval:number=Infinity;for(leti=0;i<maxCandidates;i++){constmove=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最不利)}constevalScore=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剪枝}returnminEval;}}

搜索树图解

假设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的选择

constscore=this.minimax(board,2,alpha,beta,false);
  • 深度1:只看对手反应——不够
  • 深度2:看AI→对手→AI——合理
  • 深度3:AI→对手→AI→对手——更好但计算量大

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

2. 候选数量限制

// 顶层:12个候选constmaxCandidates=Math.min(12,candidates.length);// 递归层:8个候选constmaxCandidates=Math.min(8,candidates.length);

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

3. 立即获胜检查

if(this.checkWin(board,move.row,move.col,this.aiColor)){board[move.row][move.col]=EMPTY;returnmove;// 不需要继续搜索}

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

4. 评估函数的差异

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

privateevaluateBoard(board:number[][]):number{letaiScore:number=0;lethumanScore:number=0;aiScore+=this.evaluateLines(board,this.aiColor);humanScore+=this.evaluateLines(board,this.humanColor);returnaiScore-humanScore*1.1;}

总结

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

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

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

http://www.jsqmd.com/news/1144625/

相关文章:

  • 【导弹】基于 6 种制导律PPNGDPGVDPGRDPGRDPG_TRDPG_SAFE的飞行器交会(Rendezvous)制导附MATLAB 代码
  • Obsidian:重新定义英雄联盟游戏资源管理的技术解决方案
  • 2026年实用降AI率平台:亲测AI率从90%降至4%的实用方案
  • wushowhide.diagcab 工具实战:3步屏蔽Windows 11自动更新AMD显卡驱动
  • Mega安汇:把外汇投教内容建设做扎实,更谨慎的使用者更容易感受到的维度
  • 珠三角全栈AI智能体私有化大模型定制开发综合实力对比
  • AI时代,服务的主角依然是人|笃实科技客户服务最佳实践
  • KuGouMusicApi双版本架构技术解析与VIP权限兼容性解决方案
  • YOLO实战第四篇:训练曲线全方位解读教程(看懂收敛、过拟合、精度好坏,告别盲目训练)
  • 【安全与故障排查】04-Redis未授权访问漏洞修复与防御体系建立
  • de4dot实战指南:.NET程序反混淆原理与逆向工程实践
  • STM32L442KC与ISOM8710构建高压隔离系统设计
  • 瑞德克斯平台:把合规意识做扎实,新手更容易感受到的标准
  • SonarQube 10.x JWT 签名漏洞排查:从 none 算法到 HS256 的 5 个修复要点
  • 23个测试全绿,一个Token没花——LLM应用的单元测试该怎么写?
  • COCO 2017 与 MPII 数据集实战:3步完成关键点标注格式转换与可视化
  • 15个实用的团队协作平台,敏捷开发
  • 我以为代码整洁对 AI Agent 影响很大,结果 660 次测试告诉我错了
  • 基于ADM工具实现Qwen 35B大模型一键本地部署实践指南
  • AI 辅助理解 Rust 泛型:让模型用具体类型举例,再抽象回泛型
  • 海岛微电网仿真:3 种典型场景(晴/阴/负荷变化)下的能量管理策略对比分析
  • THPX信号源:把技术架构做到位——逻辑梳理与提示整理
  • 短剧系统数据模型怎么搭?短剧源码与短剧平台搭建技术实战
  • 3 种注意力机制改进 YOLOv7:在红外目标检测任务中的对比与《红外与激光工程》投稿适配
  • MAX77654与MKV42F嵌入式电源管理方案设计与优化
  • Xilinx Zynq-7000 7个关键引脚详解:POR_OVERRIDE到PS_INIT_B的硬件设计指南
  • maSigPro 与 Mfuzz 对比:2种时间序列基因表达聚类方案选择指南
  • Harness Engineering与Hermes Agent框架:企业级AI Agent开发实战指南
  • http_lib:纯仓颉标准库 HTTP 封装,HTTP/1 + HTTP/2 + HTTP/3
  • 直流电机静音驱动方案:TB9051FTG与PIC18F96J94实战