【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 Truereturn False# 判断同行是否可连def isRowConnect(self, x, y1, y2):minY = min(y1, y2)maxY = max(y1, y2)# 相邻直接可连if maxY - minY == 1:return True# 判断两个坐标之间是否全为0for y0 in range(minY + 1, maxY):if self.im2num_arr[x][y0] != 0:return Falsereturn True# 判断同列是否可连def isColConnect(self, y, x1, x2):minX = min(x1, x2)maxX = max(x1, x2)# 相邻直接可连if maxX - minX == 1:return True# 判断两个坐标之间是否全为0for x0 in range(minX + 1, maxX):if self.im2num_arr[x0][y] != 0:return Falsereturn 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 Truereturn False
5、控制鼠标消除
5.1、消除并置为零
# 点击事件并设置数组为0def 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)# 设置矩阵值为0self.im2num_arr[x1][y1] = 0self.im2num_arr[x2][y2] = 0print("消除:(%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:continuefor 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):continueif 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、图标矩阵定位需要人工校准。