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

如果你还没有看完本blog的上篇,建议您先看完上篇!!

第一代辅助如何死的?

我们先来看四张图

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

如上方最左图所示,前面是一个小圆柱子,看起来很人畜无害似不似??

由于上一步跳出了偏差,并没有跳在正中心,导致该扫描的位置未被扫描,如上方第二幅图所示。(上方右图绿色部分为被作为关键点的部分)

我们把log翻到上一次,发现位置的判断正常,但因不明原因跳偏,跳偏的原因至今不明.....

为防止再次出锅,我写了第二个版本的代码....

显然,要修改判定机制

一眼扫过去,就会发现扫描的范围过窄,显然要增大被扫描的范围....

如果单纯这么修改,依然会出锅,简单地来说,就是依然存在扫描到柱子侧面的可能,导致再次出锅。

通过进一步的测试,我发现跳一跳的方块具有此类奇特性质:

除了棕色带数字433的方块,及木凳子方块外,在确定方块正面后,以该面频数最高颜色作为匹配色,求出所有颜色与匹配色相同的点的平均坐标,即为下一个方块的中心点:

此处说明一下,挂掉的那根柱子侧面并非完全同色

如图所示:

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

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

绿色部分的正中间的那个红点即为计算出的落点。

通过该判断机制,在未启用白点判断的情况下,实现了连续30次命中中心点。

如何判定方块正面

启初,我根据已有的几千张图片进行了分析,发现若不进行专门的顶部判定,仅通过上述方式进行判定,也是可以找到准确找到方块中心点的。

码了出来,挂着去吃了顿饭,回来发现在8200+时死掉了....

通过分析log,事实证明我凸漾...   如图所示:

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

由于上图用的是经过优化的算法,并没有抓偏移。若仅采用上述的判定机制,由于两图红色标记部分面积均大于绿色部分,会出现算错目标落点的情况。

考虑如何进行优化。

不难发现,相对于方块侧面,方块正面与棋子的距离会更远一些,故在计算频数时,我们考虑对每个点赋予一个权值,该权值与计算点至棋子中心点间距呈线性关系(目前采用的是k=1),求出该颜色后,作为匹配色,求出所有颜色与匹配色完全相同的点的平均坐标,作为目标点。

然后就可以了(没错就这么简单)

求目标点的代码:

     mp.clear(); Xsum.clear(); Ysum.clear();
if(chessY<= ){//第二代扫描
for(int i=chessY+;i<=P.m;i++){
int j=chessX-(i-chessY)*tan30;
for(int jj=-;jj<=;jj++){
int R=P.r[j+jj][i],G=P.g[j+jj][i],B=P.b[j+jj][i];
if(R==&&G==&&B==) continue;
if(R==&&G==&&B==) continue;
int J=j+jj,I=i;
node id=node(R,G,B);
int add=getQZ(chessX-J);
mp[id]+=add; Xsum[id]+=J*add; Ysum[id]+=I*add;
}
}
}else{
for(int i=chessY-;i;i--){
int j=chessX-(chessY-i)*tan30;
for(int jj=-;jj<=;jj++){
int R=P.r[j+jj][i],G=P.g[j+jj][i],B=P.b[j+jj][i];
if(R==&&G==&&B==) continue;
if(R==&&G==&&B==) continue;
int J=j+jj,I=i;
node id=node(R,G,B);
int add=getQZ(chessX-J);
mp[id]+=add; Xsum[id]+=J*add; Ysum[id]+=I*add;
}
}
}
printf("siz=%d\n",mp.size());
if(mp.size()>){
wave2();
return ;
}
map<node,int>::iterator it,itX,itY,maxn;
it=maxn=mp.begin();
itX=Xsum.begin();
itY=Ysum.begin();
while(it!=mp.end()){
int sum1=it->second,sum2=maxn->second;
if(sum1>sum2)
maxn=it;
it++;
itX++;
itY++;
}
int sumX=Xsum[maxn->first];
int sumY=Ysum[maxn->first];
int cnt=maxn->second;
sumX/=cnt; sumY/=cnt;//已经确定目标点

如何确定另外两种特殊情况并作出反应

不难发现,那两种方块比较花,说白了,就是颜色的种类较多。

