扫雷代码教程简单(室友扫雷通关来炫耀)
扫雷代码教程简单(室友扫雷通关来炫耀)我给出我的第三方库和版本仅供参考win32api win32gui win32con Pillow numpy opencv可通过 pip install --upgrade SomePackage 来进行安装注意:有的版本是下载pywin32,但是有的要把pywin32升级到最高并自动下载了pypiwin32,具体情况每个python版本可能都略有不同源自:https://www.cnblogs.com/chestnut-egg/p/9302238.html我是win10,没有默认的扫雷,所以去扫雷网下载http://www.saolei.net/BBS/2.python 3我的版本是 python 3.6.1
自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。
代码已上传至GitHub:
https://github.com/chestnut-egg/GoMine
作者:chestnut_egg
源自:https://www.cnblogs.com/chestnut-egg/p/9302238.html
一、准备工作1.扫雷游戏
我是win10,没有默认的扫雷,所以去扫雷网下载
http://www.saolei.net/BBS/
2.python 3
我的版本是 python 3.6.1
3.python的第三方库
win32api win32gui win32con Pillow numpy opencv可通过 pip install --upgrade SomePackage 来进行安装注意:有的版本是下载pywin32,但是有的要把pywin32升级到最高并自动下载了pypiwin32,具体情况每个python版本可能都略有不同
我给出我的第三方库和版本仅供参考
二、关键代码组成
1.找到游戏窗口与坐标
#扫雷游戏窗口
class_name="TMain"
title_name="MinesweeperArbiter"
hwnd=win32gui.FindWindow(class_name title_name)
#窗口坐标
left=0
top=0
right=0
bottom=0
ifhwnd:
print("找到窗口")
left top right bottom=win32gui.GetWindowrect(hwnd)
#win32gui.SetForegroundWindow(hwnd)
print("窗口坐标:")
print(str(left) '' str(right) '' str(top) '' str(bottom))
else:
print("未找到窗口")
2.锁定并抓取雷区图像
#锁定雷区坐标
#去除周围功能按钮以及多余的界面
#具体的像素值是通过QQ的截图来判断的
left =15
top =101
right-=15
bottom-=42
#抓取雷区图像
rect=(left top right bottom)
img=ImageGrab.grab().crop(rect)
3.各图像的RGBA值
#数字1-8周围雷数
#0未被打开
#ed被打开空白
#hongqi红旗
#boom普通雷
#boom_red踩中的雷
rgba_ed=[(225 (192 192 192)) (31 (128 128 128))]
rgba_hongqi=[(54 (255 255 255)) (17 (255 0 0)) (109 (192 192 192)) (54 (128 128 128)) (22 (0 0 0))]
rgba_0=[(54 (255 255 255)) (148 (192 192 192)) (54 (128 128 128))]
rgba_1=[(185 (192 192 192)) (31 (128 128 128)) (40 (0 0 255))]
rgba_2=[(160 (192 192 192)) (31 (128 128 128)) (65 (0 128 0))]
rgba_3=[(62 (255 0 0)) (163 (192 192 192)) (31 (128 128 128))]
rgba_4=[(169 (192 192 192)) (31 (128 128 128)) (56 (0 0 128))]
rgba_5=[(70 (128 0 0)) (155 (192 192 192)) (31 (128 128 128))]
rgba_6=[(153 (192 192 192)) (31 (128 128 128)) (72 (0 128 128))]
rgba_8=[(149 (192 192 192)) (107 (128 128 128))]
rgba_boom=[(4 (255 255 255)) (144 (192 192 192)) (31 (128 128 128)) (77 (0 0 0))]
rgba_boom_red=[(4 (255 255 255)) (144 (255 0 0)) (31 (128 128 128)) (77 (0 0 0))]
(左右滑动可查看完整代码)
4.扫描雷区图像保存至一个二维数组map
#扫描雷区图像
defshowmap():
img=ImageGrab.grab().crop(rect)
foryinrange(blocks_y):
forxinrange(blocks_x):
this_image=img.crop((x*block_width y*block_height (x 1)*block_width (y 1)*block_height))
ifthis_image.getcolors()==rgba_0:
map[y][x]=0
elifthis_image.getcolors()==rgba_1:
map[y][x]=1
elifthis_image.getcolors()==rgba_2:
map[y][x]=2
elifthis_image.getcolors()==rgba_3:
map[y][x]=3
elifthis_image.getcolors()==rgba_4:
map[y][x]=4
elifthis_image.getcolors()==rgba_5:
map[y][x]=5
elifthis_image.getcolors()==rgba_6:
map[y][x]=6
elifthis_image.getcolors()==rgba_8:
map[y][x]=8
elifthis_image.getcolors()==rgba_ed:
map[y][x]=-1
elifthis_image.getcolors()==rgba_hongqi:
map[y][x]=-4
elifthis_image.getcolors()==rgba_boomorthis_image.getcolors()==rgba_boom_red:
globalgameover
gameover=1
break
#sys.exit(0)
else:
print("无法识别图像")
print("坐标")
print((y x))
print("颜色")
print(this_image.getcolors())
sys.exit(0)
#print(map)
(左右滑动可查看完整代码)
5.扫雷算法
这里我采用的最基础的算法
1.首先点出一个点
2.扫描所有数字,如果周围空白 插旗==数字,则空白均有雷,右键点击空白插旗
3.扫描所有数字,如果周围插旗==数字,则空白均没有雷,左键点击空白
4.循环2、3,如果没有符合条件的,则随机点击一个白块
#插旗
defbanner():
showmap()
foryinrange(blocks_y):
forxinrange(blocks_x):
if1<=map[y][x]andmap[y][x]<=5:
boom_number=map[y][x]
block_white=0
block_qi=0
foryyinrange(y-1 y 2):
forxxinrange(x-1 x 2):
if0<=yyand0<=xxandyy<blocks_yandxx<blocks_x:
ifnot(yy==yandxx==x):ifmap[yy][xx]==0:
block_white =1
elifmap[yy][xx]==-4:
block_qi =1ifboom_number==block_white block_qi:foryyinrange(y-1 y 2):
forxxinrange(x-1 x 2):
if0<=yyand0<=xxandyy<blocks_yandxx<blocks_x:
ifnot(yy==yandxx==x):
ifmap[yy][xx]==0:
win32api.SetCursorPos([left xx*block_width top yy*block_height])
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN 0 0 0 0)
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP 0 0 0 0)
showmap()
#点击白块
defdig():
showmap()
iscluck=0
foryinrange(blocks_y):
forxinrange(blocks_x):
if1<=map[y][x]andmap[y][x]<=5:
boom_number=map[y][x]
block_white=0
block_qi=0
foryyinrange(y-1 y 2):
forxxinrange(x-1 x 2):
if0<=yyand0<=xxandyy<blocks_yandxx<blocks_x:
ifnot(yy==yandxx==x):
ifmap[yy][xx]==0:
block_white =1
elifmap[yy][xx]==-4:
block_qi =1ifboom_number==block_qiandblock_white>0:foryyinrange(y-1 y 2):
forxxinrange(x-1 x 2):
if0<=yyand0<=xxandyy<blocks_yandxx<blocks_x:
ifnot(yy==yandxx==x):
ifmap[yy][xx]==0:
win32api.SetCursorPos([left xx*block_width top yy*block_height])
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN 0 0 0 0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP 0 0 0 0)
iscluck=1
ifiscluck==0:
luck()
#随机点击
defluck():
fl=1
while(fl):
random_x=random.randint(0 blocks_x-1)
random_y=random.randint(0 blocks_y-1)
if(map[random_y][random_x]==0):
win32api.SetCursorPos([left random_x*block_width top random_y*block_height])
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN 0 0 0 0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP 0 0 0 0)
fl=0
defgogo():
win32api.SetCursorPos([left top])
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN 0 0 0 0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP 0 0 0 0)
showmap()
globalgameover
while(1):
if(gameover==0):
banner()
banner()
dig()
else:
gameover=0
win32api.keybd_event(113 0 0 0)
win32api.SetCursorPos([left top])
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN 0 0 0 0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP 0 0 0 0)
showmap()