Python 脚本基础模块

Python 脚本基础模块

@firestaradmin 2020年12月15日15:14:34

如果死亡会带来平静,和安息。死去吧。

一、键盘鼠标操作模拟

autopy 模块

安装:pip3 install autopy

主要用来模拟鼠标和键盘的点击操作。

1. 键盘

这个模块包含控制键盘的函数.

函数

按下键或者释放键

autopy.key.toggle(autopy.key.Code.UP_ARROW, True, [])  #按下方向键
autopy.key.toggle(autopy.key.Code.UP_ARROW, False, [])  #释放方向键

autopy.key.toggle(autopy.key.Code.UP_ARROW, True, [autopy.key.Modifier.CONTROL], 0)

#参数1 键盘代码(看下表)或键名

#参数2 True表示按下,False松开

#参数3 同时按下的修饰键

#参数4 延迟n秒后再往下执行

#注意释放,要不然会电脑会一直按着那个键,直到你终止程序


autopy.key.tap(autopy.key.Code.CONTROL, [], 2)

#对autopy.key.toggle进行的封装,方便使用,按下并自动释放.


autopy.key.type_string(‘Hello123’, 0)

#输入相应的字符串

#参数2 每分钟的字符个数,0表示最快

常量

class autopy.key.Code

type code
Code F1
Code F2
Code F3
Code F4
Code F5
Code F6
Code F7
Code F8
Code F9
Code F10
Code F11
Code F12
Code ALT
Code BACKSPACE
Code CAPS_LOCK
Code CONTROL
Code DELETE
Code DOWN_ARROW
Code END
Code ESCAPE
Code HOME
Code LEFT_ARROW
Code PAGE_DOWN
Code PAGE_UP
Code RETURN
Code RIGHT_ARROW
Code SHIFT
Code SHIFT
Code SPACE
Code UP_ARROW

class autopy.key.Modifier

type code
Modifier META
Modifier ALT
Modifier CONTROL
Modifier SHIFT

2. 鼠标

有些窗口可能需要管理员运行,才能移动鼠标!!!

这个模块包含获取发鼠标状态和控制鼠标光标的函数.非特殊情况下,都使用屏幕坐标系,原点在左上角.

函数

#移动鼠标到指定点–相对于屏幕,没有移动过程

autopy.mouse.move(100, 100)

#移动鼠标到指定点–相对于屏幕,有直线移动过程

autopy.mouse.smooth_move(500, 500)

#返回鼠标的当前位置–相对于屏幕

i = autopy.mouse.location()
#i => (500.0, 500.0)

#按下指定鼠标键

autopy.mouse.toggle(autopy.mouse.Button.LEFT, True)

#autopy.mouse.Button.LEFT   鼠标左键
#autopy.mouse.Button.RIGHT  鼠标右键
#autopy.mouse.Button.MIDDLE  鼠标中键
#None   默认左键

#释放指定鼠标键

autopy.mouse.toggle(autopy.mouse.Button.LEFT, False)  
#注意释放,要不然会电脑会一直按着那个键,直到你终止程序

autopy.mouse.click(None)   # 点左键一下,然后松开
autopy.mouse.click(autopy.mouse.Button.RIGHT)  # 点右键一下,然后松开
autopy.mouse.click(autopy.mouse.Button.LEFT, 3)   # 按住左键保持3秒,然后松开

autopy.mouse.Button:Code

type code
Button LEFT
Button RIGHT
Button MIDDLE

3.控制屏幕的模块screen

这个模块包含控制屏幕的函数

函数
  1. autopy.screen,scale()->float
    获得屏幕的scale值,多少像素代表一个点.
  2. autopy.screen.size()->(float,float)
    返回tuple(width,height),代表屏幕宽高有多少个像素点.
  3. autopy.screen.is_point_visible(x:float,y:float)->bool
    如果这个点在屏幕的范围内,返回True
  4. autopy.screen.get_color(x:float,y:float)->(int,int,int)
    返回屏幕上对应点的颜色值.异常:如果点不在屏幕上,抛出ValueError.

autopy 也有图像识别,但是是位图识别,它的处理图像不适合脚本编写,我们会使用其他的模块,更加适合。

二、屏幕截图

Pillow

