本项目为RPA开发的一个练手项目,纯属娱乐。
代码如下,注释清晰:
import win32gui
from pymouse import PyMouse
import win32con
from PIL import ImageGrab, Image
import pyautogui
from time import sleep, time
import numpy as np
# 小图标的数量规格
WIDTH = HEIGHT = 10
# 寻找并前置目标窗口
win = win32gui.FindWindow(0, '熊猫连连看')
left, up, right, bottom = win32gui.GetWindowRect(win)
win32gui.SendMessage(win, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
win32gui.SetForegroundWindow(win)
win32gui.ShowWindow(win, win32con.SW_SHOW)
sleep(0.1)
# 窗口截图,截去边缘部分
left, up, right, bottom = left + 15, up + 45, right - 15, bottom - 15
img = ImageGrab.grab((left, up, right, bottom))
# img.save(r'D:\hk\images\grab.jpg')
width, height = img.size
sz_w, sz_h = width // WIDTH, height // HEIGHT
# 将每张小图矩阵化
kinds = dict()
kinds_mat = np.zeros((WIDTH, HEIGHT))
cnt = 0
img_centers = np.zeros((WIDTH, HEIGHT, 2)) #每张小图片的实际坐标位置
for i in range(WIDTH):
for j in range(HEIGHT):
l, u, r, b = j * sz_w, i * sz_h, (j + 1) * sz_w, (i + 1) * sz_h
img_centers[i][j] = [(l + r) // 2 + left, (u + b) // 2 + up]
im = np.array(img.crop((l, u, r, b)))
im_w, im_h, _ = np.shape(im)
# 向内缩小图像以避免边缘像素影响
im = im[int(im_h * 0.1):int(im_h * 0.9), int(im_w * 0.1):int(im_w * 0.9)]
if str(im) not in kinds.values():
kinds[cnt] = str(im)
cnt += 1
for k, v in kinds.items():
if v == str(im):
kinds_mat[i][j] = k
print(kinds_mat)
def my_click(point):
'''
自定义点击
'''
global img_centers
x, y = img_centers[point[0]][point[1]]
pyautogui.click(x, y)
sleep(0.001)
def if_connected(x, y):
'''
判断x,y两点是否连通
'''
global kinds_mat
# 相贴
if x[0] == y[0] and abs(x[1] - y[1]) == 1 or x[1] == y[1] and abs(x[0] - y[0]) == 1:
print(1)
return True
# 直线
if x[0] == y[0] and (kinds_mat[x[0], x[1] + 1:y[1]] == -1).all() or x[1] == y[1] and (
kinds_mat[x[0] + 1:y[0], x[1]] == -1).all():
print(2)
return True
# 一弯
def one_corner(x, y):
if x[0]>y[0]: #二弯情况下
x,y=y,x
if x[1] < y[1]:
if (kinds_mat[x[0], x[1] + 1:y[1] + 1] == -1).all() and (kinds_mat[x[0] + 1:y[0], y[1]] == -1).all() \
or (kinds_mat[y[0], x[1]:y[1]] == -1).all() and (kinds_mat[x[0] + 1:y[0], x[1]] == -1).all():
return True
elif x[1] > y[1]:
if (kinds_mat[x[0], y[1]:x[1]] == -1).all() and (kinds_mat[x[0] + 1:y[0], y[1]] == -1).all() \
or (kinds_mat[y[0], y[1] + 1:x[1] + 1] == -1).all() and (kinds_mat[x[0] + 1:y[0], x[1]] == -1).all():
return True
if one_corner(x, y):
print(3)
return True
# 二弯,点的气遍历加一弯判断
# 上
cnt = 1
if x[0] > 0:
while x[0] - cnt >= 0 and kinds_mat[x[0] - cnt, x[1]] == -1:
xup = (x[0] - cnt, x[1])
oc = one_corner(xup, y)
if oc:
print(4.1)
return True
cnt += 1
# 下
cnt = 1
if x[0] < WIDTH - 1:
while x[0] + cnt <= WIDTH - 1 and kinds_mat[x[0] + cnt, x[1]] == -1:
xbottom = (x[0] + cnt, x[1])
oc = one_corner(xbottom, y)
if oc:
print(4.2)
return True
cnt += 1
# 左
cnt = 1
if x[1] > 0:
while x[1] - cnt >= 0 and kinds_mat[x[0], x[1] - cnt] == -1:
xleft = (x[0], x[1] - cnt)
oc = one_corner(xleft, y)
if oc:
print(4.3)
return True
cnt += 1
# 右
cnt = 1
if x[1] < WIDTH - 1:
while x[1] + cnt <= WIDTH - 1 and kinds_mat[x[0], x[1] + cnt] == -1:
xright = (x[0], x[1] + cnt)
oc = one_corner(xright, y)
if oc:
print(4.4)
return True
cnt += 1
#逐一判断
inds = [np.where(kinds_mat == i) for i in kinds]
connections = []
while not (kinds_mat == -1).all():
for ind in inds:
row, col = ind
sz = len(row)
for i in range(sz - 1):
for j in range(i + 1, sz):
x, y = (row[i], col[i]), (row[j], col[j])
if x not in connections and y not in connections:
if if_connected(x, y):
connections.extend((x, y))
kinds_mat[x] = kinds_mat[y] = -1
my_click(x)
my_click(y)
效果演示:
参考文章: