惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
Martin Fowler
Martin Fowler
爱范儿
爱范儿
IT之家
IT之家
Last Week in AI
Last Week in AI
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
aimingoo的专栏
aimingoo的专栏
G
Google Developers Blog
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
美团技术团队
The Cloudflare Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog

Go Further

【教程】manim动画制作工具 【直观算法】二叉搜索树算法总结 【直观算法】二叉树遍历算法总结 【直观算法】Egg Puzzle 鸡蛋难题 博客文章总目录 TensorSpace 一个3D神经网络可视化框架 【直观详解】通俗易懂了解什么是黎曼猜想 支持币与去中心化商业模式 那些值得一看的TED演讲附全文文稿笔记 【区块链】共识算法与如何解决拜占庭将军问题 【直观详解】让你永远忘不了的傅里叶变换解析 【直观详解】泰勒级数 Dota2-A帐效果 深入浅出看懂AlphaGo Zero/AlphaGo元 【直观详解】线性代数中的转置正交正规正定 程序员技能图谱 【直观详解】线性代数的本质 【直观详解】什么是PCA、SVD 【直观详解】什么是正则化 Pandas-Wiki 【区块链】比特币与金融、ICO和监管 【区块链】现代区块链与新技术 【区块链】一文看懂区块链:一步一步发明比特币 【直观详解】拉格朗日乘法和KKT条件 【直观详解】支持向量机SVM Dota2伤害类型详解 【直观详解】机器学习分类器性能指标详解 【直观详解】信息熵、交叉熵和相对熵 Dota2机制总结 【直观详解】Logistic Regression
微信跳一跳解题报告
2018-01-19 · via Go Further

【阅读时间】5min - 7min 2810 words
【内容简介】本文总结了解决问题{如何在跳一跳上快速取得高分的问题},分为人类解决方案,机器解决方案两部分

问题描述

对于微信跳一跳来说,问题描述很直观

问题描述

问题描述

  • 【玩游戏的心态】游戏本身有没有什么小技巧?
    • 特殊的加分技巧有哪些?
    • 如何才能不紧张?
  • 【解题目的心态】每一次【跳跃】如何不掉下去?
    • 每一跳,看到目标墩后,需要按多久?
    • 目标墩和小人的距离是多少?

游戏机制

考虑到这是一个【按得时间越久,跳的距离越远的游戏】,也就是说:不摔死才是王道!问题描述已经如此明了,依次解决就好

加分机制

【1】特殊墩。停留2s,可加对应分数

墩类型 加分
井盖 +5
魔方 +10
便利店 +15
音乐盒(注意,有一层透明玻璃的才是) +30

【2】连击跳。连续中心点,+2 +4 …… (是个人都知道)

【3】快速跳。落地之后马上起跳,可以在下一次落地即使也从+1变为+2

按压时间与跳跃距离

直说结论,微信跳一跳的按压时间和跳跃距离是大约线性关系(根据其他大神的验证和精确测试,并不是完美线性关系)

打开声音,在蓄力的过程会有嘟嘟声,两次声音之间0.105秒左右,而每次跳跃的距离可以用尺子量出来。拟合(找一条直线看看是否能正好通过所有的点)后是个直线

写成公式的话为
$$
按压时间 = k \times 目标墩中心和小人的距离
$$
其实只要针对你的手机把这个k拟合出来就好(iOS,非Plus系列,k = 2.045)

设计原则

对于游戏设计来说,一款优秀的【休闲游戏】一定要满足三点

  • 核心规则简单
  • 容易失误
  • 回报和难度成正比 + 随机奖励

所以,跳一跳能火爆,除了好友圈(这里包含微信强大的整合推广能力)之中的攀比心理,更是在这三点都做的相当出色

解决方案

不是每个人都闲着没事做去搞得那么复杂来玩这个游戏,只有两种人会这么做,一种好胜心装逼心爆炸的,另一种就是吃饱了撑着(估计我是两者兼而有之),所以根据现根据前一种人来说,给出的解决方案就是【技巧上】

技巧

游戏技巧当然是利用【比较容易达成】的手段来减少失误的方法,这款游戏考验的核心节奏感控制力

【节奏感】

大家都知道默数一分钟这个游戏吧

能完美默数60s,并且每一秒差距都不大的同学,在这部分就有很高的天赋了。当然还有学乐器,长时间锻炼的同学也是

【控制力】

也叫手残部分。你的APM(每分钟操作次数)速度,控制自己手的能力都考虑其中。

有个游戏是掉尺子抓住,看谁抓的位置更靠上,控制力包含对手的掌控力+反应速度,在这个游戏能取得很棒成绩的同学,你的得分肯定不会低

当然,所有这两点,都是可以通过不断的锻炼(花时间疯狂跳)来提高(这和花时间练琴才能弹的越来越好是一个道理)。只是有些人提高的快,有些同学可能提高的慢,而且很不幸,这种提升是一个Logistic曲线(有天花板)

天赋这东西就是这样,你在这里不擅长,太正常不过。每个人天赋都在不同的领域,所以放宽心才是王道,别太较真(跳一跳跳出一场轰轰烈烈的人生,我的天)

以下就是一些小技巧

用纸贴住分数

紧张和手不稳是【失误】的最大元凶,所以贴住分数有奇效

建立自己的模型

个人建议自己把距离分为4类

  • 很近(人和墩基本贴起来,一看就觉得好近)
  • 很远(看起来就远的那种)
  • 介于两者之间但是靠很近
  • 介于两者之间但是靠很远

在新墩出现的时候,先用0.5秒分一个类

【4类】原则,宁愿多按一点不少按

【1类】原则,蜻蜓点水千万不多

