用Python玩连连看是什么效果?别霍霍别人了

共 6768字,需浏览 14分钟

 ·

2020-07-28 17:20


2020

07

22

今天距2021年162天

这是ITester软件测试小栈第144次推文

点击上方蓝字“ITester软件测试小栈“关注我,每周一五早上 07:30准时推送。


微信公众号后台回复“资源测试工具包”领取测试资源


本文5294字,阅读约需14分钟



作者:Laziji
源自:https://laboo.top/2018/11/07/lianliankan/



前言


连连看游戏纵览全局,扫到能够相连的相同图片,就用鼠标去点,先点第一个,再点第二个,随着“撕拉”一道闪电相连方块随即爆炸,爽的不要不要。


Python大法好,Java下这个代码大概需要2000行左右,而python算上注释也才300行而已。以下用Python 实现的qq连连看辅助, 仅用于学习, 请在练习模式下使用, 不要拿去伤害玩家们。


基本环境配置


版本:Python3.6

系统:Windows 7


相关模块

import PIL.ImageGrab
import pyautogui
import win32api
import win32gui
import win32con
import time
import random



使用方法


开始游戏后运行就行了, 再次提示, 在练习模式中使用, 否则可能会被其他玩家举报。

效果图




代码实现

游戏重点:

  • 生成成对的图片元素;

  • 将图片元素打乱排布;

  • 定义什么才算“相连”(两张图片的连线不多于3跟直线,或者说转角不超过2个);

  • 实现“相连”判断算法;

  • 消除图片元素并判断是否消除完毕;

import PIL.ImageGrab
import pyautogui
import win32api
import win32gui
import win32con
import time
import random

def color_hash(color):
    value = ""
    for i in range(5):
        value += "%d,%d,%d," % (color[0], color[1], color[2])
    return hash(value)


def image_hash(img):
    value = ""
    for i in range(5):
        c = img.getpixel((i * 3, i * 3))
        value += "%d,%d,%d," % (c[0], c[1], c[2])
    return hash(value)


def game_area_image_to_matrix():
    pos_to_image = {}

    for row in range(ROW_NUM):
        pos_to_image[row] = {}
        for col in range(COL_NUM):
            grid_left = col * grid_width
            grid_top = row * grid_height
            grid_right = grid_left + grid_width
            grid_bottom = grid_top + grid_height

            grid_image = game_area_image.crop((grid_left, grid_top, grid_right, grid_bottom))

            pos_to_image[row][col] = grid_image

    pos_to_type_id = {}
    image_map = {}

    empty_hash = color_hash((4876112))

    for row in range(ROW_NUM):
        pos_to_type_id[row] = {}
        for col in range(COL_NUM):
            this_image = pos_to_image[row][col]
            this_image_hash = image_hash(this_image)
            if this_image_hash == empty_hash:
                pos_to_type_id[row][col] = 0
                continue
            image_map.setdefault(this_image_hash, len(image_map) + 1)
            pos_to_type_id[row][col] = image_map.get(this_image_hash)

    return pos_to_type_id


def solve_matrix_one_step():
    for key in map:
        arr = map[key]
        arr_len = len(arr)
        for index1 in range(arr_len - 1):
            point1 = arr[index1]
            x1 = point1[0]
            y1 = point1[1]
            for index2 in range(index1 + 1, arr_len):
                point2 = arr[index2]
                x2 = point2[0]
                y2 = point2[1]
                if verifying_connectivity(x1, y1, x2, y2):
                    arr.remove(point1)
                    arr.remove(point2)
                    matrix[y1][x1] = 0
                    matrix[y2][x2] = 0
                    if arr_len == 2:
                        map.pop(key)
                    return y1, x1, y2, x2