Pillow是PIL的一个派生分支,但如今已经发展成为比PIL本身更具活力的图像处理库。pillow可以说已经取代了PIL,将其封装成python的库(pip即可安装),且支持python2和python3,目前最新版本是3.0.0。

安装:

pip3 install pillow

屏幕截图:

from PIL import ImageGrab 
im = ImageGrab.grab((0,0,800,200)) 	#截取屏幕指定区域的图像 
im = ImageGrab.grab() 				#不带参数表示全屏幕截图
im.save("D:\\test.jpg");			#储存为.jpg

其他图像处理功能,如缩放、颜色等操作,百度。

三、窗口控制

pywin32

一般系统自带,如果没有,安装可能是pip install pywin32


使用 win32gui win32api win32con 等模块进行窗体控制。

import win32gui, win32api, win32con
def main():
    global game_hwnd, window_size
    game_hwnd = win32gui.FindWindow(game_class, game_title)  #获得句柄 <hwnd: int>
    print("窗口句柄:",game_hwnd)
    win32gui.SetForegroundWindow(game_hwnd)              #窗口浮现
    window_size = win32gui.GetWindowRect(game_hwnd)      #pos: (x1, y1, x2, y2) <pos: tuple>

1、获取窗口句柄

win32gui.FindWindow(game_class, game_title)  #获得句柄 <hwnd: int>

关键在于 窗口类名窗口标题 ** 的获取, 可以使用spy**++ 软件 来抓取窗口信息。

2、窗口移到最前

win32gui.SetForegroundWindow(game_hwnd)     #窗口浮现

把窗口移到前方,但窗口最小化后会有错误,待解决。

3、获取窗口坐标位置

window_size = win32gui.GetWindowRect(game_hwnd)      #pos: (x1, y1, x2, y2) <pos: tuple>

获取窗口的位置,可以通过点坐标计算窗口大小,获取的位置数据类型为 元组 (X1, Y1, X2, Y2) 对应窗体左上角和右下角的坐标。

4、更好的获取句柄的方式

因为有时候应用程序会更新,标题可能会更改,所以可以通过 窗口的标题进行关键字匹配,从而找到窗体句柄。

四、图像识别

CV2 [ opencv-python ]

安装:

pip3 install opencv-python

会自动安装依赖的 numpy 模块。

可能的import 错误:

>>>import cv2 
ImportError: numpy.core.multiarray failed to import

原因是因为 numpy 模块的版本太新,将版本降低即可。

pip3 install -U numpy==1.14.5

具体版本和 opencv 的 版本有关。可以直接降低到 1.12.0。 如果版本太低,会有提示:

opencv-python 4.4.0.46 has requirement numpy>=1.14.5, but you'll have numpy 1.12.0 which is incompatible.

基本库函数

1、读入一张图像

cv2.imread(filepath, flags) #读入一张图像

  • filepath:要读入图片的完整路径
  • flags:读入图片的模式
    • cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道
    • cv2.IMREAD_GRAYSCALE:读入灰度图片
    • cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道
2、显示图像

cv2.imshow(wname,img) #显示图像

  • 第一个参数是显示图像的窗口的名字
  • 第二个参数是要显示的图像(imread读入的图像),窗口大小自动调整为图片大小
cv2.imshow('image',img)
cv2.waitKey(0)   #等待键盘输入,单位为毫秒,即等待指定的毫秒数看是否有键盘输入,若在等待时间内按下任意键则返回按键的ASCII码,程序继续运行。
#若没有按下任何键,超时后返回-1。参数为0表示无限等待。不调用waitKey的话,窗口会一闪而逝,看不到显示的图片。
cv2.destroyAllWindow()     #销毁所有窗口
cv2.destroyWindow(wname)   #销毁指定窗口
3、保存图像

cv2.imwrite(file,img,num) #保存一张图像

  • 第一个参数是要保存的文件名
  • 第二个参数是要保存的图像。可选的第三个参数,它针对特定的格式:对于JPEG,其表示的是图像的质量,用0 - 100的整数表示,默认95。
  • 第三个参数表示的是压缩级别。默认为3.
4、其他部分函数
img.copy()  #图像复制

cv2.resize(image, image2,dsize)   #图像缩放:(输入原始图像,输出新图像,图像的大小)

