C语言从零起步分析《象眼》象棋引擎的源码(17)
接下来分析第3部分:根据棋子的类型检查走法是否合理
程序代码:
// 3. 根据棋子的类型检查走法是否合理
switch (pcSrc - pcSelfSide) {
//pcSrc - pcSelfSide//目前是轮到红方走,pcSelfSide =8,轮到黑方走,pcSelfSide =16;
//红子8----14:帅士象马车炮兵//黑子16----22:将士象马车炮卒
//(pcSrc - pcSelfSide)=[红子帅0士1象2马3车4炮5兵6]=[黑子将0士1象2马3车4炮5卒6]
// 棋子编号
//const int PIECE_KING = 0;
//const int PIECE_ADVISOR = 1;
//const int PIECE_BISHOP = 2;
//const int PIECE_KNIGHT = 3;
//const int PIECE_ROOK = 4;
//const int PIECE_CANNON = 5;
//const int PIECE_PAWN = 6;
//即:(pcSrc - pcSelfSide)对应着棋子编号;
将或帅:
程序代码:
case PIECE_KING://将或帅
return IN_FORT(sqDst) && KING_SPAN(sqSrc, sqDst);
//sqDst走法的终点;sqSrc走法的起点;
函数IN_FORT:判断棋子是否在九宫中
程序代码:
// 判断棋子是否在九宫中
inline BOOL IN_FORT(int sq) {
return ccInFort[sq] != 0;//ccInFort[]// 判断棋子是否在九宫的数组
}
数组ccInFort:
程序代码:
// 判断棋子是否在九宫的数组
static const char ccInFort[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
以上的一看就明白,因为已经图形化了;什么时候,俺自己开发一套图形化的编程工具去,让图形生成代码,你们就可以享福了
函数KING_SPAN:走法是否符合帅(将)的步长
程序代码:
// 走法是否符合帅(将)的步长
inline BOOL KING_SPAN(int sqSrc, int sqDst) {
return ccLegalSpan[sqDst - sqSrc + 256] == 1;//ccLegalSpan// 判断步长是否符合特定走法的数组,1=帅(将),2=仕(士),3=相(象)
}
数组ccLegalSpan:
程序代码:
// 判断步长是否符合特定走法的数组,1=帅(将),2=仕(士),3=相(象)
static const char ccLegalSpan[512] = {
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0
};
这个图形看上去就蒙了
sqDst - sqSrc + 256
0+256,刚好在中心点处----0,
如果位移差(
纵或者横)(0,1)或(1,0)指向了1,则会返回1,
推演:斜位移差为(1,1),则返回2;斜(2,2)则返回3;
所以,这个数组适合三种子的下法合理性判断;
1=帅(将),2=仕(士),3=相(象)
总结一下
return IN_FORT(sqDst) && KING_SPAN(sqSrc, sqDst);的意思:
当目标点在九宫范围之内 并且 移动棋子的位移差返回的字==1 时,将帅的下法合理;
士就无需分析了,哈哈:
case PIECE_ADVISOR://士
return IN_FORT(sqDst) && ADVISOR_SPAN(sqSrc, sqDst);
程序代码:
// 走法是否符合仕(士)的步长
inline BOOL ADVISOR_SPAN(int sqSrc, int sqDst) {
return ccLegalSpan[sqDst - sqSrc + 256] == 2;
}
[此贴子已经被作者于2016-3-27 17:33编辑过]