最近春节,qq上出了一个叫穿越福城的小游戏。游戏的玩法类似挑一挑,也是通过一个个木桩。只不过把跳的过程变成了搭梯子。按的时间越长,梯子越长。梯子过长或者过短小企鹅都会掉下去,游戏失败。我的目的是用python来实现自动玩游戏。(主要原因是我手残。。没办法,只好另辟蹊径,技术开挂)。在刚开始构思的时候,我其实是觉得挺简单的一个小脚本就能搞定。但是在实际编码和测试的过程中,我越发觉得想要完成一个简陋版本,勉强能用的版本非常容易。但是想要做到稳定性好,准确率高实在是不容易。下面我就把我这两天的编码和完善过程记录下来。

先说说我的总体思路。通过adb的截图功能获得截图,然后根据获得的截图计算出应该按压多少毫秒,再通过adb shell input swipe来按压指定毫秒数。循环往复,理论上可以一直刷到无限分。

这里面的难点显然是在第二步,即怎样根据截图计算毫秒数呢?

那我们首先要思考毫秒数和什么变量有关,再从图片中提取或者计算出变量即可。梯子是按得时间越长就越长,所以可以认为按得时间t应该和木桩之间的距离成线性关系。那我们怎样从图片上计算起始木桩和目标木桩之间的距离呢?第一想法肯定是在图片中找到起始点x0,y0,再找到目的点x1,y1.计算这两个点的欧氏距离。但是玩这个游戏会发现,如果木桩之间的距离很长,游戏中会拉高视角。所以要想获得木桩之间的实际距离,不能光考虑像素之间的距离,还要考虑视角高度。视角越高,一个像素点代表的实际距离就越长。所以综上,时间和两个因素有关,一是像素距离,而是视角高度。

第一个因素像素距离,想要获取这个参数的关键在于怎样确定起点和终点。一个图片在计算机中就是一个矩阵,在矩阵中怎样找到起点和终点?这就需要明确起点和终点的特征。根据特征找到满足特征的像素,进而就可以找到起点和终点。从截图可以发现,起点的明显特征就是深色的小企鹅,在明艳的背景中,只有小企鹅是深色的。所以找图片中rgb均小于50的像素点,就可以定位小企鹅所在的位置。终点就更好确定了,每个木桩的中心都有一块红色菱形。这些红色菱形的rgb都是一样的。找这个rgb值就可以找到这些菱形,那么怎么知道哪个菱形是目标点呢?观察可知,在小企鹅上方的,且满足红色菱形的是目标点。找到了起点和终点,我们就可以算出来dis(distance)

第二个因素是视角高度。这个就比较抽象了,改用什么表示呢?视角高度不好直接计算,但是有办法体现出来。视角高度越高,相同面积的东西所占的像素数量就越少,也就是近大远小。而观察游戏可知,每个木桩上的红色菱形的面积是一定的。所以我们可以用目标点红色菱形的像素数(size)来表示视角高度。像素数越多,视角高度越低;像素数越少,视角高度越高。

现在找到了计算dis和size的方法,那么按压时间t怎么计算呢?首先设置一个参数a,用于调整系数。

t = a*dis/sqrt(size)

dis越大,显然按压时间应该越长。size越大,说明视角越低,显然按压时间应该越短。那么为什么size要开一个平方根呢?这是因为dis是一次的长度,而size是二次的面积。所以要开一个平方根,保证量纲一致。a由实验测得。经过实验我发现a=30左右的时候,程序运行良好,虽然做不到每次都非常精准,但是大部分时候都是可以通过的。

到这里为止,我的小程序已经基本可以大部分时候100+了。运气比较好的时候我还拿到了273分。但是在一次次测试中也暴露出了很多问题。接下来开始我的调试之路。

1、广告干扰

观察上图,本来我的起始点是根据颜色判断的。结果广告中也出现了相同的色彩,从颜色来确定起始点的路子走不通了,怎么办?那只好找其他特征。什么特征呢?那就是

1、企鹅是实心的

2、企鹅是近似圆形的

我之前都是用PIL的,现在不根据颜色了,就需要用更加高级和复杂的python-opencv了。先二值化,只保留深色部分,然后用findContours找边缘,然后筛选出满足条件的contour即可。这样一来找对起点的准确率就极高啦。

第二个问题:准确率不高。显然我建立的模型和游戏的内部逻辑还是有一定的差距。

怎么解决?从数学上来说,就是要确定一个二元函数time=f(dis,size).为了找到这个函数到底是啥,我首先得采集足够多的样本点。

采集了300个样本点后,绘制出dis-size函数,发现如下图所示

这说明和我原先想的不一样,这不是一个连续函数,而是一个离散的函数。(dis,size)一共只有十六中组合。

既然这样就好办了。先kmeans聚类,划分成16类,找到每一类的dis,size,time,作为table记录到程序中。每次获得一个dis和size,查找table,找到最先进的dis和size所对应的time,然后用adb按相应的time即可。

经过这么已改进,准确率极高。几乎每一次都是三分。当然其中的time参数由于是取得平均数,和真正的准确值还有一定的差距,在偶尔不是三分的情况下还要对time进行改进。

经过这些改进这个程序可以说已经基本可以跑了。我写了两个版本的代码,一个是aaa.py,这个是使用t=dis/sqrt(size)方法的;另一个是bbb.py,这个是使用table版本的。table版本的正确率更加高。