cv2.flip(img,flipcode)            #图像翻转,flipcode控制翻转效果。
#flipcode = 0:沿x轴翻转;flipcode > 0:沿y轴翻转;flipcode < 0:x,y轴同时翻转

实现屏幕上找到特定图像

cv2.matchTemplate(image, templ, method, result=None, mask=None)

image:待搜索图像
templ:模板图像
result:匹配结果
method:匹配模式参数

method:

  • CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
  • CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
  • CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
  • CV_TM_SQDIFF_NORMED 归一化平方差匹配法
  • CV_TM_CCORR_NORMED 归一化相关匹配法
  • CV_TM_CCOEFF_NORMED 归一化相关系数匹配法

模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。

一般,寻找的目标和容器,尺寸必须相同

实例代码

import cv2
'''
* @brief 在容器图片里寻找样例. 使用OPONCV TM_CCOEFF_NORMED 模式识别
* @param template the target will find in container ex. "D:\\a.jpg"
* @param container the pic where to find ex. "D:\\b.jpg"
* @param thres the threshold of finding simlike, default 0.8, range(0, 1)
* @retval 0 means not found, > 0 means level of similarity range(0 ,1)
'''
def match_sim_img(template, container, thres = 0.80):
    template = cv2.imread(template,0)
    container = cv2.imread(container,0)
    res = cv2.matchTemplate(container, template, cv2.TM_CCOEFF_NORMED)
    if res.max() >= thres:
        return res.max()
    return 0

返回值 res 为列表变量,所以取res.max() 判断是否大于阈值,大于就说明可能找到了该图。


但我们的目的大部分的在屏幕上查找坐标,然后进行鼠标点击操作。那么如何获得图片相对于屏幕的坐标呢?

import numpy
from PIL import Image
import cv2

'''
* @brief 在容器图片里寻找样例并返回坐标值. 使用OPONCV TM_CCOEFF_NORMED 模式识别
* @param template_path the target will find in container ex. "D:\\a.jpg"
* @param container_path the pic where to find ex. "D:\\b.jpg"
* @param thres the threshold of finding simlike, default 0.8, range(0, 1)
* @retval tuple[X, Y], if return (0, 0) means not found.
'''
def get_img_pos(template_path, container_path, thres = 0.80):
    template = cv2.imread(template_path,0)
    container = cv2.imread(container_path,0)
    res = cv2.matchTemplate(container, template, cv2.TM_CCOEFF_NORMED)
    
    if res.max() < thres:
        return (0, 0)

    container_size = Image.open(template_path).size
    
    loc = numpy.where(res==res.max())
    X = int(loc[1]+container_size[0]/2)
    Y = int(loc[0]+container_size[1]/2)
    return (X,Y)

五、配置文件

configparser

python使用自带的configparser模块用来读取配置文件,配置文件的形式类似windows中的ini文件,在使用前需要先安装该模块,使用pip安装即可

pip install configparser

实例:

可以新建一个.ini文件 输入以下内容进行测试:

[user-info]
name = ZhangSan
passwd = 123456
level = 12

[email]
address = 123455678@qq.com
passwd = 123123

python code:

import configparser 

def main():
    cf = configparser.ConfigParser()
    cf.read("C://temp/config.ini")  # 读取配置文件,如果写文件的绝对路径,就可以不用os模块

    secs = cf.sections()    # 获取文件中所有的section, 一个配置文件中可以有多个配置  
    print(secs)

    sec_userinfo = cf.options("user-info")  # 获取sec名为user-info 所有的键
    print(sec_userinfo)

    items_userinfo = cf.items("user-info")  # 获取sec名为user-info 所有的键值对
    print(items_userinfo)

    username = cf.get("user-info", "name")  # 获取[user-info]name 对应的值
    print(username)
    
    level = cf.getint("user-info", "level")
    print(level + 2)

if __name__ == "__main__":
    main()

执行结果如下:

>>>
['user-info', 'email']
['name', 'passwd']
[('name', 'ZhangSan'), ('passwd', '123456')]
ZhangSan
14

实例2

import configparser

