Let's Minesweeper(一起来扫雷) 自动扫雷程序
因为自己在玩一个Steam的多人扫雷游戏,最近又进一步学习了AI开发和测试,所以心血来潮做了一个自动扫雷程序。
难点不在于扫雷的算法,而是在这个超大的地图中通过什么样的拖动导航,精确找到未打开和已开格子的边缘地带。
好在最后终于也是成功开发,虽然导航还是存在一丝丝问题,但是完全可以可以用了。
项目地址: Github:letsminesweeper-bot
Let's Minesweeper 自动扫雷程序
这是一个完全离线运行的 Let's Minesweeper(一起来扫雷) 自动扫雷辅助程序。它通过读取当前游戏窗口截图,识别棋盘格、数字、地雷和特殊图形,再使用本地规则推理决定下一步操作。
程序只处理当前可见视口,不尝试读取或保存整张超大地图;当当前区域没有可执行操作时,会通过拖动鼠标探索相邻区域。
一、Let's Minesweeper 简单介绍
Let's Minesweeper(一起来扫雷) 是经典扫雷游戏的玩法。与普通固定大小的扫雷不同,本游戏地图非常大,需要按住鼠标左键拖动视口来查看不同区域。
游戏中主要存在以下类型的格子:
- 已打开的空白格和数字格。
- 未打开的灰色格。
- 灰色背景上带有图形的已确认雷格。
- 已打开的雷图形。
- 黄色宝箱,包括打开和关闭两种外观,属于安全图形格。
二、特性
识别与推理
- 自动定位当前窗口和可见棋盘网格。
- 支持数字
1–6的颜色识别。 - 灰格上出现任何图形时,按游戏规则识别为地雷。
- 支持黄色宝箱安全图形识别。
- 支持“已经打开的雷”图形识别,并将其计入周围数字的雷数。
- 使用基础扫雷规则和集合差分规则推导安全格与地雷。
- 只执行确定性操作,不进行概率猜雷。
自动操作
- 连续批量右键标旗,再连续批量左键开格。
- 点击带有移动等待、按键保持和点击间隔,降低游戏漏收输入的概率。
- 自动拖动地图,拖动后等待画面稳定并重新校准网格。
- 允许从任意完整棋盘格开始拖动,拖动不会触发开格或踩雷。
- 沿未开区域边缘顺时针探索,并尽量让已开格与未开格各占视口一半。
- 当前视口清空时,先沿最后一次开格或标雷方向移动一次,再进入顺时针探索。
- 识别异常时最多进行
8次恢复拖动,恢复成功后继续运行。 - 中央小块未开区域会被识别为孤岛并主动离开,避免围绕孤岛循环。
- 沿前沿搜索超过一分钟没有找到可执行区域时,在战术台提示按
F8停止并手动更换区域。
战术台
- 观察窗口默认不勾选“每秒自动刷新”,需要时手动开启。
- 自动运行时观察窗口保持打开。
F8紧急停止。- 统计自动程序实际执行的累计开格和标旗数量。
- 统计数据持久化到本地,重启程序或重新开始自动运行不会清零。
- 提供“清除统计”按钮,只有手动点击后才会归零。
- 截图识别在后台线程运行,减少窗口卡顿。
- 小窗口布局下,开始、暂停、执行一批、重新读取和自动刷新选框仍保持可见。
三、运行要求
操作系统
- Windows 10 或 Windows 11。
- 屏幕必须处于解锁状态。
Let's Minesweeper窗口需要保持可见;使用屏幕截图后备方式时不能被其他窗口遮挡。
软件环境
- Python 3.10 或更高版本。
- Python 标准库中的 Tkinter。
- Pillow。
- NumPy。
- OpenCV-Python。
当前项目使用的导入依赖为:
1 | Pillow |
自动点击通常需要以管理员权限运行程序;如果出现 WinError 5,请使用“以管理员身份运行”。
四、软件说明
Github文件结构
1 | lets-minesweeper-bot/ |
战术台示意
战术台左侧显示当前棋盘截图和识别覆层,右侧显示当前安全格、建议标雷、未开格、累计统计和操作按钮。
颜色含义:
- 蓝框:确定安全,可以开格。
- 红框:逻辑推导出的待标雷。
- 绿框:游戏画面中已经带图形的确认雷。
- 深红框:已经打开的雷,不会再次操作。
- 金色框:黄色宝箱安全格。
- 紫色框:无法识别的格子,程序不会根据它点击或标雷。
关键安全机制
- 拖动过程中不把中间截图交给识别器。
- 鼠标释放后连续确认画面稳定,才重新识别棋盘。
- 点击批次结束后等待绿色浮动加分文字消失。
- 识别矛盾或网格异常时不执行点击。
F8可以中断点击批次和拖动过程。
五、使用方法
1. 准备游戏窗口
- 启动
Let's Minesweeper。 - 将窗口还原并保持棋盘可见。
- 如果使用自动点击,请确保游戏和自动程序使用相同的权限级别;推荐都以管理员权限运行。
2. 启动战术台
双击:
start-minesweeper-bot.cmd
也可以cd到项目目录运行:
1 | python .\app.py |
3. 观察模式
程序启动后会自动读取一次当前视口。此时默认不会每秒刷新,也不会点击游戏。
需要持续观察时,勾选“每秒自动刷新”。
4. 执行一批
点击“执行一批”时,程序只处理当前截图中已经推导出的这一批标旗和开格操作,完成后返回观察状态。
5. 开始自动运行
点击“开始自动运行”后,程序会等待一秒,然后循环执行:
1 | 读取当前视口 |
6. 暂停和紧急停止
- 点击“暂停”:等待当前鼠标按键释放后停止。
- 按
F8:立即停止后续操作;拖动过程中会释放左键。 - 如果一分钟内一直找不到可开区域,按提示使用
F8停止,再手动把游戏换到新的区域。
六、测试过程
项目使用本地截图样本和离线单元测试验证,不需要网络。
测试覆盖内容包括:
- 普通灰格、数字、空白格识别。
- 数字
6识别。 - 黄色宝箱和关闭宝箱识别。
- 已打开雷识别及雷数约束。
- 拖动动画期间不识别,稳定后重新校准。
- 从任意格子开始拖动。
- 顺时针未开区域边缘导航。
- 开格/未开格比例救援。
- 中央未开孤岛逃离。
- 当前视口清空后的探索。
- 异常识别后的最多
8次恢复拖动。 - 累计统计持久化和手动清零。
- 战术台默认自动刷新状态。
运行测试:
1 | python -m unittest discover -s .\tests -v |
当前已验证全部 34 项测试通过,并完成 Python 编译检查:
1 | python -m compileall -q .\app.py .\minesweeper .\tests |
注意事项
- 本程序只针对当前
Let's Minesweeper的画面风格和交互方式进行识别。 - 游戏窗口移动、缩放或遮挡后,程序需要重新读取并校准。
- 遇到新图形素材时,建议先保持观察模式并采集截图,再加入识别规则。
- 程序不会获取或保存整张超大地图,只保留当前视口和少量导航状态。