0%

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

渐变头图
渐变头图

东西是疫情期间做的, 但由于拖延症博客一直拖到现在都没写, 半年了再不写出来自己都要忘光了 _(:з」∠)_.

起因是疫情期间蹲家里, 就迷上了扫雷. Win XP 的扫雷程序在高分辨率屏下体验不好, 于是一开始是玩的 Win 10 商店里的那个 Microsoft Minesweeper, 但它区区一个扫雷却还好意思整了那么多广告, 搞得花里胡哨体验还差. 于是一时气愤, 决定自己写一个.

写完之后想着既然游戏本体都写了, 这不乘着气没消顺路再研究研究自动扫雷 AI? 于是又折腾了好一阵子, 终于发现 AI 确实难写... (啊不是), 终于写出一个胜率还能看, 速度也不差的 AI. 说实话写到后面挺丧气的, 毕竟是 19 世纪 60 年代的老游戏了, 我能想到的大佬们基本都想得到, 我做的也就是造个轮子以提高提高自己的代码姿势水平.

成品介绍

先列一下最终做出来的样子, 以防博客没人看. 开源地址放文末了.

AI 胜率

先看 AI 的胜率 (专家难度) 与运行效率. 在 Win XP 的规则下 (开局第一步戳的格子必不为雷):

  • 测试了 50,0000 局,
  • AI 胜率: 39.68%,
  • 运行总耗时: 21275秒 (串行跑的),
  • 每局平均耗时: 42毫秒,
  • 所有胜局的每局平均耗时: 57毫秒.

而在 Win 7 的规则下 (开局第一步戳的格子与其周围 8 格均不为雷), 也跑了 50,0000 局, AI 胜率 52.45%.

注1: 测试 AI 使用的游戏规则是根据 Win XP, Win 7 版扫雷公开的规则自己复现的 (而不是在原版游戏窗口上模拟鼠标点击, 那样测试起来太慢了), 使用的地雷随机生成算法肯定与原版游戏不同, 但运行结果应该是差不多的 (网上有大佬测过, 原版扫雷并没有什么特殊的隐藏规则). 注2: 测试用的是笔记本上的 CPU i7-7700HQ, 测试速度因人而异.

我在网上看到的胜率最高的的应该是 ztxz16大佬 的, Win XP 版本胜率 40.07%, Win 7 版本胜率 52.98%. 我的做法也有参考 ztxz16 大佬的算法 (最强扫雷 AI 算法详解 + 源码分享 - ztxz16).

游戏本体

游戏本体完成度其实也挺高的, 还带一些趣味小功能, 欢迎来玩~

首先是游戏界面. 仿的经典 XP 原版扫雷的风格. GUI 用的 Swing 编写. 操作比原版更人性化一点点, 比如支持改变格子大小, 支持单击已揭开的格子以快速检查周围 8 格 (原版要求左右键一起按) 等. 然后由于是 Java 写的所以跨平台 (Ubuntu 自带的扫雷竟然不能自动扫已知格子的周围八格, 十分影响体验. 但是在 Ubuntu 下实测 Emoji 和字体渲染有偏差, 但至少能用, 所以暂时不想管了).

稀疏平常的一局
稀疏平常的一局

菜单里的功能有:

所有菜单
所有菜单

其中部分功能的说明:

  1. 套娃扫雷: 在我的扫雷程序里扫原版程序的雷 (没看懂? 没看懂就对了). 原理是在屏幕里找到 XP 原版扫雷的窗口, 然后同步棋盘到我的扫雷程序的棋盘, 同时玩家对我的扫雷程序的操作都会同步到原版扫雷. 套娃扫雷 - 玩家

    乍一看是不是感觉很无厘头 <(* ̄▽ ̄*)/, 但此时再配合我的 AI 的概率预测与自动清扫功能, 事情就变得有意思了起来~ 套娃扫雷 - 概率

    没错, 可以拿来分析棋局! 帮助初学者快速入门 (好吧, 确实有种透视外挂的感觉了...

    当然硬要用 AI 去扫原版 XP 扫雷游戏也不是不可以~ 套娃扫雷 - 自动

  2. 规则切换: 众所周知, 扫雷有两套经典的规则, 分别使用在 Win XP 版与 Win 7 版上. Win XP 版的规则是, 挖的第一个格子必不为雷; Win 7 版的规则是, 挖的第一个格子与其周围 8 格均必不为雷.

  3. 作弊: 不开启作弊则下面的选项都是灰的. 开启作弊后不会计时 (永远 9999). > 注: 这里区分一下本游戏中的 "作弊" 与 "AI". 作弊是指直接告诉你所有雷在哪, AI 则是在游戏规则内帮你推断雷在哪.

  4. 撤销操作: 字面意思, 但是只能撤销一步, 毕竟不会真的有人在除了炸雷以外的时候去用这个功能吧?

  5. 透视: 直接把雷显示在棋盘上.

  6. 导入, 保存棋盘: 从文件导入残局, 以及把当前残局导出到文件. 为什么使用这个功能也需要先开启作弊呢? 因为文件里需要储存雷的位置...

  7. 提示一格: 使用最简单的扫雷规则找出一个必为雷或必不为雷的格子并予以高亮, 旨在辅助星际玩家找出遗漏的地方 (类似于连连看里的提示).

  8. 显示概率: 对整个棋盘精准地计算每个格子不是雷的概率 (通过展示出来的不同颜色, 相信你也猜出来大概用的什么算法去计算的了). AI - 概率

  9. 显示胜率: 对整个棋盘精准地计算每个格子作为下一步挖掘目标时的全局胜率. 计算胜率的算法复杂度爆炸, 所以只在残局未知格子少于等于 12 时才计算. 胜率和上面的概率是两个概念. 具体在算法原理部分会解释. AI - 概率 VS 胜率

  10. 安全清扫 (很快): 用简单的规则帮你清扫棋局. 所以运行速度极快. 所谓 "安全" 就是指只清扫必为雷或必不为雷的格子.

  11. 安全清扫 (较慢): 在上面规则的基础上, 计算概率再清扫一遍必为雷或必不为雷的格子. 尽管已经充分剪枝, 计算概率的复杂度依然较高. 绝大部分情况下还是能很快出结果, 但是在极端环境下可能会耗时很久.

  12. 扫到结束: 所有算法一起上, 遇到不一定是不是雷的格子则根据概率与胜率猜雷, 直到胜利或失败.

以上基本就是游戏的全部功能了. 下面介绍 AI 算法.

但是又看了一下, 本文长度够一篇了 (~ ̄▽ ̄)~, 所以决定拆开来, 下一篇再讲 AI, 这篇就算是项目介绍~

项目开源地址

本博客仅发布于 Github IO: https://xienaoban.github.io/posts/25814.html

和 CSDN: https://blog.csdn.net/xienaoban/article/details/112424609

其他都是盗的.

Github 发布页: https://github.com/xienaoban/minesweeper/releases (喜欢的话 Star 一下呀 (づ ̄3 ̄)づ╭❤~)

不会用 Github 的萌新也可以在这里下载: https://download.csdn.net/download/XieNaoban/14090898