Python之微信跳一跳V2.0

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():
    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, dir_flg):
    '''
    定位目标位置
    :param image: 游戏画面
    :dir_flg: 小旗子位置标志,dir_flg=0,小旗子处于屏幕左边,反之则小旗子处于屏幕靠右
    :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))
        if dir_flg == 1:
            for j in range(0,w//2):
                pixel = image.getpixel((j,i))
                if left_pixel != pixel:
                    found_aim = True
                    x = j
                    break
        else:
            for j in range(0,w//2):
                pixel = image.getpixel((w-j-1,i))
                if left_pixel != pixel:
                    found_aim = True
                    x = w-j-1
                    break
        if found_aim:
            y = i+40
            break
    if x == -1 or y == -1:
        raise Exception('Not Found piece')

    return x, y


def locate_piece(image_s, image_t):

    pixels_t = image_t.load()

    pixels_s = image_s.load()

    width_t, height_t = image_t.size
    width_s, height_s = image_s.size
    D = []
    time_start = time.time()
    for i in range(50, width_s-width_t-50, 10):
        for j in range(300, height_s-height_t-300, 25):
            d = 0
            for x in range(width_t):
                for y in range(height_t):
                    d += abs(pixels_t[x, y] - pixels_s[i+x, j+y])
            D.append((i, j, d))
        print('completed %%%d' % (((i+1)/(width_s-width_t))*100) )
    time_end = time.time()
    print('cost time %s ms' % str((time_end-time_start)*1000))
    min = D[0][2]
    x = 0
    y = 0
    for i in range(len(D)):
        d = D[i]
        if min > d[2]:
            min = d[2]
            x = d[0]
            y = d[1]

    x = x+ width_t//2
    y = y+ (int)(height_t*0.936)

    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():
    image_t = Image.open('flag_gray.png', 'r')              # MAD算法模板图T

    while True:
        capture()     # 截取游戏画面
        image_s = Image.open('shot.png', 'r').convert('L')  # type:Image.Image
        image_s.convert()
        w,h = image_s.size
        x1, y1 = locate_piece(image_s, image_t)             # MAD算法定位小棋子图标
        f = 0
        if x1 > w/2:
            f = 1
        print('dir_flg = %d' % f )
        x2, y2 = locate_checkerboard(image_s,f)               # 定位跳跃目标位置
        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.966)                # 根据距离计算按压时长
        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()



写在最后的话

相对于第一个版本,V2.0改善了两个地方,一是小旗子的定位算法,用自己的代码实现了最简单的基于灰度图像匹配的MAD算法。二是优化了棋盘位置的定位算法。
跳一跳游戏界面元素比较单一,MAD算法表现还不错,识别精度也较高。在实际运行中发现V1.0版本的棋盘定位算法在小旗子顶部高于棋盘顶部位置时会失败,通过分析得知,小旗子相对于屏幕中心位置来说,只有两种状态,一种是小旗子相对于屏幕中心处于左边,另一种则是小旗子相对于屏幕中心处于右边,在查找棋盘时,把小旗子的位置状态考虑进去。当旗子处于左边时,可以从屏幕最右边向屏幕中心开始定位棋盘,反正同理。
V2.0的不足之处在于,MAD模板匹配算法太耗时,平局耗时在8秒左右,目前有两个办法来解决这个问题,一是把MAD模块用C语言完成,从python中直接导入。二是使用OpenCV,这个强大的开源图像处理库应该实现了各种灰度图像的匹配算法,效率也应该比较高。
此版本得分在400-700分,比V1.0有所提高,但是相比其他大牛的,还是有很大差距,继续努力。。。
有需要完整工程的朋友,请联系QQ772148609。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值