QQ游戏连连看的脚本

利用vs 2019和easyx图形库完成QQ游戏连连看的脚本

需要的工具:

  1. win 10
  2. vs 2019
  3. easyx
main.cpp
#include <stdio.h>
#include <easyx.h>

#define ROW 11
#define COL 19

HWND qqHwnd = NULL;
IMAGE image(800, 600);
HDC qqHdc, imgHdc;
IMAGE img[ROW][COL];
RECT rect;

void ClearImage(IMAGE* pimg)
{
	SetWorkingImage(pimg);
	setbkcolor(RGB(48, 76, 112));
	cleardevice();
	SetWorkingImage(NULL);
}

bool IsSimilar(IMAGE* pimg1, IMAGE* pimg2)
{
	//10 10
	SetWorkingImage(pimg1);
	COLORREF color11 = getpixel(3, 3);
	COLORREF color12 = getpixel(3, 6);
	COLORREF color13 = getpixel(6, 3);
	COLORREF color14 = getpixel(6, 6);
	COLORREF color15 = getpixel(5, 5);
	SetWorkingImage(pimg2);
	COLORREF color21 = getpixel(3, 3);
	COLORREF color22 = getpixel(3, 6);
	COLORREF color23 = getpixel(6, 3);
	COLORREF color24 = getpixel(6, 6);
	COLORREF color25 = getpixel(5, 5);

	if (color11 == color21 && 
		color12 == color22 && 
		color13 == color23 && 
		color14 == color24 && 
		color15 == color25)
		return true;
	else
		return false;
}

bool IsBlank(IMAGE* pimg)
{
	SetWorkingImage(pimg);
	COLORREF color11 = getpixel(2, 2);
	COLORREF color12 = getpixel(2, 7);
	COLORREF color13 = getpixel(7, 2);
	COLORREF color14 = getpixel(7, 7);
	COLORREF color15 = getpixel(5, 5);

	if (color11 == RGB(48, 76, 112) &&
		color12 == RGB(48, 76, 112) &&
		color13 == RGB(48, 76, 112) &&
		color14 == RGB(48, 76, 112) &&
		color15 == RGB(48, 76, 112))
		return true;
	else
		return false;
}

void GameInit()
{
	//初始化image对象
	qqHwnd = FindWindowA(NULL, "QQ游戏 - 连连看角色版"); //获取连连看窗口句柄
	if (qqHwnd == NULL)
	{
		printf("没有找到游戏窗口\n");
		system("pause");
		exit(0);
	}
	qqHdc = GetDC(qqHwnd);			//获取游戏窗口绘图句柄
	imgHdc = GetImageHDC(&image);	//获取image绘图句柄
	BitBlt(imgHdc, 0, 0, 800, 600, qqHdc, 0, 0, SRCCOPY);  //调用winapi将窗口图像绘制到image中

	SetWorkingImage(&image);  //设置image位当前工作对象
	setorigin(15, 182);		  //设置坐标原点
	for (int i = 0; i < ROW; i++)  //切割图像
		for (int j = 0; j < COL; j++)
			getimage(&img[i][j], j * 31 + 10, i * 35 + 10, 10, 10);  //缩小范围
	SetWorkingImage(NULL);
}

bool IsExist()
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (!IsBlank(&img[i][j]))
				return true;
		}
	}
	return false;
}

bool HorizConnect(int row1, int col1, int row2, int col2) {
	if (row1 != row2) 
	{  //如果r1 != r2 
		return false;  //不连通
	}

	int maxCol = col1 > col2 ? col1 : col2;  //最大的列
	int minCol = col1 > col2 ? col2 : col1;  //最小的列

	if (maxCol - minCol == 1) 
	{ //两图块相邻
		return true;  //连通
	}

	for (int i = minCol + 1; i < maxCol; i++) {
		if (!IsBlank(&img[row1][i])) 
		{
			return false;
		}
	}

	return true;
}

bool VerticConnect(int row1, int col1, int row2, int col2) {
	if (col1 != col2) 
	{
		return false;
	}

	int maxRow = row1 > row2 ? row1 : row2;
	int minRow = row1 > row2 ? row2 : row1;

	if (maxRow - minRow == 1) 
	{ //两图块相邻
		return true;
	}

	for (int i = minRow + 1; i < maxRow; i++) 
	{
		// 水平方向遇到一个非空节点,就认为水平连接失败
		if (!IsBlank(&img[i][col1])) 
		{
			return false;
		}
	}

	return true;
}

bool OneTurnConnect(int row1, int col1, int row2, int col2) 
{
	if (row1 == row2 || col1 == col2) 
	{
		return false;  //不能在同一水平线,或同一垂直线上
	}

	// 第1个拐点
	int turnRow1 = row1;
	int turnCol1 = col2;
	// 第2个拐点
	int turnRow2 = row2;
	int turnCol2 = col1;

	if (IsBlank(&img[turnRow1][turnCol1]) && //第1个拐点是空节点
		HorizConnect(row1, col1, turnRow1, turnCol1) &&
		VerticConnect(turnRow1, turnCol1, row2, col2)) 
		{
		return true;
		}

	if (IsBlank(&img[turnRow2][turnCol2]) && //第2个拐点是空节点
		VerticConnect(row1, col1, turnRow2, turnCol2) &&
		HorizConnect(turnRow2, turnCol2, row2, col2)) 
		{
		return true;
		}

	return false;
}

