10

跳一跳自动脚本了解一下

 3 years ago
source link: http://fuzhii.com/2018/03/13/jump-game/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

跳一跳自动脚本了解一下

主页 关于 时间 友链 留言

去年项目空闲时学完 iOS,想着找一个小项目实践一下。有了以下想法:

1、读纸质书时重点划线的段落没有进行摘录存档,可以使用 OCR 技术将文字扫描到笔记本中,以书的维度进行管理。实际上「识墨笔记」就是这样做的,可是它是按扫描次数收费的,这样体验很差,just like Timi?

2、比如你听这首 Here We Are Again ,可以一耳就听出主奏乐器是钢琴,那么后面的伴奏还有哪些?这是一个很好的需求场景——听歌识器。可以写个 APP 识别所有参与演奏的乐器,甚至名字我都想好了——Piper - recognize the instruments in music。如果你和我一样,听到结束都不知道这首钢琴曲的主奏乐器是什么,那就更需要这个 App 了。这个应用的核心识别算法怎么实现呢?机器学习深度学习训练模型进行分类即可。

3、小游戏跳一跳发布时,外挂盛行,这是个很好玩的现象。也想着用脚本控制 iPhone 上的跳一跳,自动化游戏可以使用符号学习(规则),统计学习(机器学习)或者连接主义方法(深度学习)等不同层次的方法。而使用规则写自动脚本是最简单的,于是本文试着从工程上分析一下。

jumpgame-1.gif

自动化测试工具

在 Android 手机上使用 USB + ADB 调试的方式可以用电脑控制手机的行为,iPhone 手机需要安装一个软件 WebDriverAgent。它相当于一个服务端,接收来自电脑 client 的请求,

It works by linking XCTest.framework and calling Apple’s API to execute commands directly on a device。

jumpgame-3.jpeg

iPhone 上的服务端安装方法参考 iOS 真机调试如何安装 WebDriverAgent。需要注意使用 iproxy 软件将手机的端口映射到电脑端口上。

PC 上的客户端使用 Python 库 facebook-wda。使用方法如下:

import wda
client = wda.Client()
session = client.session()

# 截图
def take_screen_shot():
	client.screenshot('./screenshot/screen.png')

# You Jump
def jump_a_step(press_time):
	print('press time: {}'.format(press_time))
	# 在 (100, 100) 的位置按压 press_time 后松开
	session.tap_hold(100, 100, press_time) 

jump_a_step(1)

自动脚本的原理就是截图 -> 计算下一步跳的距离 -> 按压屏幕跳 -> 截图 …

量出棋子到下一个跳的目标棋盘的距离,然后乘以一个时间系数得到按压的时间,传入 jump_a_step 接口即可。


定位棋子采用以下策略

1、将 RGB 图片转换为 256 级别灰度的灰度图

2、棋子的灰度值小于 80,将小于 80 的区域置为黑色(值为 0),大于 80 的区域置为白色(值为 255),去除干扰噪声

3、从上到下,从左到由扫描图像矩阵,若有一块区域的灰度值为 0,则判定为棋子。返回这个区域横纵坐标的平均值

jumpgame-2.jpg

定位棋盘简单采用以下策略

1、使用上述步骤的灰度图矩阵

2、从上到下,从左到右扫描,遇到的第一个灰度值和周围差异较大的点即为棋盘的顶点,简单将这个点当做棋盘的位置。可以用其他的规则去准确定位棋盘的中心点,本文不再研究

def get_dest_postion(gray_img_array, width, height):
	for line in range(500, height - 500, 3):
		for col in range(50, width - 50, 3):
			if (abs(gray_img_array[line][col] - 
				gray_img_array[line-1][col]) > 20 and
				abs(gray_img_array[line][col] - 
					gray_img_array[line-1][col]) < 250):
				return line, col

扫描的时候优化一下执行效率,棋盘位于上 1/3 位置到 2/3 位置之间,因此只扫描这个区域。扫描步长可以加长一些,一次扫描 3 个像素点。

这样就可以让跳一跳自动运行起来了,但由于图像识别的策略太暴力简单,容易出现一些边界情况。对 2000 的高分没有什么执著,所以就到此为止了。整个 repo 位于 jump-a-jump。后续学完 DL 算法有时间再来一个 AI 版本的跳一跳或者王者荣耀?

我的目标是,青铜五。


iOS 真机调试如何安装 WebDriverAgent


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK