【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]]
直连的概念:同行或者同列,可以不相邻但中间没有其他非零元素。
# 是否为同行或同列且可连
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
获取核心矩阵(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
算法:两个集合内存在两个元素在同行或者同列。
# 是否为同行或同列且相连
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
# 点击事件并设置数组为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()
先生成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)
if __name__ == "__main__":
wdname = u'宠物连连看经典版2小游戏,在线玩,4399小游戏 - 360极速浏览器 13.5'
demo = GameAssist(wdname)
demo.start()
存在的问题:
1、如果一次未消除完,需要手动重新执行程序。
2、图像识别算法还需要优化。
3、图标矩阵定位需要人工校准。