Python学习——利用Python实现自动扫雷小脚本
小职 2020-12-17 来源 :马哥Linux运维 阅读 590 评论 0

摘要:本篇主要介绍了通过分析图片获得数据,并通过模拟鼠标操作,进行自动扫雷,希望对Python的学习有所帮助。

本篇主要介绍了通过分析图片获得数据,并通过模拟鼠标操作,进行自动扫雷,希望对Python的学习有所帮助。

Python学习——利用Python实现自动扫雷小脚本

自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。

 

一、准备工作

 

1.扫雷游戏

 

我是win10,没有默认的扫雷,所以去扫雷网下载

 

//www.saolei.net/BBS/

 Python学习——利用Python实现自动扫雷小脚本

 

 

2.python 3

 

我的版本是 python 3.6.1

 

3.python的第三方库

 

win32api,win32gui,win32con,Pillow,numpy,opencv

 

可通过 pip install --upgrade SomePackage 来进行安装

 

注意:有的版本是下载pywin32,但是有的要把pywin32升级到最高并自动下载了pypiwin32,具体情况每个python版本可能都略有不同

 

我给出我的第三方库和版本仅供参考

 

 Python学习——利用Python实现自动扫雷小脚本

 

二、关键代码组成

 

1.找到游戏窗口与坐标

 

#扫雷游戏窗口  

class_name = "TMain"  

title_name = "Minesweeper Arbiter "  

hwnd = win32gui.FindWindow(class_name, title_name)  

#窗口坐标  

left = 0  

top = 0  

right = 0  

bottom = 0  

if hwnd:  

    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

 

#扫描雷区图像  

def showmap():  

    img = ImageGrab.grab().crop(rect)  

    for y in range(blocks_y):  

        for x in range(blocks_x):  

            this_image = img.crop((x * block_width, y * block_height, (x + 1) * block_width, (y + 1) * block_height))  

            if this_image.getcolors() == rgba_0:  

                map[y][x] = 0  

            elif this_image.getcolors() == rgba_1:  

                map[y][x] = 1  

            elif this_image.getcolors() == rgba_2:  

                map[y][x] = 2  

            elif this_image.getcolors() == rgba_3:  

                map[y][x] = 3  

            elif this_image.getcolors() == rgba_4:  

                map[y][x] = 4  

            elif this_image.getcolors() == rgba_5:  

                map[y][x] = 5  

            elif this_image.getcolors() == rgba_6:  

                map[y][x] = 6  

            elif this_image.getcolors() == rgba_8:  

                map[y][x] = 8  

            elif this_image.getcolors() == rgba_ed:  

                map[y][x] = -1  

            elif this_image.getcolors() == rgba_hongqi:  

                map[y][x] = -4  

            elif this_image.getcolors() == rgba_boom or this_image.getcolors() == rgba_boom_red:  

                global gameover  

                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,如果没有符合条件的,则随机点击一个白块

 

#插旗  

def banner():  

    showmap()  

    for y in range(blocks_y):  

        for x in range(blocks_x):  

            if 1 <= map[y][x] and map[y][x] <= 5:  

                boom_number = map[y][x]  

                block_white = 0  

                block_qi = 0  

                for yy in range(y-1,y+2):  

                    for xx in range(x-1,x+2):  

                        if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:  

                            if not (yy == y and xx == x):if map[yy][xx] == 0:  

                                    block_white += 1  

                                elif map[yy][xx] == -4:  

                                    block_qi += 1if boom_number == block_white + block_qi:for yy in range(y - 1, y + 2):  

                        for xx in range(x - 1, x + 2):  

                            if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:  

                                if not (yy == y and xx == x):  

                                    if map[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()   

#点击白块  

def dig():  

    showmap()  

    iscluck = 0  

    for y in range(blocks_y):  

        for x in range(blocks_x):  

            if 1 <= map[y][x] and map[y][x] <= 5:  

                boom_number = map[y][x]  

                block_white = 0  

                block_qi = 0  

                for yy in range(y - 1, y + 2):

                    for xx in range(x - 1, x + 2):  

                        if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:  

                            if not (yy == y and xx == x):  

                                if map[yy][xx] == 0:  

                                    block_white += 1  

                                elif map[yy][xx] == -4:  

                                    block_qi += 1if boom_number == block_qi and block_white > 0:for yy in range(y - 1, y + 2):  

                        for xx in range(x - 1, x + 2):  

                            if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:  

                                if not(yy == y and xx == x):  

                                    if map[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  

    if iscluck == 0:  

        luck()  

#随机点击  

def luck():  

    fl = 1  

    while(fl):  

        randomrandom_x = random.randint(0, blocks_x - 1)  

        randomrandom_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  

def gogo():  

    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()  

    global gameover  

    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()  


本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程