def verifying_connectivity(x1, y1, x2, y2):
    max_y1 = y1
    while max_y1 + 1 < ROW_NUM and matrix[max_y1 + 1][x1] == 0:
        max_y1 += 1
    min_y1 = y1
    while min_y1 - 1 >= 0 and matrix[min_y1 - 1][x1] == 0:
        min_y1 -= 1

    max_y2 = y2
    while max_y2 + 1 < ROW_NUM and matrix[max_y2 + 1][x2] == 0:
        max_y2 += 1
    min_y2 = y2
    while min_y2 - 1 >= 0 and matrix[min_y2 - 1][x2] == 0:
        min_y2 -= 1

    rg_min_y = max(min_y1, min_y2)
    rg_max_y = min(max_y1, max_y2)
    if rg_max_y >= rg_min_y:
        for index_y in range(rg_min_y, rg_max_y + 1):
            min_x = min(x1, x2)
            max_x = max(x1, x2)
            flag = True
            for index_x in range(min_x + 1, max_x):
                if matrix[index_y][index_x] != 0:
                    flag = False
                    break
            if flag:
                return True

    max_x1 = x1
    while max_x1 + 1 < COL_NUM and matrix[y1][max_x1 + 1] == 0:
        max_x1 += 1
    min_x1 = x1
    while min_x1 - 1 >= 0 and matrix[y1][min_x1 - 1] == 0:
        min_x1 -= 1

    max_x2 = x2
    while max_x2 + 1 < COL_NUM and matrix[y2][max_x2 + 1] == 0:
        max_x2 += 1
    min_x2 = x2
    while min_x2 - 1 >= 0 and matrix[y2][min_x2 - 1] == 0:
        min_x2 -= 1

    rg_min_x = max(min_x1, min_x2)
    rg_max_x = min(max_x1, max_x2)
    if rg_max_x >= rg_min_x:
        for index_x in range(rg_min_x, rg_max_x + 1):
            min_y = min(y1, y2)
            max_y = max(y1, y2)
            flag = True
            for index_y in range(min_y + 1, max_y):
                if matrix[index_y][index_x] != 0:
                    flag = False
                    break
            if flag:
                return True

    return False


def execute_one_step(one_step):
    from_row, from_col, to_row, to_col = one_step

    from_x = game_area_left + (from_col + 0.5) * grid_width
    from_y = game_area_top + (from_row + 0.5) * grid_height

    to_x = game_area_left + (to_col + 0.5) * grid_width
    to_y = game_area_top + (to_row + 0.5) * grid_height

    pyautogui.moveTo(from_x, from_y)
    pyautogui.click()

    pyautogui.moveTo(to_x, to_y)
    pyautogui.click()


if __name__ == '__main__':

    COL_NUM = 19
    ROW_NUM = 11

    screen_width = win32api.GetSystemMetrics(0)
    screen_height = win32api.GetSystemMetrics(1)

    hwnd = win32gui.FindWindow(win32con.NULL, 'QQ游戏 - 连连看角色版')
    if hwnd == 0:
        exit(-1)

    win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
    win32gui.SetForegroundWindow(hwnd)
    window_left, window_top, window_right, window_bottom = win32gui.GetWindowRect(hwnd)
    if min(window_left, window_top) < 0 or window_right > screen_width or window_bottom > screen_height:
        exit(-1)
    window_width = window_right - window_left
    window_height = window_bottom - window_top

    game_area_left = window_left + 14.0 / 800.0 * window_width
    game_area_top = window_top + 181.0 / 600.0 * window_height
    game_area_right = window_left + 603 / 800.0 * window_width
    game_area_bottom = window_top + 566 / 600.0 * window_height

    game_area_width = game_area_right - game_area_left
    game_area_height = game_area_bottom - game_area_top
    grid_width = game_area_width / COL_NUM
    grid_height = game_area_height / ROW_NUM

    game_area_image = PIL.ImageGrab.grab((game_area_left, game_area_top, game_area_right, game_area_bottom))

    matrix = game_area_image_to_matrix()

    map = {}

    for y in range(ROW_NUM):
        for x in range(COL_NUM):
            grid_id = matrix[y][x]
            if grid_id == 0:
                continue
            map.setdefault(grid_id, [])
            arr = map[grid_id]
            arr.append([x, y])

    pyautogui.PAUSE = 0

    while True:
        one_step = solve_matrix_one_step()
        if not one_step:
            exit(0)
        execute_one_step(one_step)
        time.sleep(random.randint(0,0)/1000)

主要思路就是利用pywin32获取连连看游戏句柄, 获取游戏界面的图片, 对方块进行切割, 对每个方块取几个点的颜色进行比对, 均相同则认为是同一个方块,后模拟鼠标去消除, 代码的最后一行是每次点击的间隔。


如需获取Python实现连连看源代码,请在后台回复“连连看”即可。




以上

That‘s all


ITester软件测试小栈
往期内容宠幸


1.Python接口自动化-接口基础(一)

2.Python接口自动化-接口基础(二)


3.Python接口自动化-requests模块之get请求


4.Python接口自动化-requests模块之post请求

5.Python接口自动化之cookie、session应用


6.Python接口自动化之Token详解及应用


7.Python接口自动化之requests请求封装


8.Python接口自动化之pymysql数据库操作


9.Python接口自动化之logging日志


10.Python接口自动化之logging封装及实战

想获取更多最新干货内容
快来星标 置顶 关注

<<  滑动查看下一张图片  >>


 后台 回复"资源"取干货
回复"微信群"入群打怪升级

测试交流Q群:727998947


点亮一下在看,你更好看


浏览 38
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报