连连看怎么判断两张图片相同C语言,连连看辅助开发——第二篇【编程实现找出相同的棋子】...

本帖最后由 YiZheng 于 2020-2-19 20:46 编辑

今天来讲讲怎么用程序算法找出相同的棋子,首先咱们今天的目标就是读取内存数据,然后分析内存,利用算法找出相同的棋子

简单说如果想消除一对棋子,咱们得先找出相同的棋子;

昨天的那张棋盘的内存截图可能会有人看不懂,我先解读解读;

先上两张图片;

55fd2b2273b5a8b4531f72773c469d6e.gif

第二天界面截图.PNG (97.55 KB, 下载次数: 2)

2020-2-18 19:03 上传

55fd2b2273b5a8b4531f72773c469d6e.gif

第二天内存截图.PNG (26.72 KB, 下载次数: 3)

2020-2-18 18:51 上传

可以发现整个棋盘的布局是有点反人类的;

我为了方便你们看,做了手脚;

观察游戏界面第一排和最后一排,再观察内存区域红线部分;

发现游戏中的一排在内存中是以一列存储的,也就是【游戏】一排==【内存】一列,【游戏】一列==【内存】一排;

第一步:读取数据到数组

//棋盘数据

char chessData[9][14];

void GetChessData()

{

///棋盘基地址

DWORD baseAddress = 0x0019FA04;

//取得窗口句柄

HWND gameHWND = FindWindowA(NULL, "连连看");

//通过窗口句柄-》取得窗口进程ID

DWORD processID; ::GetWindowThreadProcessId(gameHWND, &processID);

//通过进程ID-》获得进程句柄

HANDLE processOpen = OpenProcess(PROCESS_ALL_ACCESS, false, processID);

//临时变量,存放棋子

char tmp[1];

//定义缓冲区

LPVOID pBuffer = (LPVOID)&tmp;

for (int i = 1; i < 13; i++)//读取列

{

for (int j = 1; j < 8; j++)//读取行

{

//定义棋盘基地址指针

LPCVOID pBase = (LPCVOID)baseAddress;

//读取棋盘数据

ReadProcessMemory(processOpen, pBase, pBuffer, 1, NULL);

//写入数据到数组

chessData[j][i] = *tmp;

//绕过两个数据之间的3个00

baseAddress += 0x4;

}

//绕过一行数据后的00和FF

baseAddress += 0x1C;

}

}

最后读取出来的数据是这个样子;

0  0   0   0   0   0  0  0  0  0  0  0  0  0

0  8   8   8   8   8  8  8  8  8  8  8  8  0

0  8   b  13   a   c  11 b  d  13  d e 11  0

0  f   10  9   14  e  2  15 12 12   4 3  3  0

0  7   a   6   8   15 4  b  9 9  1  11  c  0

0  e   3   7   f   6  a  10 7 13  f 2  2    0

0  12  d   4   15  e  f  1  10  1  5  14  11 0

0  11  11  11  11  11 11  11 11 11 11 11 11 0

0  0   0   0   0   0  0  0  0  0 0 0 0 0

完美!一个一个空格敲的我眼睛酸,后面没敲了,所以比较乱,别介意;

为什么我写数据到数组的时候要从一开始,就是为了周围有一圈零,这个后面会用到;

还有就是每次写入一个数据,地址都要加上一个4,以正确的读取后面的数据,每读取一行也要加一个1C,十进制就是28,如果你不这样做,你就等着叫爸爸:

0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 8 8 8 8 8 8 8 8 8 8 8 8 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0

不加就是读出一群8来

第二步:实现找出相同一对的算法;

bool FindPair()

{

int firstPiece_x; int firstPiece_y;//第一颗棋子

int cecondPiece_x; int cecondPiece_y;//第二颗棋子

for (firstPiece_x = 1; firstPiece_x < 13; firstPiece_x++)

{

for (firstPiece_y = 1; firstPiece_y < 8; firstPiece_y++)//外面两层,是第一颗棋子的XY坐标

{

for (cecondPiece_x = firstPiece_x; cecondPiece_x < 13; cecondPiece_x++)

{

for (cecondPiece_y = firstPiece_y; cecondPiece_y < 8; cecondPiece_y++)//里面两层,是第二颗棋子的XY坐标

{

//如果两个棋子的值相等,并且两个棋子值不等于零(未被消除),并且第一颗棋子与第二颗棋子不在同一个位置(自己不等于自己)

if ((chessData[firstPiece_y][firstPiece_x] == chessData[cecondPiece_y][cecondPiece_x])

&& (chessData[firstPiece_y][firstPiece_x] != 0 || chessData[cecondPiece_y][cecondPiece_x] != 0)

&& !(firstPiece_x == cecondPiece_x && firstPiece_y == cecondPiece_y))

{

//找到了返回真,这里会写一个算法判断两个棋子是否能消除。。。。。

return true;

}

}

}

}

}

}

找棋子的话也是从数组的1下标开始,周围的零没必要也去找一遍;

好了结束!大家有建议欢迎提出来;

第一篇传送门 :分析游戏

第三篇传送门:算法设计

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值