首先感谢知乎用户神奇的战士(https://zhuanlan.zhihu.com/p/32452473),实测中发现手动版有效,自动版无效,且不同手机效果存在较大差异。
因此在这里改写并实现了自动跳一跳的功能,并整理出一套具有普适性的方案分享给大家。
文章分为两部分,前半段为使用教程,后半段谈谈对源码的学习和认知。
一、使用说明书
为了避免版本兼容问题,我把自己用的相关软件的安装包上传到了百度网盘:
链接: https://pan.baidu.com/s/1boRAPR5 密码: wryq
1、下载并安装Anaconda
(1)Anaconda预装了很多Python的科学计算包及依赖项,相比于原生Python可以免去很多辅助包的安装工作
(2)脚本依赖于Python3,如果电脑中预装Python2,请先卸载
(3)安装完毕后可能会要求重启系统,暂时不重启
2、下载并安装Bluestack
(1)在下载/安装Anaconda等待过程中执行本步骤
(2)BlueStack是安卓模拟器,对电脑配置有一定要求。运行时如发现有卡顿不妨关掉一些暂时不用的软件
(3)安装完BlueStack后,右上角有点下三角下拉菜单,点击设置,将分辨率调整为1600*900
(4)搜索并安装微信
3、下载并安装Adb
(1)在下载/安装Anaconda和BlueStack等待过程中执行本步骤
(2)安装过程中有一步是确认安装位置,把具体路径记录到文本框中
(3)任务栏中点击开始->输入environment->点击编辑账户的环境变量->找到“系统变量”选项卡->点击“新建”按钮->“变量名”文本框中填入android->“变量值”文本框中填入刚才的具体路径->点击“确定”按钮->找到“系统变量”选项卡->列表中找到并双击Path变量->“变量值”文本框的最后追加上“;%android%”(双引号可不要加上去T T)->点击“确定”按钮->点击“确定”按钮
4、下载Python脚本到某一个系统盘的根目录,这里假定保存在c盘
5、以上步骤全部完成后重启电脑,准备工作结束
7、任务栏中点击开始->输入cmd->回车
8、在命令行中依次输入以下命令:
c:
cd\
adb connect 127.0.0.1
python wechat_jump_auto_py3.py
(完毕)
二、源码杂谈
脚本主体思路是:
1、获取游戏截屏
2、分析得到截屏中小人位置和目标块中心点的位置
3、计算两者之间的距离,并乘以一个时间系数作为按压时长
4、模拟按压
5、等待跳跃完毕,循环执行
主要差异在第2步,手动版是由人工点击来确定。而自动版中则通过对截图的解析来获取位置:
小人位置的确定上,基本沿用了原作者的代码,因为小人的颜色通常为深色而且不会变化,通过扫描找到指定颜色的像素点,进而便可确定小人的坐标。
目标块中心点的坐标确定:
(1)当小人在屏幕左半边时,目标块会在右半边,反之亦然;
(2)在目标块所在的半边屏幕上1/3部分往下扫描首先发生颜色变化的就是目标块的上顶点
(3)目标块从上往下边缘呈扩张,结束扩张的高度即为中心点的高度
基于以上三点,代码的思路也就很明朗了:使用双重循环,垂直方向起始位置是屏幕上1/3处往下扫描,水平方向起始位置为屏幕中线,如果小人位置在左边,则往右扫描,反之则向左。如果发生颜色变化,终止循环,由此找到目标块上顶点坐标(i0,j0)。然后双重循环,继续往下扫描,当目标块不再扩张时终止循环,获得垂直方向y坐标为j1,那么中心点位置就是(i0,j1)
接下来补充说一下其他几个步骤,第1步和第4步主要是借用Android调试工具adb来实现Python与模拟器的连接和互动。步骤3先计算起点和终点的直线距离,乘以一个时间系数来得到按压时间,这主要是得益于按压时间和跳跃距离的变化是线性的,因此时间系数可以是个固定值,可以通过反复调试得到。
另外,在获取截屏之后,用到了Python的内置包PIL(Python Imaging Library),这是Python图像处理的标准库,在本案例中就是借助它把图像解析成一个两维矩阵,矩阵上的每个点表示一个颜色,用RGBA来表示,所以判断颜色变化,就是通过比较两个颜色的RGBA值来判断。
最后,聊一聊小程序团队可能会采取的反措施,撇开判断点击位置是否相同、检测点击时间间隔是否一致等迂回策略,在图像识别与反识别的正面攻防上,其实最简单的方法就是把背景换成非纯色的,这就会增加在确定目标块上顶点的难度,而攻方相应的解决方案可以用降维算法预处理图片,突出目标块与背景相邻边界的特征,进而确定和计算中心点坐标。接下来的防守方则考虑如何在不降低用户体验的前提下模糊化这个边界特征,例如考虑把目标块设定运动中的,边线形状和颜色不规则变化等……
最后的最后,攻方的最终解决方案将可能是自学习深度神经网络,姑妄揣测一下算法思路:
1、截屏,取随机数作为按压时间,尝试跳跃,将屏幕截图和随机按压时间作为自变量,是否成功跳跃到目标块作为因变量
2、不断重复第一步,其中有的随机跳跃成功,但更多的随机跳跃失败,每一次跳跃都是一个样本
3、在获得足够多的样本之后便可以训练出能够计算出当前截图下有最高成功概率的跳跃时间的模型
4、用最高成功概率的跳跃时间替代随机时间继续尝试跳跃,依旧将截屏和随机按压时间作为自变量,是否成功跳跃到目标块作为因变量
5、不断重复第四步,将测试样本不断加入训练集中,不断训练模型,成功的概率将会越来越高。
选择神经网络的原因目前想到两个,其一是每一次跳跃相互独立,其二是因变量决定于自变量间的内部关系。
当然这只是理论上的选择,正式环境下实现成本极高,比起算法更大的难度在于深度神经网络计算集群的搭建和运维上。如果最终实现,就直接宣告防守方的失败,因为这整个过程是拟人的。可是话再说回来,码农何苦为难码农,相煎何太急。
最后的最后,祝大家新年快乐,分数刷得高高哒!
领取专属 10元无门槛券
私享最新 技术干货