连连看(三)

Python3 实现QQ游戏连连看游戏辅助

目录

Python3 实现QQ游戏连连看游戏辅助

0、本片前言 

1、水平方向

2、垂直方向

3、一个拐角

4、两个拐角

5、判断是否可以连接


 0、本片前言

从这里开始,我们可以按照上一篇文章中介绍的方法,手动赋值一个矩阵和 total ,不用每次调试运行都打开游戏、截图、保存、构建矩阵了。

本文使用的是这个矩阵,total = 32

       [ [1,  2,  3,  4,  5,  1,  1,  6,  7,  8,   9, 10, 11, 12, 13, 14, 15,  9,  7],
         [16, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  3],
         [17, -1, 18, 19, 20, 21, 22,  2,  9, 12,  4,  7, 16, 12, 23, 17,  6, -1,  5],
         [18, -1, 24, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  8, -1,  5],
         [25, -1,  2, -1, 22, 20, 16, 19, 26, 23,  4,  1, 27,  8, -1, -1, 14, -1,  6],
         [16, -1, 28, -1, 29, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, 17],
         [ 3, -1, 19, -1, 15,  3, 21, 24, 11,  5, 18, 28, 27, 30, 25, 22, 10, -1, 27],
         [17, -1, 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19],
         [11, -1, 31, 29, 20, 13,  4, 13, 14, 11, 10, 24,  7, 18, 14, 12, 30,  8, 28],
         [31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
         [ 9,  6, 10, 24, 27, 26,  2, 25, 28, 20, 23, 29, 22, 29, 31, 31, 13, 21, 25]])

 每写完一个函数都可以进行测试,方法就是 print 看结果

扫描二维码关注公众号,回复: 10814438 查看本文章
# 使用保存的矩阵和 total 初始化
linkup = game()

# 随心所欲的想要测试的两点坐标带入即可
print(linkup.vertical(3, 1, 4, 1))
print(linkup.two_corner(r1, c1, r2, c2))

1、水平方向

首先判断是否在同一行,然后根据进行扫描两点之间是否存在非空(非 -1)的点。

第一次写的时候发现测试 (0, 5) 和 (0, 6) 这两点的时候,发现明明是可以连接的,但是返回的却是 False。

因为有两种特殊情况:

1、如果两点相连接,导致在 for 循环一次都不运行。(使用 Pycharm 的 Debug 模式发现)

      解决方案就是判断同一行的两点是否纵坐标相邻。如果两个坐标点所对应的矩阵中的值相同,可以连线。但这就引起了第二个特殊情况:其中一个点是 -1,另一个点为大于零的数字。

2、其中一个点是 -1,另一个点为大于零的数字。(主要是为了后面的拐点连线判断做铺垫)

    解决方案是用或操作对两个点进行判断,若其中一个为 -1,可以连线。

# 判断水平方向
    def horizon(self, row1: int, col1: int, row2: int, col2: int) -> bool:
        if row1 == row2:
            for i in range(min(col1, col2) + 1, max(col1, col2)):
                # print(self.game_map[row1, i])
                if self.game_map[row1, i] != -1:
                    return False
            # 解决 conjunction
            if min(col1, col2) + 1 == max(col1, col2):
                if (self.game_map[row1, col1] == -1) or (self.game_map[row2, col2] == -1):
                    return True
                if self.game_map[row1, col1] == self.game_map[row2, col2]:
                    return True
            return True
        return False

2、垂直方向

与水平方向相同,举一反三,不再赘述。

    # 判断垂直方向
    def vertical(self, row1: int, col1: int, row2: int, col2: int) -> bool:
        if col1 == col2:
            for i in range(min(row1, row2) + 1, max(row1, row2)):
                # print(self.game_map[i, col1])
                if self.game_map[i, col1] != -1:
                    return False
            # 解决 conjunction
            if min(row1, row2) + 1 == max(row1, row2):
                if (self.game_map[row1, col1] == -1) or (self.game_map[row2, col2] == -1):
                    return True
                if self.game_map[row1, col1] == self.game_map[row2, col2]:
                    return True
            return True
        return False