通过多次测试,令阈值为3000,若颜色种类低于阈值,则采用上述判定机制直接进行判定,否则直接采用第一代判定机制(是不是很机智【learning】微信跳一跳辅助c++详解 轻松上万 【下】

在统计颜色数量孰多前,先进行白点检测,若检测到白点则直接跳白点即可。

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

(上图在测试主算法的可靠性,故没有启用抓白点)

然而...

尽管新的算法看起来极其优秀(实际测试中其实就是),截止目前尚未出现因算法本身而导致死亡的锅,但现实中,受限于电脑性能的不稳定性,按压时间会出现偏差,导致跳偏甚至跳死的现象,至今无解...(考虑回广州后用性能更强的电脑跑一下)

二代辅助目前历史记录为37244,尚未破一代记录。

理论上,在无卡顿的电脑上,二代辅助可实现99999。

不过,我还有一些其他的方法可以实现99999,比如游戏原始方块信息采集+AE渲染,渲染1分钟,实现5个9,看起来还天衣无缝哦~(逃)

全文终

代码如下(由于里面有一代的代码故很长请不要吐槽)

 #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,Xsum,Ysum;
int chessX,chessY;//棋子的x,y坐标
int TX,TY; int cmpspecial(char c[],int px,int py,int eps){//判断所有特殊的东西,包括白点,椅子等
CAP.readfile(c);
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){
minn=sum,maxx=i,maxy=j;
//break;
}
}
if(minn<=eps){
printf("catch %s\n",c);
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+py; TY=maxx+px;
P.r[TX][TY]=; P.g[TX][TY]=P.b[TX][TY]=;
// P.outfile("test.bmp");
return ;
}else return ;
} int getQZ(int x){
return x;
} int lineR[]={},lineG[]={},lineB[]={},X[]={},Y[]={};
int wave2(){//专门处理椅子和其他东西的
printf("find chess or 433day\n");
memset(X,,sizeof(X)); memset(Y,,sizeof(Y));
memset(lineR,,sizeof(lineR)); memset(lineG,,sizeof(lineG)); memset(lineB,,sizeof(lineB));
//loop:;
int cnt=;
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]=;
}
}
JumpepsR=JumpepsG=JumpepsB=;
//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 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("st1152.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; if(cmpspecial("000white.bmp",,,)) return ; //loop:;
mp.clear(); Xsum.clear(); Ysum.clear();
if(chessY<= ){//第二代扫描
for(int i=chessY+;i<=P.m;i++){
int j=chessX-(i-chessY)*tan30;
for(int jj=-;jj<=;jj++){
int R=P.r[j+jj][i],G=P.g[j+jj][i],B=P.b[j+jj][i];
if(R==&&G==&&B==) continue;
if(R==&&G==&&B==) continue;
int J=j+jj,I=i;
node id=node(R,G,B);
int add=getQZ(chessX-J);
mp[id]+=add; Xsum[id]+=J*add; Ysum[id]+=I*add;
}
}
}else{
for(int i=chessY-;i;i--){
int j=chessX-(chessY-i)*tan30;
for(int jj=-;jj<=;jj++){
int R=P.r[j+jj][i],G=P.g[j+jj][i],B=P.b[j+jj][i];
if(R==&&G==&&B==) continue;
if(R==&&G==&&B==) continue;
int J=j+jj,I=i;
node id=node(R,G,B);
int add=getQZ(chessX-J);
mp[id]+=add; Xsum[id]+=J*add; Ysum[id]+=I*add;
}
}
}
printf("siz=%d\n",mp.size());
if(mp.size()>){
wave2();
return ;
}
map<node,int>::iterator it,itX,itY,maxn;
it=maxn=mp.begin();
itX=Xsum.begin();
itY=Ysum.begin();
while(it!=mp.end()){
int sum1=it->second,sum2=maxn->second;
if(sum1>sum2)
maxn=it;
it++;
itX++;
itY++;
}
int sumX=Xsum[maxn->first];
int sumY=Ysum[maxn->first];
int cnt=maxn->second;
sumX/=cnt; sumY/=cnt;//已经确定目标点
node hh=maxn->first; if(chessY<= ){//第二代采用密集的扫描
for(int i=chessY+;i<=P.m;i++){
int j=chessX-(i-chessY)*tan30;
for(int jj=-;jj<=;jj++){
int R=P.r[j+jj][i],G=P.g[j+jj][i],B=P.b[j+jj][i];
if(R!=hh.r||G!=hh.g||B!=hh.b) continue;
P.r[j+jj][i]=; P.g[j+jj][i]=; P.b[j+jj][i]=;
}
}
}else{
for(int i=chessY-;i;i--){
int j=chessX-(chessY-i)*tan30;
for(int jj=-;jj<=;jj++){
int R=P.r[j+jj][i],G=P.g[j+jj][i],B=P.b[j+jj][i];
if(R!=hh.r||G!=hh.g||B!=hh.b) continue;
P.r[j+jj][i]=; P.g[j+jj][i]=; P.b[j+jj][i]=;
}
}
}
loop:;
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=%dpixels\n",he);
me(); s(he*2.55); me();
s();
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);
} }
上一篇:32位的CPU最多只能支持最大到4GBytes的内存


下一篇:【solr专题之三】Solr常见异常