C/C++游戏辅助基础05之QQ连连看辅助的功能实现

数据我们已经获取到了,接下来没有什么能阻止我们实现外挂了~

我们先在我们的游戏中,定义一个[11][19]的byte类型数组用以存储数据

bytem_szGameData[11][19];

然后再写一个ReadGameData()函数用以读取数据

boolCKyodaiPluginDlg::ReadGameData()

{

HWNDhGameWnd=GetGameHwnd();

ZeroMemory(m_szGameData,11*19);

if(!hGameWnd)

{

returnfalse;

}

DWORDdwPid=false;

GetWindowThreadProcessId(hGameWnd,dwPid);

HANDLEhGameProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPid);

if(!hGameProcess)

{

MessageBox(L”打开进程失败”);

returnfalse;

}

if(!ReadProcessMemory(hGameProcess,(LPVOID)0x00199F68,m_szGameData,sizeof(m_szGameData),NULL))

{

returnfalse;

}

}

接下来就是要怎么消除的问题了,如下图,是否可以消除无非就是三种情况,两个在同一条线上,这也就一条线可以消除,要要门就是2条线段可以消除,最多只能有3条线



我们要判断x1,y1x2,y能否消除我们要先构建2个点x3y3,x4y4如果x1y1能到达x3y3(也就是说他们直接的数据都是0)并且x3y3能到达x4y4并且x2y2能到达x4y4则可以消除


//判断两个点之间是不是连通的

boolCLLK_WGDlg::LineIsNull(intnRow,intnCol,intnRow2,intnCol2)

{

if(nRow2==nRownCol2!=nCol)

{

intnColMax=max(nCol2,nCol);

intnColMin=min(nCol2,nCol);

for(inty=nColMin;y=nColMax;y++)

{

if(m_szGameData[nRow][y]!=0)

{

returnfalse;

}

}

returntrue;

}

elseif(nCol==nCol2nRow!=nRow2)

{

intnRowMin=min(nRow,nRow2);

intnRowMax=max(nRow,nRow2);

for(intx=nRowMin;x=nRowMax;x++)

{

if(m_szGameData[x][nCol]!=0)

{

returnfalse;

}

}

returntrue;

}

elseif(nRow2==nRownCol2==nCol)//2点为同一点的情况

{

returntrue;

}

else

{

returnfalse;

}

returntrue;

}

boolCLLK_WGDlg::IsClear(intnRow,intnCol,intnRow2,intnCol2)

{

//先把两个点的数据拿出来

bytedata1=m_szGameData[nRow][nCol];

bytedata2=m_szGameData[nRow2][nCol2];

//把两个点的数据置0是为了两个贴在一起的能消除

m_szGameData[nRow][nCol]=0;

m_szGameData[nRow2][nCol2]=0;

intnTmpRow1=nRow;

intnTmpRow2=nRow2;

for(intnTmpCol=0;nTmpCol19;nTmpCol++)

{

if(LineIsNull(nTmpRow1,nTmpCol,nTmpRow2,nTmpCol)LineIsNull(nTmpRow1,nTmpCol,nRow,nCol)LineIsNull(nTmpRow2,nTmpCol,nRow2,nCol2))

{

m_szGameData[nRow][nCol]=data1;

m_szGameData[nRow2][nCol2]=data2;

returntrue;

}

}

intnTmpCol1=nCol;

intnTmpCol2=nCol2;

for(intnTmpRow=0;nTmpRow11;nTmpRow++)

{

if(LineIsNull(nTmpRow,nTmpCol1,nTmpRow,nTmpCol2)LineIsNull(nTmpRow,nTmpCol1,nRow,nCol)LineIsNull(nTmpRow,nTmpCol2,nRow2,nCol2))

{

m_szGameData[nRow][nCol]=data1;

m_szGameData[nRow2][nCol2]=data2;

returntrue;

}

}

m_szGameData[nRow][nCol]=data1;

m_szGameData[nRow2][nCol2]=data2;

returnfalse;

}

我们再添加一个函数ClearOne用于消除一对

voidCKyodaiPluginDlg::ClearOne()

{

ReadGameData();

for(intnRow=0;nRow11;nRow++)

{

for(intnCol=0;nCol19;nCol++)

{

if(m_szGameData[nRow][nCol]==0)

{

continue;

}

for(intnRow2=0;nRow211;nRow2++)

{

for(intnCol2=0;nCol219;nCol2++)

{

if((nRow2!=nRow||nCol2!=nCol)m_szGameData[nRow][nCol]==m_szGameData[nRow2][nCol2]IsClear(nRow,nCol,nRow2,nCol2))

{

SelectChess(nRow,nCol);

SelectChess(nRow2,nCol2);

return;

}

}

}

}

}

}

clearOne中如果判断可以消除则调用SelectChess

可以消的算法有了,我们双击单消按钮,然后添加代码如下

voidCKyodaiPluginDlg::SelectChess(intnRow,intnCol)

{

HWNDhGameWnd=GetGameHwnd();

if(hGameWnd)

{

intnPosXBase=5;

intnPosYBase=165;

intxPos=(nCol+1)*30+nPosXBase;

intyPos=(nRow+1)*35+nPosYBase;

::PostMessage(hGameWnd,WM_LBUTTONDOWN,0,MAKELPARAM(xPos,yPos));

::PostMessage(hGameWnd,WM_LBUTTONUP,0,MAKELPARAM(xPos,yPos));

}

}

上面代码中5,165是第一个图片的位置,30,35是每一格图片的大小

接着,我们在按钮消除一对的响应函数中增加如下调用一下ClearOne

//消除一对

voidCKyodaiPluginDlg::OnBnClickedBtnremove()

{

ClearOne();

}

QQ连连看写辅助系列每篇都有源代码,若想获取源代码请私信我。

发布于 2025-01-08
191
目录

    推荐阅读