'''
config.ini 内容:

[game-info]
title = NBA2KOL2 0.3.230.675
classname = "NBAWindowClass"

[debug-config]
debug_enable = False
'''
def main():
    cf = configparser.ConfigParser()
  	cf.read("F:\MarsCloud\MyFortune\Program\mycode\python\code\gameAssistant_2kol2\config.ini")  
    
    title = cf.get("game-info", "title")
    print(title)

    classname = cf.get("game-info", "classname")
    print(name)

    val_bool = cf.getboolean("debug-config", "debug_enable")
    print(val_bool)

结果:

>>>
NBA2KOL2 0.3.230.675
"NBAWindowClass"
False

六、其他知识

1、判断是否以管理员模式运行

使用 pywin32 模块

代码如下:

from win32com.shell import shell

def main():
    if shell.IsUserAnAdmin():
        print("now is admin mode.")
    else:
        print("just a poor man.")

2、获取程序当前绝对路径

使用 os 模块

import os

print(os.getcwd())

七、NBA2kOL2 挂机实例

'''
 @brief This is for NBA2KOL2 game.
 @author firestaradmin 2020年12月16日
'''
import time
import numpy 
from PIL import Image,ImageGrab
from cv2 import cv2
import autopy
import win32gui
from win32com.shell import shell
import os
import configparser


# Configuartion
debug_enable = True # config if print debug

# 'GLOBAL VARIABLE'
game_title = "NBA2KOL2 0.3.230.675"
game_class = "NBAWindowClass"
game_hwnd = 0
window_size = (0,0,0,0)

game_completed_cnt = 0
game_win_cnt = 0
game_fail_cnt = 0

game_one_game_timeS = 0

cwd_path = ""

'''
* @brief 在容器图片里寻找样例并返回坐标值. 使用OPONCV TM_CCOEFF_NORMED 模式识别
* @param template   the path of target will find in container. ex- "D:\\a.jpg"
* @param container  the path of pic where to find. ex- "D:\\b.jpg"
* @param img_mode   the img open mode. 
    - cv2.IMREAD_COLOR:    默认参数,读入一副彩色图片,忽略alpha通道
    - cv2.IMREAD_GRAYSCALE:读入灰度图片
    - cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道
* @param thres      the threshold of finding simlike level. default 0.7, range(0, 1)
* @retval (X, Y), find_falg, matching_value
    (X, Y): The relative center coordinate of matched template.
    find_flag: if have found return True 
    matching_value: return finding max value

'''
def get_img_pos(template_path, container_path, img_mode = cv2.IMREAD_GRAYSCALE, thres = 0.7):
    template = cv2.imread(template_path, img_mode)
    container = cv2.imread(container_path, img_mode)

    res = cv2.matchTemplate(container, template, cv2.TM_CCOEFF_NORMED)
    
    if res.max() < thres:
        return (0, 0), False, res.max()

    container_size = Image.open(template_path).size
    
    loc = numpy.where(res==res.max())
    X = int(loc[1]+container_size[0]/2)
    Y = int(loc[0]+container_size[1]/2)
    return (X,Y), True, res.max()
    


# @brief capture window and save it.
def grab_window():
    global game_hwnd, window_size, cwd_path
    win32gui.SetForegroundWindow(game_hwnd) #窗口浮现
    mydelay(0.3)
    im = ImageGrab.grab(window_size) 	    #截取屏幕指定区域的图像 
    im.save(cwd_path + "/resource/window.jpg");			#储存为.jpg
    mydelay(0.2)



# @brief find a template and click it.
def finding_in_window_and_click_it(template_path, click_delay = 0.5, img_mode = cv2.IMREAD_GRAYSCALE, thres = 0.7):
    global cwd_path
    grab_window()   #截取窗口

    err_code = 0
    relative_pos, flag, value = get_img_pos(template_path, cwd_path + "/resource/window.jpg", img_mode, thres)
    mydebug("匹配度:"+ str(value)+ "of"+ template_path)
    if(not flag):
        err_code = 1    #have not found template.
        return
    abs_pos = (relative_pos[0] + window_size[0], relative_pos[1] + window_size[1])
    autopy.mouse.move(abs_pos[0], abs_pos[1])
    mydelay(0.5)
    autopy.mouse.click(autopy.mouse.Button.LEFT, click_delay)

    return err_code