3、一个拐角

 增加两个拐点 (cor_one_row, cor_one_col) = (row1, col2) 和 (cor_two_row, cor_two_col) = (row2, col1) 作为辅助,不用担心两个点的位置关系,因为在水平和垂直的判断中,我们都使用了 max 和 min 函数进行修正。

那么思路就是判断:

1、point1 与 cor_one 之间是否可以水平连接,point2 与 cor_one 之间是否可以垂直连接。

2、point2 与 cor_two 之间是否可以水平连接,point1 与 cor_two 之间是否可以垂直连接。

其中一个可行,那么 point1 与 point2 之间可以连线。

# 判断一个拐点
def one_corner(self, row1: int, col1: int, row2: int, col2: int) -> bool:
    cor_one_row, cor_one_col = row1, col2
    cor_two_row, cor_two_col = row2, col1
    if self.game_map[cor_one_row, cor_one_col] == -1:
        if self.horizon(cor_one_row, cor_one_col, row1, col1) & self.vertical(cor_one_row, cor_one_col, row2, col2):
            return True
        if self.game_map[cor_two_row, cor_two_col] == -1:
            if self.horizon(cor_two_row, cor_two_col, row2, col2) & self.vertical(cor_two_row, cor_two_col, row1, col1):
                return True
    return False

4、两个拐角

详细分析:

1、在 point1 的水平或垂直连线上任意一点可以与 point2 经过一个拐点的连线连接,即两点间可以经过两个拐点链接

2、在 point2 的水平或垂直连线上任意一点可以与 point1 经过一个拐点的连线连接,即两点间可以经过两个拐点链接

辅助函数:用于获取两目标点所在水平和垂直方向上的空白点(-1)

ps:此函数可以优化,大家可以自行修改优化,欢迎评论私信。

# 收集水平、垂直方向可行点
def collect_points(self, row: int, col: int) -> list:
    points = []
    # 向右方搜索
    for i in range(col + 1, 19):
        try:
            if self.game_map[row, i] == -1:
                points.append((row, i))
            else:
                break
        except IndexError as err:
            # print("Ignore col error.")
            continue
    # 向左方搜索
    for i in range(col - 1, -1, -1):
        try:
            if self.game_map[row, i] == -1:
                points.append((row, i))
            else:
                break
        except IndexError as err:
            # print("Ignore col error.")
            continue
    # 向上方搜索
    for i in range(row - 1, -1, -1):
        try:
            if self.game_map[i, col] == -1:
                points.append((i, col))
            else:
                break
        except IndexError as err:
            # print("Ignore row error.")
            continue
    # 向下方搜索
    for i in range(row + 1, 19):
        try:
            if self.game_map[i, col] == -1:
                points.append((i, col))
            else:
                break
        except IndexError as err:
            # print("Ignore row error.")
            continue
    return points

然后拿着这些点进行遍历,看看是否存在可以经过一个拐点和另一个目标点连接的。存在,则可以两拐点链接。

最终判断两个拐点的完整代码: 

# 判断两个拐点
def two_corner(self, row1: int, col1: int, row2: int, col2: int) -> bool:
    for item in self.collect_points(row1, col1):
        if self.one_corner(item[0], item[1], row2, col2):
            return True
    for item in self.collect_points(row2, col2):
        if self.one_corner(item[0], item[1], row1, col1):
            return True
        return False

5、判断是否可以连接

符合任意一种连接方式即可认定为可以连接。

# 判断是否可以连接
def erasable(self, row1: int, col1: int, row2: int, col2: int) -> bool:
    flag_no_corner = (self.horizon(row1, col1, row2, col2)) or (self.vertical(row1, col1, row2, col2))
    flag_corner = (self.one_corner(row1, col1, row2, col2)) or (self.two_corner(row1, col1, row2, col2))
    return flag_no_corner or flag_corner

【本片完】

【下一篇:连连看(四)—— 你看我这鼠标比用户还真(Pymouse 的替身)

发布了29 篇原创文章 · 获赞 2 · 访问量 1394

猜你喜欢

转载自blog.csdn.net/Lucky_Z1111/article/details/104596421