目录
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 看结果
# 使用保存的矩阵和 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
【本片完】