C语言从零起步分析《象眼》象棋引擎的源码(18)
接下来分析象的下法合理性判断:程序代码:
case PIECE_BISHOP://象 return SAME_HALF(sqSrc, sqDst) && BISHOP_SPAN(sqSrc, sqDst) && ucpcSquares[BISHOP_PIN(sqSrc, sqDst)] == 0;
走法是否符合相(象)的步长inline BOOL BISHOP_SPAN(int sqSrc, int sqDst) { return ccLegalSpan[sqDst - sqSrc + 256] == 3;}
BISHOP_SPAN这个函数也已经分析过了;
函数SAME_HALF:起点和终点 没有过河为TRUE 过河为FALSE
// 是否在河的同一边 inline BOOL SAME_HALF(int sqSrc, int sqDst) { return ((sqSrc ^ sqDst) & 0x80) == 0; }
我们来学习一下基础知识吧:
“异或”运算符(^)用法:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1);
十六进制,以0x开头,比如0x7a;
八进制,以0开头,比如030;
0x80==128==二进制10000000;
也就是说,当二进制两者第8位不同,(sqSrc ^ sqDst) 的第8位为1,则((sqSrc ^ sqDst) & 0x80)!=0;
第8位代表什么?
0--127,的第8位为0,128--255的第8位为1;
也就是说,过河,不过河,分界,就是对半分的;
0--255当小于128时,第8位为0,否则为1;这样就可以判断:是否在河的同一边;
关于过河的更多讨论,在------C语言从零起步分析《象眼》象棋引擎的源码(21)
函数BISHOP_PIN:相(象)眼的位置
程序代码:
// 相(象)眼的位置 inline int BISHOP_PIN(int sqSrc, int sqDst) { return (sqSrc + sqDst) >> 1; }
即(sqSrc + sqDst) \2;
当其他条件符合,即不过河并且走了田字则;
设起点为x,差为a;
(起点+终点)\2=(x+x+a)\2=x+a\2;
也就是起点+位移差\2;
这个位移差,是个田字,为16*2+2,或者16*2-2,或者-16*2+2,或者-16*2-2;
位移差\2则为16+1,16-1,-16+1,-16-1;
总之,水平方向隔着1格,同时,垂直方向隔着1格;
ucpcSquares[BISHOP_PIN(sqSrc, sqDst)] == 0
则是说这个象眼没有子;
return (sqSrc + sqDst) >> 1,这个得数不可能为负数,也不会大于255;
因此不会数组下标越界。
好难呀,考数学呢?
[此贴子已经被作者于2016-3-28 10:33编辑过]