如何基于Python实现自动扫雷
这篇文章主要介绍了如何基于Python实现自动扫雷,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。
一、准备工作
我的版本是python3.6.1
python的第三方库:
- win32api
- win32gui
- win32con
- Pillow
- numpy
- opencv
可通过pipinstall--upgradeSomePackage来进行安装
注意:有的版本是下载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<=xxandyy0:foryyinrange(y-1,y+2): forxxinrange(x-1,x+2): if0<=yyand0<=xxandyy 这个算法在初级和中级通过率都不错,但是在高级成功率惨不忍睹,主要是没有考虑逻辑组合以及白块是雷的概率问题,可以对这两个点进行改进,提高成功率。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。