找回密码
 立即注册
查看: 20120|回复: 73

利用Python实现自动扫雷小脚本!就没有我过不了的扫雷游戏 ...

    [复制链接]
  • TA的每日心情

    2024-8-31 02:02
  • 签到天数: 487 天

    连续签到: 1 天

    [LV.9]妙领天机

    481

    主题

    3030

    回帖

    4593

    积分

    如雷贯耳

    积分
    4593
    发表于 2020-1-6 12:08:31 | 显示全部楼层 |阅读模式

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×
    自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。
    代码已上传至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/ CzE4EA0L0NwLHz3s.jpg

    2.python 3

    我的版本是 python 3.6.1
    3.python的第三方库

    win32api,win32gui,win32con,Pillow,numpy,opencv
    可通过 pip install --upgrade SomePackage 来进行安装
    注意:有的版本是下载pywin32,但是有的要把pywin32升级到最高并自动下载了pypiwin32,具体情况每个python版本可能都略有不同
    我给出我的第三方库和版本仅供参考
    y2KBuGPwH9m1puuO.jpg

    二、关键代码组成

    1.找到游戏窗口与坐标



    #扫雷游戏窗口class_name="TMain"title_name="MinesweeperArbiter"hwnd=win32gui.FindWindow(class_name,title_name)#窗口坐标left=0top=0right=0bottom=0ifhwnd: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+=15top+=101right-=15bottom-=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]=0elifthis_image.getcolors()==rgba_1:map[y][x]=1elifthis_image.getcolors()==rgba_2:map[y][x]=2elifthis_image.getcolors()==rgba_3:map[y][x]=3elifthis_image.getcolors()==rgba_4:map[y][x]=4elifthis_image.getcolors()==rgba_5:map[y][x]=5elifthis_image.getcolors()==rgba_6:map[y][x]=6elifthis_image.getcolors()==rgba_8:map[y][x]=8elifthis_image.getcolors()==rgba_ed:map[y][x]=-1elifthis_image.getcolors()==rgba_hongqi:map[y][x]=-4elifthis_image.getcolors()==rgba_boomorthis_image.getcolors()==rgba_boom_red:globalgameovergameover=1break#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=0block_qi=0foryyinrange(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+=1elifmap[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=0foryinrange(blocks_y):forxinrange(blocks_x):if1<=map[y][x]andmap[y][x]<=5:boom_number=map[y][x]block_white=0block_qi=0foryyinrange(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+=1elifmap[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=1ifiscluck==0:luck()#随机点击defluck():fl=1while(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=0defgogo():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()globalgameoverwhile(1):if(gameover==0):banner()banner()dig()else:gameover=0win32api.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()私信小编01 领取完整项目代码!
    楼主热帖
  • TA的每日心情
    开心
    2019-8-30 16:31
  • 签到天数: 456 天

    连续签到: 2 天

    [LV.9]妙领天机

    9

    主题

    3013

    回帖

    3030

    积分

    声名显赫

    积分
    3030
    发表于 2020-1-6 12:16:29 | 显示全部楼层
    好,很好,非常好!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2019-8-30 11:06
  • 签到天数: 472 天

    连续签到: 1 天

    [LV.9]妙领天机

    2

    主题

    3070

    回帖

    3072

    积分

    声名显赫

    积分
    3072
    发表于 2020-1-21 16:44:56 | 显示全部楼层
    不错 支持一个了
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 10:13
  • 签到天数: 473 天

    连续签到: 1 天

    [LV.9]妙领天机

    2

    主题

    3019

    回帖

    3019

    积分

    声名显赫

    积分
    3019
    发表于 2020-1-28 10:18:51 | 显示全部楼层
    支持,楼下的跟上哈~
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2019-8-30 15:29
  • 签到天数: 486 天

    连续签到: 1 天

    [LV.9]妙领天机

    1

    主题

    3111

    回帖

    3109

    积分

    声名显赫

    积分
    3109
    发表于 2020-1-29 07:51:02 | 显示全部楼层
    路过 帮顶 嘿嘿
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-30 16:06
  • 签到天数: 468 天

    连续签到: 9 天

    [LV.9]妙领天机

    11

    主题

    3118

    回帖

    3139

    积分

    声名显赫

    积分
    3139
    发表于 2020-2-3 00:55:24 | 显示全部楼层
    我也来顶一下..
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-8-30 02:28
  • 签到天数: 475 天

    连续签到: 2 天

    [LV.9]妙领天机

    8

    主题

    3098

    回帖

    3113

    积分

    声名显赫

    积分
    3113
    发表于 2020-2-4 15:05:19 | 显示全部楼层
    支持楼主,用户楼主,楼主英明呀!!!
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2019-8-30 13:50
  • 签到天数: 463 天

    连续签到: 1 天

    [LV.9]妙领天机

    2

    主题

    3081

    回帖

    3081

    积分

    声名显赫

    积分
    3081
    发表于 2020-2-15 02:10:43 | 显示全部楼层
    非常好,顶一下
    回复

    使用道具 举报

  • TA的每日心情

    2019-8-29 12:52
  • 签到天数: 471 天

    连续签到: 5 天

    [LV.9]妙领天机

    12

    主题

    3101

    回帖

    3120

    积分

    声名显赫

    积分
    3120
    发表于 2020-2-16 04:08:59 | 显示全部楼层
    无论是不是沙发都得回复下
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2019-8-30 15:02
  • 签到天数: 469 天

    连续签到: 3 天

    [LV.9]妙领天机

    5

    主题

    3086

    回帖

    3094

    积分

    声名显赫

    积分
    3094
    发表于 2020-2-23 03:32:32 | 显示全部楼层
    支持,楼下的跟上哈~
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|任逍遥

    GMT+8, 2024-11-21 18:59 , Processed in 0.089902 second(s), 52 queries .

    Powered by 任逍遥 X3.5

    Copyright © 2001-2024, Rxiaoyao Cloud.

    快速回复 返回顶部 返回列表