这几天做了个外挂,主要是想学习下相关技术,
参考的是郁金香老师的视频
核心算法是我自己实现的
我在判断3条线路连通性时,用了4个辅助点,纵向pa和pb,横向pc和pd
让其中2个点与我们棋盘上的棋子形成一个矩形,
然后遍历它们组成这个矩形的所有行和所有列
把所有的情况都考虑成3条路径,因为它们都在一个矩形上
其中有的点重合的话那就是2条或1条路径
只要保证2个参考点p1和p2不重叠就行了
纵向时的pa与pb 可以和参考点p1或p2重叠
横向时的pc与pd 可以和参考点p1或p2重叠
xp_sp2
vc6的MFC程序
在框架代码中调用下面的方法就可以了
//llk_wg.h
const PCHAR gameCaption="QQ游戏 - 连连看角色版"; //程序窗口标题
const LPARAM lpStartMenu= (568<<16)+655; //开始按钮坐标
HWND hGame=::FindWindow(NULL,gameCaption); //获取游戏窗口句柄
DWORD dwProcessId; //进程的pid
HANDLE hProcess; //进程句柄
LPCVOID lpBaseAddress; //基地址
byte arrChessData[11][19]; //棋盘数据存放
DWORD rDwLen; //实际读取的字节数
LPDWORD lpNumberOfBytesRead=&rDwLen; //实际读取的字节数指针
BOOL readFlag=false; //读取数据标志失败
BOOL ReadData(LPCVOID lpBaseAddress,LPVOID lpRead,DWORD nsize);//读数据
void LeftClick(POINT pp); //模拟鼠标单击
BOOL ReadChessData(); //读棋盘数组数据
BOOL CheckChess(POINT p1,POINT p2); //检测棋子是否可清除
BOOL CheckLine2p(POINT pi,POINT pj) ; //检测2点是否直通(无障碍)
BOOL Click2p(POINT p1,POINT p2); //模拟点击消息
void ClearPairOfChess(BOOL b) ; //消除棋子主过程
void KillAll(); //秒杀
void AutoStart(); //自动开局
BOOL CheckLine2p(POINT pi,POINT pj)//检测同行或同列的2点是否连通(无障碍)
{ //关键算法之一
POINT pUp;
POINT pDown;
POINT pLeft;
POINT pRight;
if ((pi.x==pj.x)&&(pi.y==pj.y)) //棋子重叠可连通
{
return true;
}
if (pi.x==pj.x) //同列时(x相等,y不等)
{
if (pi.y<pj.y)
{
pUp=pi;
pDown=pj;
}
else
{
pUp=pj;
pDown=pi;
}
if ( 1==(pDown.y-pUp.y) ) //相邻棋子可连通
{
return true;
}
else //不相邻时
{
for (int lineNum=pUp.y+1; lineNum<pDown.y; lineNum++)
{
if (arrChessData[lineNum][pUp.x]!=0)
{
return false; //有障碍
}
}
}
}//
if (pi.y==pj.y) //同行时(x不等,y相等)
{
if (pi.x<pj.x)
{
pLeft=pi;
pRight=pj;
}
else
{
pLeft=pj;
pRight=pi;
}
if ( 1==(pRight.x-pLeft.x) ) //相邻棋子可连通
{
return true;
}
else
{
for (int columnNum=pLeft.x+1; columnNum<pRight.x; columnNum++)
{
if (arrChessData[pLeft.y][columnNum]!=0)
{
return false; //有障碍
}
}
}
}//
return true;
}
BOOL CheckChess(POINT p1,POINT p2) //检测棋子可否消除
{ //关键算法之一
bool checkFlag=false;
POINT pa,pb;//pa的x坐标与p1相等,pb的x坐标与p2相等
pa.x=p1.x;
pb.x=p2.x;
POINT pc,pd;//pc的y坐标与p1相等,pd的y坐标与p2相等
pc.y=p1.y;
pd.y=p2.y;
for (int lineNum=0;lineNum<11;lineNum++)
{
pa.y=lineNum;
pb.y=lineNum;
if( CheckLine2p(p1,pa)&&CheckLine2p(pa,pb)&&CheckLine2p(pb,p2) )
{
//Click2p(p1,p2); //执行消除
checkFlag=true;
}
}
for (int columnNum=0;columnNum<19;columnNum++)
{
pc.x=columnNum;
pd.x=columnNum;
if ( CheckLine2p(p1,pc)&&CheckLine2p(pc,pd)&&CheckLine2p(pd,p2) )
{
//Click2p(p1,p2); //执行消除
checkFlag=true;
}
}
return checkFlag;
}
BOOL Click2p(POINT p1,POINT p2) //模拟单击事件
{ //棋子宽度31,高度35
//int x=25,y=195; //第一个棋子坐标
LeftClick(p1);
LeftClick(p2);
ReadChessData();
if (arrChessData[p1.y][p1.x]==0)
{
return true; //成功消除一对棋子
}
return false;
}
void KillAll() //秒杀
{
for (int a=0;a<10;a++)
{
ClearPairOfChess(true); //一般5次循环内就完成秒杀
}
}
void ClearPairOfChess(BOOL b) //清除一对棋子的主过程
{
ReadChessData(); //更新一下棋盘数据
//遍历棋盘,找出成对的棋子
POINT p1,p2;
int x1,y1;
int x2,y2;
for (y1=0;y1<11;y1++) //遍历行数y
{
for (x1=0;x1<19;x1++) //遍历列数x
{
if (arrChessData[y1][x1]!=0) //不为空子时,此子设为p1
{
for (y2=y1;y2<11;y2++)
{
for (x2=0;x2<19;x2++)
{
if ((arrChessData[y1][x1]==arrChessData[y2][x2])&&
(!((x1==x2)&&(y1==y2)))
)
{ //存在p2时
p1.x=x1;
p1.y=y1;
p2.x=x2;
p2.y=y2;
if (CheckChess(p1,p2)) //检测是否可清除
{
if (Click2p(p1,p2))//消除
{
if (!b) //不秒杀
{
return;
}
}
}
}
}
}
}
}
}
}
void LeftClick(POINT pp) //模拟鼠标单击
{
if (hGame)
{
LPARAM lParam = ((195+pp.y*35)<<16)+(25+pp.x*31);
SendMessage(hGame,WM_LBUTTONDOWN,0,lParam);
SendMessage(hGame,WM_LBUTTONUP,0,lParam);
}
}
void AutoStart() //自动开始按钮
{
hGame=::FindWindow(NULL,gameCaption); //获取游戏窗口句柄
if (hGame)
{
LPARAM lParam = lpStartMenu; //(568<<16)+655
PostMessage(hGame,WM_LBUTTONDOWN,MK_LBUTTON,lParam);
PostMessage(hGame,WM_LBUTTONUP,0,lParam);
}
}
BOOL ReadData(LPCVOID lpBaseAddress,LPVOID lpRead,DWORD nsize) //读数据
{ //3个参数分别是,基址,读取数据存放的缓冲区指针,要读取的数据大小
hGame=::FindWindow(NULL,gameCaption);//获取游戏窗口句柄
if (hGame==NULL)
{
//AfxMessageBox(gameErr);
return readFlag;
}
::GetWindowThreadProcessId(hGame,&dwProcessId); //获取进程id
hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,dwProcessId); //打开
readFlag=::ReadProcessMemory(hProcess,lpBaseAddress,
lpRead,nsize,lpNumberOfBytesRead); //读一个字节
return readFlag;
}
BOOL ReadChessData() //读棋盘数组数据
{
lpBaseAddress= (LPCVOID)0x0012A480; //棋盘数组基址
ReadData(lpBaseAddress,arrChessData,sizeof(byte)*11*19);
return readFlag;
}
- 大小: 28.5 KB
- 大小: 36 KB
分享到:
相关推荐
【标题】易语言qq连连看辅助程序源码 在编程领域,辅助程序通常是用来增强或自动化某一特定软件功能的工具,而"易语言"是一种基于汉语词汇的编程语言,旨在降低编程的难度,让更多人能够参与到编程活动中。本资源...
这个代码只目前适合平面连连看游戏,可以用鼠标点击,也可以自己修改...本代码在第一高手的代码基础上修改而成,主要修改QQ游戏背景添加后原工具不能正常工作的bug。以每个图标的左上角标志性白点为识别点进行定位查找。
易语言QQ连连看辅助源码! 原创 要的速度了
qq连连看辅助工具java源码,Idea项目
QQ连连看是一款深受玩家喜爱的经典休闲游戏,而“按键精灵”是一种自动化工具,它能够模拟用户的键盘和鼠标操作,极大地提升了工作效率或者游戏体验。在这个场景中,我们将关注的重点放在使用Vbscript(Visual Basic...
QQ游戏连连看源码,直接就可以编译,秒杀一切QQ游戏连连看
易语言源码,仅供大家学习编程做参考,只做参考价值,有兴趣学习易语言的
QQ连连看秒杀源码是一种基于经典游戏QQ连连看的作弊工具,主要目的是帮助玩家在游戏中快速消除匹配项,实现秒杀效果。这类源码通常由编程爱好者或黑客编写,利用了游戏的某些漏洞或者机制来达到秒杀的目的。在本案例...
自学python时, 拿来练手的小代码, 基于python3.4, PyQt, Pywin32, 并提供了py2exe的setup.py及相关dll, ... 功能上实现了QQ连连看手动消除, 自动定时消除, 功能. 核心算法是基于递归调用的一个连连看相关模块的查找.
QQ连连看秒杀源码 - 易语言
QQ连连看是一款经典的休闲益智游戏,其VC++源代码的提供对于学习和研究游戏开发,尤其是C++编程和Windows GUI编程的开发者来说是宝贵的资源。这个源代码包含的功能有自动消除、秒杀以及单个消除,这展示了游戏逻辑和...
QQ连连看是一款深受玩家喜爱的经典休闲游戏,其2D版本更是简单易上手,适合各年龄段的用户。本文将深入探讨“仿QQ连连看单机版”这一项目,旨在解析其核心技术和实现方法,帮助开发者们更好地理解和创建类似的游戏。...
【Java仿QQ连连看】项目是一个使用Java Swing库构建的桌面游戏,旨在模仿经典游戏QQ连连看的玩法和界面。Swing是Java提供的一种用于构建图形用户界面(GUI)的工具包,它允许开发者创建丰富的交互式应用。下面将详细...
QQ连连看辅助源码,一次消去一对方格或一键秒杀
【JS连连看游戏,QQ连连看】是一款基于JavaScript、HTML和CSS开发的在线游戏,它模仿了QQ游戏中心的经典连连看玩法。这款游戏的核心是利用JavaScript的事件处理、DOM操作以及数组算法来实现游戏逻辑,而HTML则构建了...
QQ连连看是一款深受玩家喜爱的经典休闲游戏,而“QQ连连看辅助工具java实现”则是一个专为此游戏设计的辅助程序,由Java编程语言编写,并利用JNI(Java Native Interface)技术来实现。本文将深入探讨这个工具的核心...
连连看是一款广受欢迎的休闲益智游戏,其FLEX版本是使用Adobe的Flex技术进行开发的。Flex是一种基于...通过深入理解这些技术,开发者不仅可以制作连连看游戏,还可以进一步开发其他类型的富互联网应用程序。
QQ连连看是一款经典的休闲益智游戏,其源码对于初学者和游戏开发者而言,是一个非常有价值的参考资料。通过学习和分析单机版QQ连连看的源码,我们可以深入了解游戏开发的基本流程,以及涉及到的关键技术。 首先,...