ADB命令
python执行os命令 os.system(‘cmd’)
ADB截屏命令 adb shell screencap -p /sdcard/shot.png
ADB下载手机图片 adb pull /sdcard/shot.png
图片文件操作
使用PIL.Image库 from PIL import Image
定位棋盘位置
详见代码
定位小旗子
详见代码
跳跃位置计算
详见代码
完整代码
#coding=utf-8
import os
import time
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import random
def capture():
'''
通过ADB指令执行截屏,并下载图片到PC上
截取的图片保存在/sdcard/shot.png
'''
os.system('adb shell screencap -p /sdcard/shot.png')
os.system('adb pull /sdcard/shot.png')
def goto_location(x,y,v):
press_time = (int)(v * 1.93)
print('adb shell input swipe {x1} {y1} {x2} {y2} {v}'.format(x1=x,y1=y,x2=x,y2=y,v=press_time))
os.system('adb shell input swipe {x1} {y1} {x2} {y2} {v}'.format(x1=x,y1=y,x2=x,y2=y,v=press_time))
def locate_checkerboard(image):
'''
定位目标位置
:param image: 游戏画面
:return: 目标位置坐标点
'''
w,h = image.size
found_aim = False
y = -1
x = -1
for i in range(h//3,h):
left_pixel = image.getpixel((0,i))
for j in range(0,w):
pixel = image.getpixel((j,i))
if left_pixel != pixel:
found_aim = True
x = j
break
if found_aim:
y = i+50
break
if x == -1 or y == -1:
raise Exception('Not Found piece')
return x, y
def locate_piece(image):
w,h = image.size
is_found = False
x = -1
y = -1
for i in range(200,h,10):
for j in range(0,w,5):
pixel = image.getpixel((j,i))
r,g,b = pixel[0:3]
if 48 < r < 58 and 54 < g < 64 and 98 < b < 108: # 根据RGB颜色来匹配
x = j
is_found = True
if is_found:
y = i
break
if x == -1 or y == -1:
raise Exception('Not Found piece')
print('piece found at (%d,%d)' % (x, y))
return x, y
def calculate_distance(x1, y1, x2, y2):
x = x1-x2
y = y1-y2
return (x**2+y**2)**0.5 # 勾股定理求斜边长度.
def random_generate(width, height):
x1 = random.randint(100,width-100)
y1 = random.randint(200,height-200)
return x1, y1
def location(x1, y1, time):
x2 = x1 + random.randint(1,9)
y2 = y1 + random.randint(3,12)
command = 'adb shell input swipe {x1} {y1} {x2} {y2} {v}'.format(x1=x1, y1=y1, x2=x2, y2=y2,v=time)
print(command)
os.system(command)
def main_thread():
while True:
capture() # 截取游戏画面
image = Image.open('shot.png', 'r') # type:Image.Image
w,h = image.size
x1, y1 = locate_piece(image) # 定位小棋子位置
x2, y2 = locate_checkerboard(image) # 定位跳跃目标位置
distance = calculate_distance(x1, y1, x2, y2) # 计算小棋子到目标位置的距离
print('distance of (%d,%d)->(%d,%d) is %d pixel' % (x1, y1, x2, y2, distance))
press_time = (int)(distance * 1.965) # 根据距离计算按压时长
x, y = random_generate(w,h) # 随机生成按压坐标
print('locate to (%d,%d), press time is %d ms' % (x2,y2,press_time))
location(x, y, press_time) # 模拟手指按压屏幕
time.sleep(random.randrange(990,1990,15)/1000.0) # 随机延时,避免微信检测到
if __name__ == '__main__':
main_thread()
写在最后的话
程序非常简单,可以称为第一个版本,其中的目标棋牌位置定位和小旗子的定位方法简直太Low了,以至于程序只能玩到200分左右,分析游戏结束的原因是定位小旗子失败,虽然如此,也算是把整个流程搞明白了,剩余的就只是优化算法而已。