bool TwoTurnConnect(int row1, int col1, int row2, int col2) 
{
	for (int i = 0; i < ROW; i++) 
	{
		for (int j = 0; j < COL; j++) 
		{
			if (!IsBlank(&img[i][j])) 
			{ // 寻找空节点
				continue;
			}

			// 双折拐点必须和起点(或终点)同一行(或同一列),
			// 否则不能作为双折拐点
			if (i != row1 && i != row2 && j != col1 && j != col2) 
			{
				continue;
			}

			if (OneTurnConnect(row1, col1, i, j) &&
				(HorizConnect(i, j, row2, col2) ||
					VerticConnect(i, j, row2, col2))) 
					{
						return true;
					}

			if (OneTurnConnect(i, j, row2, col2) &&
				(HorizConnect(row1, col1, i, j) ||
					VerticConnect(row1, col1, i, j))) 
					{
						return true;
					}
		}
	}

	return false;
}

bool CheckConnect(int row1, int col1, int row2, int col2) 
{
	// 1. 起点和终点都不能是空白点
	if (IsBlank(&img[row1][col1]) ||
		IsBlank(&img[row2][col2]) ||
		// 2. 起点和终点不能是同一个点
		row1 == row2 && col1 == col2 ||
		// 3. 起点和终点必须是相同的图块
		!IsSimilar(&img[row1][col1], &img[row2][col2])) 
		{
			return false;
		}

	if (HorizConnect(row1, col1, row2, col2) ||  // Redmi
		VerticConnect(row1, col1, row2, col2) ||
		OneTurnConnect(row1, col1, row2, col2) ||
		TwoTurnConnect(row1, col1, row2, col2)) 
		{
			return true;
		}

	return false;
}

void Match()
{
	//找第一个点 起点/终点
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			if (IsBlank(&img[i][j]))  //不管  0空的
				continue;//找下一个

			//找下一个
			for (int m = i; m < ROW; m++)
			{
				for (int n = 0; n < COL; n++)
				{
					if (IsSimilar(&img[i][j], &img[m][n])) //找到2个一样
					{
						if (CheckConnect(i, j, m, n))  //判断是否连通
						{
							//鼠标移动到起点上。
							SetCursorPos((rect.left + 15 + j * 31) + 10, (rect.top + 182 + i * 35) + 10);

							//鼠标点击一下起点。
							mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

							//Sleep(20);

							//鼠标设置到终点。
							SetCursorPos((rect.left + 15 + n * 31) + 10, (rect.top + 182 + m * 35) + 10);
							//鼠标点击一下终点。
							mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
							ClearImage(&img[i][j]);
							ClearImage(&img[m][n]);
							//Sleep(20);
						}
					}
				}
			}
		}
	}
}

int main()
{
	GameInit();

	GetWindowRect(qqHwnd, &rect);
	SetForegroundWindow(qqHwnd);
	Sleep(1000);
	while (IsExist())
		Match();

	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
实现QQ游戏连连看脚本需要用到图像识别和游戏操作的技术。这里提供一个基于Python的脚本,使用了PIL库进行图像处理,以及pyautogui库进行鼠标操作。 首先,我们需要对游戏中的图像进行截取和处理,以便于后续的匹配和操作。可以使用PIL库中的ImageGrab和Image模块进行图像处理和截取。 ```python import os import time from PIL import ImageGrab, Image # 定义截图函数 def screenshot(x1, y1, x2, y2): # 获取屏幕大小 screen = ImageGrab.grab() width, height = screen.size # 截取指定区域 box = (x1, y1, x2, y2) im = screen.crop(box) return im ``` 接下来,我们需要对截取的图像进行匹配,找出相同的图案。可以使用OpenCV库进行图像匹配,这里为了简单起见,使用PIL库中的histogram方法进行颜色匹配。 ```python # 定义匹配函数 def match(image1, image2): # 直方图 histogram1 = image1.histogram() histogram2 = image2.histogram() # 计算相似度 similarity = 0 for i in range(len(histogram1)): similarity += min(histogram1[i], histogram2[i]) return similarity ``` 最后,我们需要进行游戏操作,找到相同的图案并进行消除。可以使用pyautogui库进行鼠标操作,找到相同的图案则进行点击。 ```python import pyautogui # 定义游戏操作函数 def play(): # 定义游戏区域 x1, y1 = 350, 200 x2, y2 = 1050, 800 # 定义图案大小和间隔 w, h = 80, 80 gap = 10 # 定义图案列表 images = [] for i in range(1, 9): image = Image.open(os.path.join("images", "{}.png".format(i))) images.append(image) # 循环查找相同的图案并消除 while True: for i in range(len(images)): for j in range(i + 1, len(images)): image1 = images[i] image2 = images[j] for m in range(x1, x2 - w, gap): for n in range(y1, y2 - h, gap): im = screenshot(m, n, m + w, n + h) similarity = match(im, image1) if similarity > 1000: pyautogui.click(m + w / 2, n + h / 2) time.sleep(0.5) similarity = match(im, image2) if similarity > 1000: pyautogui.click(m + w / 2, n + h / 2) time.sleep(0.5) ``` 这里需要注意的是,游戏操作需要在游戏窗口中进行,因此需要将游戏窗口置于最前面,并将游戏区域的坐标进行调整。 以上就是一个基于Python的QQ游戏连连看脚本的实现。需要注意的是,这只是一个简单的示例,实际上游戏中可能存在多种图案、道具等元素,需要进行更加复杂的处理和匹配。因此,这个脚本只作为学习和参考使用,不应该用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T h a t

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值