破世界纪录了!用Python实现自动扫雷!
前阵子闲着无聊,晚上十二点多刷视频的时候看到有人用 AI 来玩扫雷,速度飞快。我那时候就想:这玩意我能不能自己撸一个?想着想着就把笔记本打开了,结果越写越上头,第二天早上四点才睡,搞出了一个自动扫雷脚本。 最神奇的是,跑起来之后我都愣了:这速度比网上那些“世界纪录”级别的都快。
不是因为我有多强,而是扫雷这种游戏——只要算法靠谱、鼠标点得快,你玩得再好都不可能比程序快。
事情是怎么开始的?
电脑桌面那个经典的扫雷图标其实我已经几年没点了。真正开始写是在某个晚上,我朋友突然问:“你不是搞 Python 吗?扫雷你能自动玩吗?”
我嘴上说:“应该不难吧。” 心里想的是:好像还真能搞。
扫雷逻辑简单:
无雷格子会显示数字 数字代表周围 8 个格子里的雷数 如果你能推算周围哪些是雷,就能把剩下的安全格点开
所以核心任务只有两个:
让 Python 识别格子的数字
让 Python 推断雷的位置并自动点击
听起来是不是挺简单? 实际上做起来也确实不复杂,但细节特别多。
第一步:截图 + 识别数字
我用的是 Python 搭配 OpenCV。 扫雷的界面非常规则,每个格子大小一致,所以我直接让程序不断截图,然后切出每个格子的小图片,丢给模板匹配(template matching)。
最早我傻乎乎地用 OCR,结果效果感人。 扫雷的数字那么小,OCR 根本识别不准。
后来改成模板匹配,小图直接对比,大大提高准确率。
示例代码大概长这样:
import cv2
import numpy as np
import pyautogui# 加载数字模板
templates = {
i: cv2.imread(f"./tpl/{i}.png", 0)
for i in range(1, 8)
}
defcapture_board():
screenshot = pyautogui.screenshot()
img = cv2.cvtColor(np.array(screenshot), cv2.COLOR_BGR2GRAY)
return img
defmatch_number(cell_img):
best = (0, None)
for n, tpl in templates.items():
res = cv2.matchTemplate(cell_img, tpl, cv2.TM_CCOEFF_NORMED)
score = res.max()
if score > best[0]:
best = (score, n)
return best[1] if best[0] > 0.7elseNone
数字识别这块调了好久,各种缩放、对比度、锐化都试过,最后解决方式特别憨憨:按固定尺寸截图 + 固定模板匹配扫雷画面不变,这招反而最稳定。
第二步:根据数字推算雷的位置
扫雷规则其实可以拆成一堆简单的约束:
如果一个格子的数字是 1,且周围只有一个未知格,那未知格就是雷。
如果数字是 2,周围有两个未知格,也同理。
所以核心就是扫描棋盘,找每个数字格,统计它周围:
未翻开格子数 已标雷的格子数
然后判断还能不能推断。
示例逻辑:
defsolve(board):
actions = []
for r in range(rows):
for c in range(cols):
num = board[r][c]
if num in range(1, 8):
around = get_neighbors(board, r, c)
unopen = [p for p in around if p.value == "unknown"]
flags = [p for p in around if p.value == "flag"]# 标记雷
if len(flags) + len(unopen) == num and len(unopen) > 0:
for p in unopen:
actions.append(("flag", p.r, p.c))
# 点安全格
if len(flags) == num and len(unopen) > 0:
for p in unopen:
actions.append(("open", p.r, p.c))
return actions
其实核心算法就是硬推理,不用什么 AI、深度学习,扫雷游戏本质就是个确定性谜题。
第三步:自动操作鼠标
扫雷窗口固定位置,鼠标点击也很容易。
defclick_cell(row, col, button="left"):
x = board_x + col * cell_w + cell_w//2
y = board_y + row * cell_h + cell_h//2
pyautogui.click(x, y, button=button)
刚开始我把点击速度设得很慢,怕出错。 后来把延迟调到几乎没有,结果鼠标飞一样点。
第一次跑起来的时候我人都傻了:扫雷在屏幕上像一个抖腿的机器人一样高速闪烁。
随机十遍专家模式(Expert Mode),最快一局直接给我干到 0.18 秒。 这是那种人眼根本看不清“发生了什么”的速度。
我当时都怀疑是不是程序没玩、直接点的某个通关按钮。 后来把整个过程录屏下来才相信它真的玩了。
网上公开最快纪录基本都是 0.x 秒 ~ 1.x 秒而我的这个……嗯,不能说世界第一,但绝对是“能和世界纪录平起平坐”的那种级别。
做完之后我才发现的几个坑
扫雷界面缩放会导致模板匹配失败
如果 Windows 缩放不是 100% 就会炸。
偶发的“猜雷”局面无法解决
扫雷本来就存在无法逻辑推断,只能赌概率的局面。 我的脚本遇到这种情况会选择概率最大的格子,但偶尔也会踩雷。
鼠标太快会触发系统保护
尤其在一些笔记本上,连续点击过快会被系统吞掉一些事件。
做完之后,我朋友说:“你做这个有啥用?”
我说:“用处?没有。但爽。”
其实就像很多程序员捣鼓的奇怪脚本一样:不是因为它有用,是因为我能搞出来。
如果你也想玩,这类自动化脚本真的特别适合作为 Python + OpenCV 的入门练习。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领