如何基于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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。