# @brief detect a page, until timeOut.
def detect_page_apper(detect_img_path, timeOut_S, detect_period_S = 5, img_mode = cv2.IMREAD_GRAYSCALE, thres = 0.7):
    print("开始侦测 ", detect_img_path, "=============================")
    global cwd_path
    timeOut = timeOut_S
    while(timeOut > 0):
        grab_window()   #截取窗口
        pos, flag, value = get_img_pos(detect_img_path, cwd_path + "/resource/window.jpg", img_mode, thres)
        
        mydebug(detect_img_path + " 匹配度= "+ str(value))  #for debug

        if(flag):
            return True
        mydelay(detect_period_S - 0.5)   #why need sub 0.5s, because grab_window() will delay 0.5s.
        timeOut -= detect_period_S
        mydebug("Time_elapsed: "+ str(timeOut_S - timeOut)+ "S")
    return False       
    
# only used in detect game over.
def detect_game_over(timeOut_S, detect_period_S = 5, img_mode = cv2.IMREAD_GRAYSCALE, thres = 0.7):
    global game_win_cnt, game_fail_cnt, cwd_path
    print("开始侦测, 等待比赛结束 =============================")
    timeOut = timeOut_S
    while(timeOut > 0):
        grab_window()   #截取窗口

        pos, flag, value = get_img_pos(cwd_path + "/resource/fail_label.jpg", cwd_path + "/resource/window.jpg", img_mode, thres)
        mydebug("失败标志匹配度= "+ str(value))  #for debug
        if(flag):
            game_fail_cnt += 1
            return True

        pos, flag, value = get_img_pos(cwd_path + "/resource/win_label.jpg", cwd_path + "/resource/window.jpg", img_mode, thres)
        mydebug("胜利标志匹配度= "+ str(value))  #for debug
        if(flag):
            game_win_cnt += 1
            return True

        mydelay(detect_period_S - 0.5)   #why need sub 0.5s, because grab_window() will delay 0.5s.
        timeOut -= detect_period_S
        mydebug("Time_elapsed: " + str(timeOut_S - timeOut) + "S")
    return False     


def mydebug(str):
    global debug_enable
    if(debug_enable):
        print("[debug] ", str)
    
def mydelay(timeS):
    global game_one_game_timeS
    time.sleep(timeS)
    game_one_game_timeS += timeS

def if_admin_runing():
    if shell.IsUserAnAdmin():
        return True
    else:
        return False

def myinit():
    print("======== 使用前注意把游戏调至窗口模式 分辨率 1440x900 !! =====I,me,justice AG====")
    print("======== 使用前注意把游戏调至窗口模式 分辨率 1440x900 !! =====  is the most  ====")
    print("======== 注意游戏版本号,因为标题会随着版本号改变        ===most cool perfect====")
    print("======== 标题改变要修改 根目录下的 config.ini 文件 配置 =====cool superman!======")
    print(" ")
    print(" ")
    time.sleep(0.5)
    print("初始化中......")
    time.sleep(0.5)
    # 初始化变量
    global game_hwnd, window_size, debug_enable, cwd_path
    cwd_path = os.getcwd().replace('\\', '/')
    cwd_temp = cwd_path+"/config.ini"
    # 读取Config文件
    cf = configparser.ConfigParser()
    cf.read(cwd_temp)

    game_title = cf.get("game-info", "title")
    game_class = cf.get("game-info", "classname")
    debug_enable = cf.getboolean("debug-config", "debug_print_enable")

    # 获取窗口句柄
    game_hwnd = win32gui.FindWindow(game_class, game_title)  #获得句柄
    if(game_hwnd == 0):
        print("未检测到游戏窗口,有以下几种原因可能:")
        print("1.游戏未运行。。真的呆哦")
        print("2.游戏更新了,版本号有变动,请到脚本根目录下的config.ini文件进行修改标题名称")
        print("3.可能你不配吧,嘻嘻")
        print("请打开游戏正确配置后再运行脚本,谢谢合作。")
        os.system('pause')
        exit()
    time.sleep(0.5)
    print("游戏窗口句柄为:",game_hwnd)
    time.sleep(0.5)
    win32gui.SetForegroundWindow(game_hwnd)              #窗口浮现
    window_size = win32gui.GetWindowRect(game_hwnd)      #pos: x1, y1, x2, y2


