| Profilo di NowCan老侃研究院微软分院BlogElenchiAmici | Guida |
|
|
25/11/2008 QQ游戏-大家来找茬之自动找茬近来在玩QQ游戏之大家来找茬,游戏我就不介绍了,就是找出两幅图中的五处不同点。可是我的水平太差,很快积分变成负数。一气之下,截图,分析,准备做计算机辅助找茬工具。 分析截图,得出结论,该游戏设计比较简单,每次出现的两幅图,其Y坐标一直不变,但X坐标会随机变化,不变化过范围不大。图像比较则更简单,只要两幅图直接异或,相同部分就是黑色(0),不同处则不为黑色(非0).因此关键在于找出两幅图的X坐标。 进一步分析,找X坐标也不难,因游戏的背景图案一直是不变的,一种淡紫色,沿着Y方向渐变,但X方向上不变,大小固定为800X600像素,同时,两幅图的大小也是定值,这为找出两幅图的X坐标提供了很大的便利。只要取得X=5处的颜色值(之所以从5开始,是因为背景图案最边上几个点颜色是黑色的),记录下来,然后向右扫描,直到遇到一个不同颜色的点,该处即为左图的X坐标。同样方法可以找到右图的X坐标。剩下的事情就是取得两图每个点的颜色值,异或即得差异部分。 原理就这么简单,核心代码也就20行左右。利用这个程序,针对这个游戏,可以在2秒之内找出五个不同点并显示。如果再加上自动点击的功能,基本可以打败99%的玩家了,还有1%的玩家打不赢,因为用了同样的助手工具,哈哈。 鼠标自动点击,这看起来很容易,其实还是有点难度的,两幅图异或后,不同部分一般都是离散的点,要找出五处不同点的位置,其实并不容易。这个就请读者想想办法了,呵呵。 23/07/2007 我从编程中悟出八个字【转】我从编程中悟出八个字:1专 2静 3谦 4筹 5悟 6慎 7透 8恒 [Microsoft777 ]
1"忽如一夜春风来,千树万树梨花开."现在的技术百花齐放,切忌不可贪. 不要盲目的追求新技术,唯有算法才是灵魂. 2"非淡泊无以明志,非宁静无以致远."要想达到高的境界,必须能够心静. 年轻的程序员都很浮躁,这一点对于他们来说尤为的重要. 3谦不仅指技术,而且还指人.一门实用的技术,无论多么容易掌握.只要你 深入的研究,都会挖掘出很多新东西来.对于人来讲,你可能会就某些方面向 其他人请教.如果你不谦虚,请教的结果肯定会不很理想. 4"凡事预则利,不预则废."在编程的过程中,如果你没有做好事前的分析工 作. 8做技术一定要一颗恒心,这样才不会半途而废. 你会发现自己慢慢就会陷入思维混乱中,最终导致失败.当你把一切都筹划 好,那种"运筹帷幄决胜于千里之外"的感觉多爽啊! 5程序中蕴含着很多的道理,唯有大彻大悟者方能体会其中的奥妙. 6内存无论在怎么发展,它都会有一个容量的限制.因此你应该堤防着它. 你的程序如果导致内存泄漏,是程序员很可耻的事情. 7对于问题的理解,一定要透彻.这样你才能实质的解决问题. 8做技术一定要一颗恒心,这样才不会半途而废.
26/01/2007 TCP连接非正常断开的检测(KeepAlive探测)此处的”非正常断开”指TCP连接不是以优雅的方式断开,如网线故障等物理链路的原因,还有突然主机断电等原因 有两种方法可以检测:1.TCP连接双方定时发握手消息 2.利用TCP协议栈中的KeepAlive探测 第二种方法简单可靠,只需对TCP连接两个Socket设定KeepAlive探测,所以本文只讲第二种方法在Linux,Window2000下的实现(在其它的平台上没有作进一步的测试) Windows 2000平台下 //定义结构及宏 struct TCP_KEEPALIVE { u_longonoff; u_longkeepalivetime; u_longkeepaliveinterval; } ; #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
//KeepAlive实现
TCP_KEEPALIVE inKeepAlive = {0}; //输入参数 unsigned long ulInLen = sizeof(TCP_KEEPALIVE); TCP_KEEPALIVE outKeepAlive = {0}; //输出参数
unsigned long ulOutLen = sizeof(TCP_KEEPALIVE); unsigned long ulBytesReturn = 0;
//设置socket的keep alive为5秒,并且发送次数为3次
inKeepAlive.onoff = 1; inKeepAlive.keepaliveinterval = 5000; //两次KeepAlive探测间的时间间隔 inKeepAlive.keepalivetime = 5000; //开始首次KeepAlive探测前的TCP空闭时间 if (WSAIoctl((unsigned int)s, SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive, ulInLen, (LPVOID)&outKeepAlive, ulOutLen, &ulBytesReturn, NULL, NULL) == SOCKET_ERROR) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) \WSAIoctl failed. error code(%d)!\n"),WSAGetLastError())); } Linux平台下
#include …… ////KeepAlive实现 //下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口 int keepAlive = 1;//设定KeepAlive int keepIdle = 5;//开始首次KeepAlive探测前的TCP空闭时间 int keepInterval = 5;//两次KeepAlive探测间的时间间隔 int keepCount = 3;//判定断开前的KeepAlive探测次数 if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)
{ ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) setsockopt SO_KEEPALIVE error!\n"))); }
if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1)
{ ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPIDLE error!\n"))); } if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1)
{ ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPINTVL error!\n"))); } if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1)
{ ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t)setsockopt TCP_KEEPCNT error!\n"))); } 16/01/2007 图象缩放算法最邻近插值(近邻取样法): 最临近插值的的思想很简单。对于通过反向变换得到的的一个浮点坐标,对其进行简单的取整,得到一个整数型坐标,这个整数型坐标对应的像素值就是目的像素的像素值,也就是说,取浮点坐标最邻近的左上角点(对于DIB是右上角,因为它的扫描行是逆序存储的)对应的像素值。可见,最邻近插值简单且直观,但得到的图像质量不高。 双线性内插值:
对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v),其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即: f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
其中f(i,j)表示源图像(i,j)处的的像素值,以此类推
这就是双线性内插值法。双线性内插值法计算量大,但缩放后图像质量高,不会出现像素值不连续的的情况。由于双线性插值具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊 三次卷积法能够克服以上两种算法的不足,计算精度高,但计算量大,他考虑一个浮点坐标(i+u,j+v)周围的16个邻点,目的像素值f(i+u,j+v)可由如下插值公式得到:
f(i+u,j+v) = [A] * [B] * [C]
[A]=[ S(u + 1) S(u + 0) S(u - 1) S(u - 2) ]
┏ f(i-1, j-1) f(i-1, j+0) f(i-1, j+1) f(i-1, j+2) ┓
[B]=┃ f(i+0, j-1) f(i+0, j+0) f(i+0, j+1) f(i+0, j+2) ┃ ┃ f(i+1, j-1) f(i+1, j+0) f(i+1, j+1) f(i+1, j+2) ┃ ┗ f(i+2, j-1) f(i+2, j+0) f(i+2, j+1) f(i+2, j+2) ┛ ┏ S(v + 1) ┓
[C]=┃ S(v + 0) ┃ ┃ S(v - 1) ┃ ┗ S(v - 2) ┛ ┏ 1-2*Abs(x)^2+Abs(x)^3 , 0<=Abs(x)<1
S(x)=┃ 4-8*Abs(x)+5*Abs(x)^2-Abs(x)^3 , 1<=Abs(x)<2 ┗ 0 , Abs(x)>=2 S(x)是对 Sin(x*Pi)/x 的逼近(Pi是圆周率——π) 最邻近插值(近邻取样法)、双线性内插值、三次卷积法 等插值算法对于旋转变换、错切变换、一般线性变换 和 非线性变换 都适用。
--------------------------------------------------------------------------------
补充: 一、对于24位DIB,需要分别对RGB分量进行处理; 二、对于f(x,y)中没有对应值的坐标,应该用最邻近坐标的值(比如f(-1,-1)用f(0,0)的值)。 28/11/2006 谁能看明白这个程序是做什么的?/* ========================================================= This Plays the game of reversi (Othello)! Compile and run. It then asks for a playing level. Enter 0-10 (easy-hard). It then asks for your move. A move is a number within 11-88, or a 99 to pass. Illegal moves (except for an illegal pass) are rejected. Then the computer does its move (or a 0 to pass), until the board is full. It plays rather well, for such a small program! Lievaart had to leave out the board printing routine, so you'll have to take a real game board to play it. ... Also due to space-limitations (the rules for 1987 had a limit of 1024 byes), Lievaart took out the passing-handler, which makes its ending-game rather poor. But further it knows all the rules, uses alpha-beta pruning, and it plays f.i. on mobility(!). Most important: it can play a pretty good game of Reversi! The Author was kind enough to supply the fully functional version of the program. The file lievaart2.c contains what the program would have been without the size restriction. This version has the full end game logic and displays the board after each move! [the code above is this slightly larger but better version] Copyright (c) 1987, Landon Curt Noll & Larry Bassel. All Rights Reserved. Permission for personal, educational or non-profit use is granted provided this this copyright and notice are included in its entirety and remains unaltered. All other uses must receive prior permission in writing from both Landon Curt Noll and Larry Bassel. ========================================================= */ //#define D define #define Y return #define R for #define e while #define I printf #define l int #define W if #define C y=v+111;H(x,v)*y++= *x #define H(a,b)R(a=b+11;a<b+89;a++) #define s(a)t=scanf("%d",&a) #define U Z I #define Z I("123\ 45678\n");H(x,V){putchar(".XO"[*x]);W((x-V)%10==8){x+=2;I("%d\n",(x-V)/10-1);}} l V[1600],u,r[]={-1,-11,-10,-9,1,11,10,9},h[]={11,18,81,88},ih[]={22,27,72,77}, bz,lv=60,*x,*y,m,t;S(d,v,f,_,a,b)l*v;{l c=0,*n=v+100,j=d<u-1?a:-9000,w,z,i,g,q= 3-f;W(d>u){R(w=i=0;i<4;i++)w+=(m=v[h[i]])==f?300:m==q?-300:(t=v[ih[i]])==f?-50: t==q?50:0;Y w;}H(z,0){W(E(v,z,f,100)){c++;w= -S(d+1,n,q,0,-b,-j);W(w>j){g=bz=z; j=w;W(w>=b||w>=8003)Y w;}}}W(!c){g=0;W(_){H(x,v)c+= *x==f?1:*x==3-f?-1:0;Y c>0? 8000+c:c-8000;}C;j= -S(d+1,n,q,1,-b,-j);}bz=g;Y d>=u-1?j+(c<<3):j;}main(){R(;t< 1600;t+=100)R(m=0;m<100;m++)V[t+m]=m<11||m>88||(m+1)%10<2?3:0;I("Level:");V[44] =V[55]=1;V[45]=V[54]=2;s(u);e(lv>0){Z do{I("You:");s(m);}e(!E(V,m,2,0)&&m!=99); W(m!=99)lv--;W(lv<15&&u<10)u+=2;U("Wait\n");I("Value:%d\n",S(0,V,1,0,-9000,9000 ));I("move: %d\n",(lv-=E(V,bz,1,0),bz));}}E(v,z,f,o)l*v;{l*j,q=3-f,g=0,i,w,*k=v +z;W(*k==0)R(i=7;i>=0;i--){j=k+(w=r[i]);e(*j==q)j+=w;W(*j==f&&j-w!=k){W(!g){g=1 ;C;}e(j!=k)*((j-=w)+o)=f;}}Y g;} |
|
|