【2 3类】是最容易出问题的类别,如果失误,根据【第二设计原则】,太正常,如果太容易高分,成就感也会被压缩到很小,所以这是必须的,大侠从头来过就好

小墩

对于遇到看起来非常小的墩(小药瓶,天崩地裂)

首先,不要虚,个人虽然没有验证,但是小的目标,感觉能跳上去的阈值也会大一些(或说磁铁or吸附效应),只要按照4分类模型来跳,上垒的可能性还是挺高的

多跳

用时间积累,就和练钢琴是一个套路,身体的肌肉根据你看的图像产生反应,如果已经成为一种自然反应,分数肯定不会低

正常方案

解决这个问题,就是计算目标墩中心和小人的距离,那么目标墩的位置(目标位置),和小人的位置(起跳点位置)就是待求量

但是这些正常方案都需要在每一跳花费一定时间,非大毅力者不可为

听音法

听到嘟的次数 跳跃的距离范围 cm
1 0 - 1.02
2 1.02 - 1.54
3 1.54 - 2.05
4 2.05 - 2.58
5 2.58 - 3.09
6 3.09 - 3.61
7 3.61 - 4.12
8 4.12 - 4.64
9 大于 4.64

量距离 ➜ 查表 ➜ 专心听 ➜ 数嘟嘟声 ➜ 到次数放

(不做评价,累)优势是如果每次都很准,+32 +64 可能都不是梦想吧?

滑动屏幕法

滑动屏幕法

然后,匀速的速度是 5.1 cm/s

(这个方法,感觉比靠感觉更容易失误)这个方法并没有每次都可以跳到中心的特点,个人感觉这个网站找到的方法有点做负功

程序方案

市面上很多的【外挂】或者说【脚本】基本都是这个方案,还有一些直接截包的可能更加暴力一些

手机和电脑交互方法

电脑手机连接起来,并且手机可以和电脑交换数据(API),比如电脑可以控制按压时间,电脑可以控制手机截图之类的基本交互操作

Android有adb工具,iOS有WebDriverAgent

算法流程图

截图 ➜ 算出小人位置 ➜ 算出目标墩位置 ➜ 计算按压时间 ➜ 利用API操控手机按压 ➜ 跳

其实流程图非常简单,直接单线程就搞定了(没有循环结构和分支结构,都不用用其他软件画了)

主要如何计算小人位置,和计算目标墩位置两部分是关键

多尺度搜索

利用OpenCV,图像处理,可以把所有小人抠图出来和图像进行匹配,最后选取置信度最高的,找出小人位置。代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def multi_scale_search(pivot, screen, range=0.3, num=10):
H, W = screen.shape[:2]
h, w = pivot.shape[:2]

found = None
for scale in np.linspace(1-range, 1+range, num)[::-1]:
resized = cv2.resize(screen, (int(W * scale), int(H * scale)))
r = W / float(resized.shape[1])
if resized.shape[0] < h or resized.shape[1] < w:
break
res = cv2.matchTemplate(resized, pivot, cv2.TM_CCOEFF_NORMED)

loc = np.where(res >= res.max())
pos_h, pos_w = list(zip(*loc))[0]

if found is None or res.max() > found[-1]:
found = (pos_h, pos_w, r, res.max())

if found is None: return (0,0,0,0,0)
pos_h, pos_w, r, score = found
start_h, start_w = int(pos_h * r), int(pos_w * r)
end_h, end_w = int((pos_h + h) * r), int((pos_w + w) * r)
return [start_h, start_w, end_h, end_w, score]

目标墩也可以使用类似的方法。只是要想办法减小搜索空间,加速。因为目标墩的数量还是比较多的。还可以搜索那个中心的小白点,速度越快越准(主需要等那个白点出现就好)

机器学习方案

为什么题都已经解了,还需要深究呢?这里主要目的是【提高用户体验感】,考虑到繁多的手机种类和尺寸,特别是iOS中截图的图像压缩问题,需要一套更加稳定的算法,机器学习算法就应运而生了

输入

经过裁剪的截图,只保留小人和目标墩(包含关键信息即可,做法使用OpenCV颜色为界,和小人位置为界即可),最终图像大小为 640*720 像素点

输出

两个值,目标墩的位置【x,y】(小人位置使用多尺度匹配搜索效率足够高了)

模型结构

考虑是图像处理。选择卷积网 - CNN,5层,基本规模,训练完成模型体积约700M

训练数据

根据跳一跳截图大约3000章,保证包含所有目标墩的形态,并且使用多尺度算法进行标注(所谓标注就是算出目标墩【x,y】值,并记录,和这幅图匹配起来)

模型增强

第一层网络经过数据训练后误差在10像素以内。为了进一步提升精度,之后,以此点中心,根据原训练图,再截图320*320大小的图片,同时加入像素偏移(噪声,防止过拟合),再次利用另一个CNN来训练计算坐标

Pipeline示意图

最终结果

小于1像素,Inference时间0.5秒左右

Trick

由于微信的反作弊系统,需要添加一些人为随机因素绕过反作弊系统,基本思路

  • Target_pos + 正态分布随机数,保证连跳次数最多5-6次
  • 间隔时间为>2s的随机数
  • 按压位置随机

至此,微信跳一跳算是通关了。倒腾不息,生命不止。游戏中学习,兴趣中学习是我辈福气!

游戏是放松的一种方式,这种休闲游戏的好处就是,上瘾不易,每个人都有自己的天花板,每周刷新后跳跳看看可能会变成常态,总之孔子说的好,过犹不及

【参考文献】

思路借鉴于知乎相关问题下的回答

代码借鉴Prinsplield大神的AI跳一跳项目,只添加绕过反作弊系统的代码

感谢大神们提供的学习资料!