【python】python制作 连连看 游戏脚本(二)

沃驰
2023-12-01

【python】python制作 连连看 游戏脚本(一)_sunriver2000的博客-CSDN博客

【python】python制作 连连看 游戏脚本(二)_sunriver2000的博客-CSDN博客

【python】python制作 连连看 游戏脚本(三)_sunriver2000的博客-CSDN博客

【python】python制作 连连看 游戏脚本(四)_sunriver2000的博客-CSDN博客

代码下载:GitHub - sunriver2000/LinkGameAss

第四步、 image_type_list列表形成的同时,self.im2num_arr矩阵也识别完成。

矩阵如下图所示。

[[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0]
 [ 0  1  2  3  4  4  5  5  3  1  1  6  7  0]
 [ 0  2  8  9  3  5  1  4  2  8 10  8  5  0]
 [ 0 11  5  2  9 12 10  7  8  9 12  3 11  0]
 [ 0 11  6  6  4  7 11  6 10 11 12  1  3  0]
 [ 0 10  2 11 10  7 12 11  3  9 12 12 10  0]
 [ 0 12  8  7  2  6  8  1 10  7  6  5  8  0]
 [ 0  1  9  9  9  4  4  6  7 11  4  1 10  0]
 [ 0  5  3  5  6  4 12  7  2  9  8  2  3  0]
 [ 0  0  0  0  0  0  0  0  0  0  0  0  0  0]]

4、消除图标算法

4.1、直连的概念

直连的概念:同行或者同列,可以不相邻但中间没有其他非零元素。

    # 是否为同行或同列且可连
    def isDirectConnect(self, x1, y1, x2, y2):
        # 1、位置完全相同
        if x1 == x2 and y1 == y2:
            return False

        # 2、行列都不同的
        if x1 != x2 and y1 != y2:
            return False

        # 3、同行
        if x1 == x2 and self.isRowConnect(x1, y1, y2):
            return True

        # 4、同列
        if y1 == y2 and self.isColConnect(y1, x1, x2):
            return True

        return False

    # 判断同行是否可连
    def isRowConnect(self, x, y1, y2):
        minY = min(y1, y2)
        maxY = max(y1, y2)

        # 相邻直接可连
        if maxY - minY == 1:
            return True

        # 判断两个坐标之间是否全为0
        for y0 in range(minY + 1, maxY):
            if self.im2num_arr[x][y0] != 0:
                return False
        
        return True

    # 判断同列是否可连
    def isColConnect(self, y, x1, x2):
        minX = min(x1, x2)
        maxX = max(x1, x2)

        # 相邻直接可连
        if maxX - minX == 1:
            return True

        # 判断两个坐标之间是否全为0
        for x0 in range(minX + 1, maxX):
            if self.im2num_arr[x0][y] != 0:
                return False
 
        return True

4.2、获取辐射通道集合

获取核心矩阵(12*8矩阵)元素能够直连的值为零元素的集合。

# 获取同行或同列可连的坐标数组
    def getDirectConnectList(self, x, y):
        plist = []

        for px in range(0, 10):
            for py in range(0, 14):
                # 获取同行或同列且为0的坐标
                if self.im2num_arr[px][py] == 0 and self.isDirectConnect(x, y, px, py):
                    plist.append([px, py])
        
        return plist

4.3、判断能否相连

算法:两个集合内存在两个元素在同行或者同列。

    # 是否为同行或同列且相连
    def isReachable(self, x1, y1, x2, y2):
        
        #1、先判断值是否相同
        if self.im2num_arr[x1][y1] != self.im2num_arr[x2][y2]:
            return False
        
        # 2、分别获取两个坐标同行或同列可连的坐标数组
        list1 = self.getDirectConnectList(x1, y1)
        list2 = self.getDirectConnectList(x2, y2)

        # 3、比较坐标数组中是否可连
        for x1, y1 in list1:
            for x2, y2 in list2:
                if self.isDirectConnect(x1, y1, x2, y2):
                    return True

        return False

5、控制鼠标消除

5.1、消除并置为零

    # 点击事件并设置数组为0
    def clickAndSetZero(self, x1, y1, x2, y2):
        # print("click", x1, y1, x2, y2)

        # (299, 251, 768, 564)
        # 原理:左上角图标中点 + 偏移量

        p1_x = int(self.screen_left_and_right_point[0] + (y1 - 1)*self.im_width + (self.im_width / 2))
        p1_y = int(self.screen_left_and_right_point[1] + (x1 - 1)*self.im_width + (self.im_width / 2))

        p2_x = int(self.screen_left_and_right_point[0] + (y2 - 1)*self.im_width + (self.im_width / 2))
        p2_y = int(self.screen_left_and_right_point[1] + (x2 - 1)*self.im_width + (self.im_width / 2))

        time.sleep(0.2)
        self.mouse.click(p1_x, p1_y)
        time.sleep(0.2)
        self.mouse.click(p2_x, p2_y)

        # 设置矩阵值为0
        self.im2num_arr[x1][y1] = 0
        self.im2num_arr[x2][y2] = 0

        print("消除:(%d, %d) (%d, %d)" % (x1, y1, x2, y2))
        # exit()

5.2、GameAssist类主要控制函数

先生成self.im2num_arr矩阵,然后使用穷举消除图标。

    # 程序入口、控制中心
    def start(self):

        # 1、先截取游戏区域大图,然后分切每个小图
        image_list = self.screenshot()

        # 2、识别小图标,收集编号
        self.image2num(image_list)

        print(self.im2num_arr)

      
        # 3、遍历查找可以相连的坐标
        while not self.isAllZero(self.im2num_arr):
            for x1 in range(1, 9):
                for y1 in range(1, 13):
                    if self.im2num_arr[x1][y1] == 0:
                        continue

                    for x2 in range(1, 9):
                        for y2 in range(1, 13):
                            # 跳过为0 或者同一个
                            if self.im2num_arr[x2][y2] == 0 or (x1 == x2 and y1 == y2):
                                continue
 
                            if self.isReachable(x1, y1, x2, y2):
                                self.clickAndSetZero(x1, y1, x2, y2)

6、主函数

if __name__ == "__main__":
    wdname = u'宠物连连看经典版2小游戏,在线玩,4399小游戏 - 360极速浏览器 13.5'

    demo = GameAssist(wdname)
    demo.start()

7、总结

存在的问题:

1、如果一次未消除完,需要手动重新执行程序。

2、图像识别算法还需要优化。

3、图标矩阵定位需要人工校准。

 类似资料: