Python之微信跳一跳V1.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():
    '''
    通过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分左右,分析游戏结束的原因是定位小旗子失败,虽然如此,也算是把整个流程搞明白了,剩余的就只是优化算法而已。

猜你喜欢

转载自blog.csdn.net/wenshifang/article/details/85569463