代码放在github上:https://github.com/blacksungrass/pythons/tree/master/qq%E6%96%B0%E5%B9%B4%E5%B0%8F%E6%B8%B8%E6%88%8F%E8%87%AA%E5%8A%A8%E5%8C%96

即使经过了改进,还是有一些问题,不过出现的次数很少

1、这个小企鹅有时候会跳起来转个圈,截图如果截取的是小企鹅挑起来的图会造成误判断

2、有时候游戏中的一些背景建筑,尤其是塔之类的,会把小企鹅挡住一小块,导致findContours函数无法将小企鹅识别为一个整体。

用python来自动玩类似跳一跳的小游戏的更多相关文章

  1. Python 帮你玩微信跳一跳 GitHub Python脚本

    前言想自己搞游戏小程序的 在github 有人已经利用 python程序, 通过adb 获取不同型号安卓手机的系统截图,然后通过计算小人与目标位置距离之后得到准确的触摸时间,再通过 开发者模式里的 a ...

  2. 教你用.Net来玩微信跳一跳

    目前开发的所有代码都已经上传到了GitHub.欢迎大家来Star https://github.com/GiantLiu/AutoJump 目前程序分为“全自动版本”和“半自动版本” 全自动版本 We ...

  3. 用python实现自动玩21点小游戏

    1. 背景 前段时间发现一个论坛上(https://npupt.com/blackjack.php)有21点小游戏. 这个21点小游戏的规则是每个人开局都会获得随机点数,如果觉得点数小,可以继续摸牌. ...

  4. 用Python来玩微信跳一跳

    微信2017年12月28日发布了新版本,在小程序里面有一个跳一跳小游戏,试着点一点玩了下.第二天刚好在一篇技术公众号中,看到有大神用Python代码计算出按压时间,向手机发送android adb命令 ...

  5. 利用Python玩微信跳一跳

    创建python项目jump_weixin,新建python程序jump.py 需要4个辅助文件[adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll,fastboot.exe ...

  6. Python程序,辅助微信跳一跳游戏介绍

    一.思路介绍 1. 通过Python自动手机截屏,并保存到电脑 2. 通过PhotoShop测量要跳的距离 3. 通过Excel计算按压时间 4. 通过CMD命令控制手机按压时间 二.实现方法详解 1 ...

  7. 了解python,利用python来制作日常猜拳,猜价小游戏

    初次接触python,便被它简洁优美的语言所吸引,正所谓人生苦短,python当歌.python之所以在最近几年越发的炽手可热,离不开它的一些特点: 1.易于学习:Python有相对较少的关键字,结构 ...

  8. python学习笔记(五) 200行实现2048小游戏

    用前文提到的基础知识,和网上流行的2048源码,用python实现该游戏. 先将用户操作和游戏逻辑绑定. WASD分别对应移动方向上.左.下.右 然后实现矩阵的转置和逆置,这样只要实现一个方向的移动, ...

  9. 用 Python 编写剪刀、石头、布的小游戏(快速学习python语句)

    import random#定义手势类型allList = ['石头','剪刀','布']#定义获胜的情况winList = [['石头','剪刀'],['剪刀','布'],['步','石头']]pr ...

随机推荐

  1. Cronolog日志分割、定时清理

    阿里云发送短信提示服务器磁盘占用到80%警报短信 经过排查发现tomcat日志文件达到10个多G,手动删除过久的日志文件后恢复到50% 但是catalina.out文件还有6个G 解决方法 一.安装C ...

  2. 考研计算机复试(广东工业大学C语言复试2018笔试题)(精华题选)

    1.obj文件是:(二进制文件) 2.函数func(float x){printf("%f",x+x);}的类型是() A.void B.int类型 C.无法确定 3.若有定义:i ...

  3. 部署安装kubernetes client-python,执行pip install setup.py时报错

    之前在本地安装过kubernetes的python库,安装下来一切正常,但今天换到测试机器上去部署,确保错了,具体步骤如下. 第一步,克隆代码,执行以下命令:    # git clone --rec ...

  4. python文件(概念、基本操作、常用操作、文本文件的编码方式)

    文件 目标 文件的概念 文件的基本操作 文件/文件夹的常用操作 文本文件的编码方式 01. 文件的概念 1.1 文件的概念和作用 计算机的 文件,就是存储在某种 长期储存设备 上的一段 数据 长期存储 ...

  5. Linux----Github环境搭建

    前面介绍了在Windows环境上安转GitHub环境,原本以为打包成jar,发布到Linux不需要再安转Git,但是因为我们使用了Config-Server配置中心,远程配置来启动,所以需要在Linu ...

  6. Vue中transition和animation的使用

    一:二者的对比 1.动画循环就用animation.在animation中有一个animation-iteration-count属性可以定义循环次数.transition是执行一次以后就不会执行,但 ...

  7. java第11周

    1.JPQL查询 JPQL全称Java Persistence Query Language 基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移 ...

  8. 花了2小时写bug

    程序员的工作,写bug,修bug,改bug 写了2小时逻辑关系,没写明白 比昨天多了一个返回上一层的功能 也很简单,清除下数组内容即可 emm..明天继续深究吧 dic = { "植物&qu ...

  9. WCF分布式3-InstanceContext和ConcurrencyMode

    WCF中,如果将实现契约(接口)的服务配置默认为 InstanceContextMode = InstanceContextMode.Single, 也就是说这个服务对象,客户端调用这个对象的接口时, ...

  10. springboot单元测试自动回滚:@Transactional

    2019-04-21 12:23:14.509 INFO 9384 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - St ...