连线达人(求哈密顿图通路)自动闯关脚本

一个自动闯关的脚本,不知道你有没有玩过这种一笔从头滑到尾的游戏
连线达人(求哈密顿图通路)自动闯关脚本_第1张图片

自动化脚本总共分为三个部分:
  • 提取图片信息,转换为 无向图 的邻接矩阵
  • 根据邻接矩阵利用DFS+回溯,递归求解通路(暴力求解,在这种小规模情况下python程序可以在2秒内求出一条有效通路)
  • 将通路路径转化为坐标点,利用adb操作手机进行模拟点击

技术难点主要在于提取图片中的信息,如何准确识别出图片中的灰色方块和起点方块,并转化成可处理的数据。信息提取这个过程占据了我开发精力的80%,想了很多办法,最后无意中发现了cv2的一些图片处理的功能才迎刃而解。下面简单介绍一下方块信息提取的思路。

  • 首先需要将无关区域去掉,只保留中间连线区域(如下图),使问题简单化,需要根据手机的屏幕尺寸进行处理(参数我都在config.json文件中进行了说明)
    连线达人(求哈密顿图通路)自动闯关脚本_第2张图片
  • 随后对区域进行灰度和二值化处理,可以简单理解为先将彩色图片处理为只有灰度的图片,然后寻找一个灰度的阀值将图片转换成只有白色和黑色的图片,处理结果如下
    连线达人(求哈密顿图通路)自动闯关脚本_第3张图片
  • 利用OpenCV的求轮廓算法cv2.findContours(),将方块包含坐标点的轮廓数据求出,此步骤可以实现最关键的将图形中的方块位置转化成可处理的数据信息。求轮廓前还需对一些细节进行处理,比如去掉尾巴和胡须,以免对结果产生干扰,比如上图倒数第二个起点方块的尾巴部分就和其他方块连接在了一起,需要提前将连通区域断开,方法也很简单。
    连线达人(求哈密顿图通路)自动闯关脚本_第4张图片
  • 利用boundingRect求出每个轮廓的外接矩形,可确定每个方块中心点的坐标,利用contourArea求出每个轮廓的面积可确定图的起点。

至此图的信息提取完成,只需将坐标信息转换成邻接矩阵表示的图,再利用以下的递归求解算法便可计算出图的通路。
连线达人(求哈密顿图通路)自动闯关脚本_第5张图片

递归求解算法如下,核心代码不超过15行:

    def find_path(self, optimize=True):
        """
        dfs+回溯 递归求解
        :param optimize: 是否对最终结果进行优化,优化可有效减少滑动次数,但模拟滑动操作可能会不稳定
        :return:
        """
        current = time.time() * 1000
        visited = []
        visited.append( self.blocks[self.begin_index])
        self.find_path_fun(visited, self.blocks[self.begin_index])
        path = []
        for item in visited:
            path.append((item.center[0], item.center[1]))
        print("求解耗时 %d ms" % (time.time()*1000 - current,))
        return path if not optimize else self.optimize_path(path)

    def find_path_fun(self, visited, start):
        for item in self.matrix[self.block_map[start]]:
            if item is not None and item not in visited:
                visited.append(item)
                if len(visited) == len(self.blocks):
                    return True
                if self.find_path_fun(visited, item):
                    return True
                else:
                    visited.pop()
        return False
  • 最后就是将路径转化成adb模拟滑动和点击的坐标点即可完成自动化闯关的功能。
  • 其实为了达到100%的自动化闯关,项目中有许多细节上的处理,可具体参考代码GitHub:https://github.com/EnthuDai/lian_xian

    总结:之前看到LeetCode排名榜上的大神写过相似的脚本,当时就觉得这样的东西很有意思,放假在家看到有 连线达人 的广告,生成闯关获得的金币可以提现,遂萌生出写这个项目的念头。这个项目虽然小,但是结合了图片处理、数据结构、算法、安卓adb等相关的知识,十分综合,而且写出来之后看着自动闯关的过程相当享受。

你可能感兴趣的:(杂谈)