C++连连看外挂
自己写的一个鼠键模拟点击屏幕上的具体坐标的小玩意儿..
/***********************************************************************************************
算法设计
1.读取更新的棋盘数据
2.遍历棋盘数据 找到相同的棋子
3.判断两点是否能消除
4.如果能消除
5.那么就模拟鼠标点击这两个点
************************************************************************************************/
bool ClearChess(){ //读取更新棋盘数据byte chess[11][19] 模式 a[y][x] Updatchess(); //进行遍历找到相同的两个点 POINT m_ponit1, m_ponit2; //临时变量 int x1, y1, x2, y2; for (y1 = 0; y1 < 11; y1++) for(x1 = 0; x1 < 19; x1++) { for (y2 = y1; y2 < 11; y2++) for(x2 = 0; x2 < 19; x2++) { //判断两个点是否相同 if ((chess[y1][x1] == chess[y2][x2])&&(!((x1==x2)&&(y1==y2)))) { m_ponit1.x = x1; m_ponit1.y = y1; m_ponit2.x = x2; m_ponit2.y = y2; //检查两点是否可以消除 if(Check2p(m_ponit1,m_ponit2)) { //模拟点击相同的两点还没有实现的 Click2P(m_ponit1,m_ponit2); return true; } } } } return false; }
这是整体程序架构;其中的Check2p, Click2p是两个重要的函数;前者是检查两点棋子是否可以消除;如果可以消除就调用Clik2P它的作用就是模拟一次点击可以消除的这两颗棋子,具体代码如下:
/************************************************************************************************ 检查两点是否可以消除 桩模块 a、在这一对棋子间找相通路径的原理 b、(Check2p函数)框架代码 c、(CheckLine函数)检测2点是否有连通 LineNull(p1,p2); //是否在棋盘上 的2个点之前是否有一条全为0的直线,如有true,否则false 1、剪贴游戏图; Y坐标相同的情况下 p1,p2 lineNull(p1.right,p2.left) //可消除 X坐标相同的情况下 p1,p2 LineNull(p1.down,p2.up) //可消除 ************************************************************************************************/ bool Check2p(POINT a,POINT b) { CChessPoint p1(a),p2(b); POINT pa,pb;//转角点 int x,y; // 如果2点为同一点 则返回假 if ((a.x==b.x) && (a.y==b.y )) { return false;} else if ((chess[a.y][a.x]==0) || (chess[b.y][b.x]==0)) { return false;} else if (chess[a.y][a.x]!=chess[b.y][b.x]) { return false;} pa=a;pb=b; // 在横向一条线上 y坐标 相同 if (a.y==b.y) { // 2点在左右相邻 //问题所在 if ((p1.right.x==p2.pold.x) || (p1.left.x==p2.pold.x)) { return true; } //检测 这条线是否有一条路径相通 if (CheckLine(p1.right,p2.left )) {return true; } //检测 上下 //y 上 pa=a;pb=b; if ((p1.up.y >=0) && (p1.up.y<=10)) for ( y=0 ;y<=p1.up.y;y++) { pa.y=y;pb.y=y; if (CheckLine(pa,p1.up) && CheckLine(pb,p2.up ) && CheckLine(pa,pb)) { return true; } } // y下 pa=a;pb=b; if ((p1.down.y >=0)&& (p1.down.y <=10)) for ( y=p1.down.y;y<=10;y++) { pa.y=y;pb.y=y; if (CheckLine(pa,p1.down ) && CheckLine(pb,p2.down ) && CheckLine(pa,pb)) { return true; } } //检测 左右 因为 y轴相等,所以不存在左右路径 } else //纵向一条线 x 坐标 相同 if (a.x==b.x) { //x下上 相邻不 //???????????a //if ((p1.down.y==p2.up.y ) || (p1.up.y==p2.up.y)) if((p1.down.y==p2.pold.y ) || (p1.up.y==p2.pold.y)) //我在这里错过 { return true; } //检测 这条线是否有一条路径相通 if (CheckLine(p1.down,p2.up) ) { return true; } //检测 上下 国为x 轴相等 所以不存在路径 //检测 左右 //x左 pa=a;pb=b; for (x=0 ;x<=p1.left.x ;x++) { pa.x=x; pb.x=x; if (CheckLine(pa,p1.left) && CheckLine(pb,p2.left ) && CheckLine(pa,pb)) { return true; } } //x右 pa=a;pb=b; for (x=p1.right.x;x<=18;x++) { pa.x=x; pb.x=x; if (CheckLine(pa,p1.right ) && CheckLine(pb,p2.right ) && CheckLine(pa,pb)) { return true; } } } else //xy 坐标 都不相同 {{{{{{ { pa=a;pb=b; if (a.x>b.x) { // p2点 在 左 left // 找x轴路径 for (x=0;x<=p2.left.x;x++) { pa.x=x;pb.x=x; if (CheckLine(pa,p1.left) && CheckLine(pa,pb) && CheckLine(pb,p2.left)) {return true; } } // end for for (x=p2.right.x ;x<= p1.left.x;x++) { pa.x=x;pb.x=x; if (CheckLine(p2.right,pb) && CheckLine(pa,pb)&& CheckLine(pa,p1.left)) {return true; } } for (x=p2.right.x;x<=18;x++) { pa.x=x;pb.x=x; if (CheckLine(p1.right ,pa)&& CheckLine(p2.right ,pb) && CheckLine(pa,pb)) { return true; } } /////////////////yyyyyyyyyyyyyyyyyyyy 找y轴路径 由于是从上向下 搜索 所以p1.y>p2.y pa.x=a.x; pb.x=b.x; //初始化坐标 y渐变 for ( y=0 ;y<=p1.up.y;y++) //1段 { pa.y=y;pb.y=y; if (CheckLine(pb,pa) && CheckLine(pa,p1.up) && CheckLine(pb,p2.up)) { return true;} } //////////////////////// for (y=p1.down.y ;y<=p2.up.y;y++)//2段 { pa.y=y;pb.y=y; if (CheckLine(pb,pa)&& CheckLine(p1.down,pa) && CheckLine(pb,p2.up)) { return true; } } /////////////////////// for (y=p2.down.y ;y<=10 ;y++) //3段 { /////////////////////////////// pa.y=y;pb.y=y; if (CheckLine(pb,pa) && CheckLine(p1.down,pa) && CheckLine(p2.down,pb)) { return true; } } } else ////////////p2点 在 右 right a.x>b.x { pa.y=a.y; pb.y=b.y; //初始化坐标 for (x=0 ;x<= p1.left.x ;x++); { pa.x=x;pb.x=x; if (CheckLine(pa,pb)&& CheckLine(pa,p1.left)&& CheckLine(pb,p2.left)) { return true; } } ///////////////////// for (x=p1.right.x ;x<=p2.left.x;x++) { pa.x=x;pb.x=x; if (CheckLine(pa,pb)&& CheckLine(p1.right,pa)&& CheckLine(pb,p2.left)) { return true; } } /////////////////////// for (x=p2.right.x ;x<=18;x++) { pa.x=0;pb.x=x; if (CheckLine(pa,pb) && CheckLine(p1.right,pa)&& CheckLine(p2.right,pb)) {return true; } } ///////////////////////yyyyyyyyyyyyyyyyyy y轴渐变 pa.x =a.x; pb.x =b.x ; //初始化坐标 if ((p1.up.y>=0) && (p1.up.y<=10)) { for (y=0 ;y<=p1.up.y ;y++) //1段 { pa.y=y;pb.y=y; if (CheckLine(pa,pb)&& CheckLine(pa,p1.up) && CheckLine(pb,p2.up)) { return true; } } } ////// pa.x =a.x; pb.x =b.x ; //初始化坐标 if ((p1.down.y<=10) && (p2.up.y>=0)) { for (y=p1.down.y ;y<=p2.up.y;y++) //2段 { pa.y=y;pb.y=y; if (CheckLine(pa,pb)&& CheckLine(p1.down,pa) && CheckLine(pb,p2.up)) { return true; } } } //// pa.x =a.x; pb.x =b.x ; //初始化坐标 if (p2.down.y <=10) { for ( y=p2.down.y;y<=10;y++) //3段 { pa.y=y;pb.y=y; if (CheckLine(pa,pb) && CheckLine(p1.down,pa)&& CheckLine(p2.down ,pb)) { return true; } } } } } //xy 坐标 都不相同 }}}}}}}}} return false; }//Cick2p() end
在这里还自定义了一个类棋子类,它描述了它周围的棋子的坐标属性具体代码:
/********************************************************************************* 1.取出原点棋子四周的棋子坐标类 POINT pold; //当前的棋子坐标 POINT up; //当前的棋子坐标上面的棋子坐标 POINT down; //当前的棋子坐标下面面的棋子坐标 POINT left; //当前的棋子坐标左边的棋子坐标 POINT right;//当前的棋子坐标右边的棋子坐标 *********************************************************************************/ class CChessPoint { public: POINT pold; //当前的棋子坐标 POINT up; //当前的棋子坐标上面的棋子坐标 POINT down; //当前的棋子坐标下面面的棋子坐标 POINT left; //当前的棋子坐标左边的棋子坐标 POINT right;//当前的棋子坐标右边的棋子坐标 CChessPoint(POINT pxy); virtual ~CChessPoint(); }; //head file
View Code
1 CChessPoint::CChessPoint(POINT pxy) 2 { 3 //初始化 4 up=pxy; 5 down=pxy; 6 left=pxy; 7 right=pxy; 8 pold=pxy; 9 //四周棋子的某一个方向的坐标改变了 10 up.y=pxy.y-1; 11 down.y=pxy.y+1; 12 left.x=pxy.x-1; 13 right.x=pxy.x+1; 14 15 }
在此你还看见一个函数CheckLien()它是用来解决两点之间是否联通具体代码:
View Code
1 /************************************************************************ 2 //是否在棋盘上 的2个点之前是否有一条全为0的直线,如有true,否则false 3 这是两种特殊的情况 同一行 或 同一列 4 ************************************************************************/ 5 6 bool CheckLine(POINT p1,POINT p2) { 7 //定义循环变量 8 int x, y, t; 9 //1.当两个相同的点在一起的时候就返回true 10 if ((p1.x==p2.x)&&(p1.y==p2.y) && (chess[p1.y][p1.x]==0) && (chess[p2.y][p2.x]==0)) {return true; } 11 else 12 //判断是否是棋盘棋子的有效数据 13 if ((p1.x<0) || (p1.x>18) || (p1.y<0) || (p1.y>10) || 14 (p2.x<0) || (p2.x>18) || (p2.y<0) || (p2.y>10) ) {return false; } 15 16 if (p1.y == p2.y) //当y相等的时候就遍历以x做为循环变量 同行 17 { 18 if (p1.x>p2.x) 19 { 20 t=p1.x; 21 p1.x=p2.x; 22 p2.x=t; 23 } 24 for (x = p1.x; x <= p2.x; x++) 25 { 26 if((chess[p1.y][x])!=0) { return false; } 27 } 28 29 } 30 31 if (p1.x == p2.x)//当x相同的时候就遍历以y做为循环变量 同列 32 { 33 if (p1.y>p2.y) 34 { 35 t=p1.y; 36 p1.y=p2.y; 37 p2.y=t; 38 } 39 for (y = p1.y; y <= p2.y; y++) 40 { 41 if((chess[y][p1.x])!=0) { return false; } 42 } 43 44 } 45 46 return true; 47 }
接下来就是Click2p()函数:
View Code
1 /************************************************************************************************ 2 模拟点击相同的两点 桩模块 3 就是一个单一的动作就是模拟点击两点 4 5 ************************************************************************************************/ 6 bool Click2P(POINT p1,POINT p2){ 7 //点击p1 8 HWND hwnd=FindWindow(NULL,gamecaption); 9 int lparam; 10 lparam=((p1.y*35+192)<<16)+(p1.x*31+21); 11 SendMessage(hwnd,WM_LBUTTONDOWN,0,lparam); 12 SendMessage(hwnd,WM_LBUTTONUP,0,lparam); 13 //点击p2 14 lparam=((p2.y*35+192)<<16)+(p2.x*31+21); 15 SendMessage(hwnd,WM_LBUTTONDOWN,0,lparam); 16 SendMessage(hwnd,WM_LBUTTONUP,0,lparam); 17 return true; 18 }