Java 实现扫雷与高胜率低耗时自动扫雷 AI (下)

在这里插入图片描述

上一篇博客介绍了本项目总体情况, 这一篇来介绍一下我实现的自动扫雷 AI 算法. 本 AI 胜率比网上最高胜率的 AI 差 0.5% 左右. 不过本 AI 也不是没有优势, 它运算速度很快 (强行有优势 (ˉ▽ ̄~)), 平均 42 毫秒可以扫完一局 Win XP 规则下的专家难度.

这篇博客会介绍一下我的思路和踩过的坑, 也会列出一些关于胜率的数据. 希望能够帮助其他萌新入个门. 项目已经开源, 代码也写了注释, 链接放在文章最后.

先再次把最终成品的 AI 胜率等指标罗列一下:

指标 Win XP 规则测试结果 Win 7 规则测试结果
测试版本 Win XP 规则, 专家难度 Win 7 规则, 专家难度
测试局数 50,0000 局 50,0000 局
胜率 39.68% 52.45%
运行总耗时 21275 秒 33136 秒
每局平均耗时 42 毫秒 66 毫秒
胜局的每局平均耗时 57 毫秒 68 毫秒

注1: 测试 Win XP 规则是在半夜运行的, 电脑除了扫雷没有在运行其他进程; 而测试 Win 7 规则时我同时还在拿电脑办公, 导致 Win 7 规则下耗时比 XP 多. 而实际上 Win XP 与 Win 7 应该运行时间差不多.
注2: 测试使用的扫雷程序是自己复现的 Win XP 与 Win 7 规则, 而非模拟鼠标点击原版扫雷窗口. 因为那样太慢了. 网上有大佬已经测试过, Win XP, Win 7 原版扫雷并无影响地雷分布的隐藏规则. 所以若真要在原版上测试, 结果应该不会有较大偏差.

我在网上找到的胜率最高的扫雷 AI 是 ztxz16 大佬写的, Win XP 版本胜率 40.07%, Win 7 版本胜率 52.98%. 我的做法也是参考了 ztxz16 大佬的算法 (最强扫雷 AI 算法详解 + 源码分享 - ztxz16). B 站的 _黄歪歪 应该也是他, 也发了些关于扫雷 AI 的视频. 膜一波.

不过 ztxz16 大佬的这个项目偏试验性, 我顶着没有注释的压力把大佬开源的源码看了一遍, 看得出来有些地方他应该是懒得优化, 最终 AI 速度不是很快. 我本来想自己测试一遍他的 AI, 但跑了一晚上也只跑出来了几千局还是几万局 (捂脸).

该交代的差不多都交代完了, 下面开始讲我的做法.

高胜率低耗时自动扫雷 AI 算法

术语与定义

统一一下一些操作的术语方便后续描述. 我不是扫雷圈的, 很多术语可能不知道, 所以如果以下操作本来就有自己的中文名称, 提醒我我会改过来的!

操作 术语
鼠标左键, 那个点开格子的操作 挖掘
鼠标右键, 那个放置小红旗的操作 插旗
鼠标双键或中键, 那个自动检测周围八格是否可挖掘的操作 检查周围
空白的, 没点过的格子 未知格
已知的有数字 (包括 0) 的格子 (已挖开且不是雷的格子) 数字格

另外,

  1. 格子坐标 ( x , y ) (x, y) (x,y) 表示 x x x y y y 列, 下标从 0 0 0 开始.
  2. N N N M M M 为棋盘行数与列数, S = N × M S = N \times M S=N×M 表示格子总数.
  3. 以下所涉及的 “胜率”, 除非另外注明, 均为 Win XP 规则专家难度下的胜率.

第一步: 开局挖哪

开局第一步点击不同的地方也是会影响胜率的. 根据 ztxz16 大佬的测试 (地表最强扫雷AI • 编程探索扫雷极限胜率 - _黄歪歪), 开局 Win XP 挖掘 ( 0 , 0 ) (0, 0) (0,0), Win 7 挖掘 ( 2 , 2 ) (2, 2) (2,2) (或对称的另外三个角落) 胜率最高.

我自己也对 Win XP 与 Win7 大致测了一下 ( 0 , 1 ) (0, 1) (0,1), ( 1 , 0 ) (1, 0) (1,0), ( 1 , 1 ) (1, 1) (1,1) 等几个位置, 确实如此, 胜率会下降 1% ~ 2% 左右.

在这里插入图片描述 在这里插入图片描述
Win XP 开局 ( 0 , 0 ) (0, 0) (0,0) Win 7 开局 ( 2 , 2 ) (2, 2) (2,2)

不过至于为什么是角落胜率比中心高, 我猜可能是角落有更多可套用减法公式的场景 (减法公式在下一节有讲). 减法公式本质就是根据相邻两个数字格的一侧去推断另一侧. 而边缘的格子天然已知靠边的一侧无雷, 因而可以更容易地推断出另一侧雷的个数.

第二步: 基于定义与定式

用到了两个基本公式或定式:

第一, 仅基于一格判断: 即根据目标数字格的数字与其周围八格 (角落的话不满八格) 的状态, 判断该数字格周围八格的未知格是不是全为雷或全不为雷. 这是扫雷最基本的公式. 其逻辑其实就是鼠标左右双键检查周围的逻辑.

第二, 基于相邻两格: 即使用减法公式.

在这里插入图片描述

如图, M M M, N N N 为两个相邻数字格, 两者上下各有一块互相影响的公共区域 P P P, Q Q Q, 左右则分别有互不影响的两翼 A A A, B B B. 记地雷数量为 C C C, 显然地雷数量 C C C 符合如下等式:

{ C A r o u n d M = C A + C P + C Q C A r o u n d N = C B + C P + C Q \begin{cases} C_{AroundM} = C_A + C_P + C_Q \\ C_{AroundN} = C_B + C_P + C_Q \end{cases} { CAroundM=CA+CP+CQCAroundN=CB+CP+CQ

两式相减即得减法公式:

C A r o u n d M − C A r o u n d N = C A − C B C_{AroundM} - C_{AroundN} = C_A - C_B CAroundMCAro

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值