def myexit():
    print("== 异常错误!请重新运行脚本 ==")
    global game_completed_cnt, game_win_cnt, game_fail_cnt
    print("已完成", game_completed_cnt, " 场比赛。")
    print("胜利", game_win_cnt, " 场比赛。")
    print("失败", game_fail_cnt, " 场比赛。")
    print("===============================")
    os.system("pause")
    exit()

# =================================== main ======================================
def main():

    # 检查是否以管理员模式运行
    if(not if_admin_runing()):
        print("请以管理员模式 重新运行本脚本!")
        os.system('pause')
        exit()

    # 初始化
    global game_completed_cnt, game_win_cnt, game_fail_cnt, game_one_game_timeS
    myinit()
    

#开始循环进行比赛
    print("开始比赛循环")
    time.sleep(0.5)
    while (True):
        print("开始新一局比赛============")

        mydelay(1)
        err = finding_in_window_and_click_it(cwd_path + "/resource/main_page_start.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.58)
        if(err == 0):
            print("[开始比赛] 点击成功")
        else:   
            print("[开始比赛] 点击失败")
            myexit()

        mydelay(1)
        err = finding_in_window_and_click_it(cwd_path + "/resource/start_page_paiwei.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.6)
        if(err == 0):
            print("[排位] 点击成功")
        else:   
            print("[排位] 点击失败")
            myexit()

        mydelay(1)
        err = finding_in_window_and_click_it(cwd_path + "/resource/start_paiwei_page_jingli.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.6)
        if(err == 0):
            print("[经理模式] 点击成功")
        else:   
            print("[经理模式] 点击失败")
            myexit()

        mydelay(1)
        err = finding_in_window_and_click_it(cwd_path + "/resource/start_paiwei_jingli_page_enter.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.6)
        if(err == 0):
            print("[进入] 点击成功")
        else:   
            print("[进入] 点击失败")
            myexit()


    #********等待匹配, 准备*********
        ret = detect_page_apper(cwd_path + "/resource/zhunbei_page_judge.jpg", 60*10, 3, cv2.IMREAD_GRAYSCALE, 0.7)
        if(not ret):
            print("准备阶段错误!")
            myexit()
        mydelay(2)
        err = finding_in_window_and_click_it(cwd_path + "/resource/zhunbei_page_ready.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.6)
        if(err == 0):
            print("[准备] 点击成功")
        else:   
            print("[准备] 点击失败")
            myexit()



    #********等待比赛完毕, 结算*********
        # ret = detect_page_apper(cwd_path + "/resource/end_page_judge.jpg", 60*40, 5, cv2.IMREAD_GRAYSCALE, 0.58)
        ret = detect_game_over(60*40, 5, cv2.IMREAD_GRAYSCALE, 0.7)
        if(not ret):
            print("err:未匹配到比赛完毕界面!")
            myexit()
        mydelay(3)
        err = finding_in_window_and_click_it(cwd_path + "/resource/end_page_confirm.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.7)
        if(err == 0):
            print("[确定比赛结果] 点击成功")
        else:   
            print("[确定比赛结果] 点击失败")
            myexit()


        mydelay(3)
        err = finding_in_window_and_click_it(cwd_path + "/resource/end_jiesuan_page_next.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.7)
        if(err == 0):
            print("[下一页] 点击成功")
        else:   
            print("[下一页] 点击失败")
            myexit()

        mydelay(1)
        err = finding_in_window_and_click_it(cwd_path + "/resource/end_jiesuan2_page_next.jpg", 1, cv2.IMREAD_GRAYSCALE, 0.7)
        if(err == 0):
            print("[下一页] 点击成功")
        else:   
            print("[下一页] 点击失败")
            myexit()


    #********结算完毕, 开始下一局*********
        print("成功完成一局比赛! 花费", game_one_game_timeS, "秒")
        game_one_game_timeS = 0
        game_completed_cnt += 1
        print("已完成", game_completed_cnt, " 场比赛。")
        print("胜利", game_win_cnt, " 场比赛。")
        print("失败", game_fail_cnt, " 场比赛。")
        print("10秒后开始下一局比赛=============")
        print("===============================")
        mydelay(10)




if __name__ == "__main__":
    main()

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!