Python深度强化学习玩微信跳一跳的实现方法

最近学习了一下深度强化学习算法,用 CNN+DDPG 算法做了一个玩微信跳一跳的 AI

和 GitHub 上的基于 OpenCV 的方法有本质的区别,实现了端到端的自动学习

有兴趣的同学可以看一看,或者帮忙改进改进一下,目前参数调优和训练量都还不足

代码在 https://github.com/hijkzzz/wechat-jump-ddpg


Python深度强化学习玩微信跳一跳的实现方法

8 回复

我跳一跳的排行榜都没人了


这个实现主要分几个核心步骤:抓取屏幕、识别位置、计算距离、模拟按压。我用ADB工具来获取屏幕截图和控制手机,用OpenCV处理图像识别棋子和小跳板的位置。

关键点在于距离计算和按压时间的关系。我通过像素距离乘以一个时间系数来模拟按压时长,这个系数需要根据手机分辨率和游戏版本进行微调。

import cv2
import numpy as np
import os
import time

def pull_screenshot():
    """使用ADB命令截取手机屏幕"""
    os.system('adb shell screencap -p /sdcard/screenshot.png')
    os.system('adb pull /sdcard/screenshot.png .')

def find_piece_and_board(im):
    """识别棋子和跳板位置"""
    # 棋子模板匹配(简化版,实际需要更精确的识别)
    piece_template = cv2.imread('piece_template.png', 0)
    res = cv2.matchTemplate(im, piece_template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    piece_x, piece_y = max_loc
    
    # 跳板边缘检测(简化版)
    edges = cv2.Canny(im, 50, 150)
    contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    board_contour = max(contours, key=cv2.contourArea)
    board_x, board_y, board_w, board_h = cv2.boundingRect(board_contour)
    
    return (piece_x, piece_y), (board_x + board_w//2, board_y)

def calculate_distance(piece_pos, board_pos):
    """计算两点间的欧几里得距离"""
    return np.sqrt((board_pos[0] - piece_pos[0])**2 + (board_pos[1] - piece_pos[1])**2)

def jump(distance):
    """根据距离计算按压时间并执行跳跃"""
    press_time = distance * 1.35  # 时间系数,需要调整
    press_time = max(press_time, 200)  # 最小按压时间
    press_time = min(press_time, 2000) # 最大按压时间
    
    cmd = f'adb shell input swipe 500 500 500 500 {int(press_time)}'
    os.system(cmd)

def main():
    while True:
        pull_screenshot()
        im = cv2.imread('screenshot.png', 0)
        
        piece_pos, board_pos = find_piece_and_board(im)
        distance = calculate_distance(piece_pos, board_pos)
        
        print(f"棋子位置: {piece_pos}, 跳板中心: {board_pos}, 距离: {distance}")
        
        jump(distance)
        time.sleep(1)  # 等待跳跃完成

if __name__ == "__main__":
    main()

实际实现时需要注意:棋子识别要用多种方法结合(颜色、形状、模板匹配),跳板识别要考虑各种形状(方形、圆形、药瓶等),时间系数需要大量测试来校准。

建议先做好基础版本再考虑强化学习优化。

好奇这个训练起来会有多慢

跳一跳距离和按压时间正相关,你这样意义不大。


输入不是距离
输入的是原始游戏图像

这个只是作死,当然用测量距离的方式更容易做
但是那种是典型的基于规则的
和 AI 就没什么太多关系了

目前 RL 对短距离激励还是比较容易做的(比如这个 case ),长距离激励会比较麻烦点。

关于可能的改进,提个可能的方向,不一定对:CNN 会不会套得有一些深。

做的还是很有意思的。
可以继续往稀疏奖励和高维状态的方向上去做,应用方面的话机器人,能源规划以及资产管理都有一些可以继续深入的点。

稀疏奖励不好学。而且很容易学到随机特征。。不过想想也是,世界的规则就是这样,某种层面上具有非常强的随机性。。

回到顶部