上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
4.3 产生一个局面的全部走法
遍历整个有效棋盘,找出当前走棋一方的棋子,然后计算出每一棋子可能的走法,就得到一个局面的全部走法。
算法4-8:生成一个局面的全部走法
输入:棋盘数组 输出:当前局面的所有走法 1 行变量i=3 to 12 2 列变量j=3 to 11 对应一维数组下标p = i<<4+j pc为p位置对应的棋子 如果pc为对方棋子,或者p位置已出界,则 返回第2步 否则: Switch( pc ): Case帅:调用帅的走法生成函数 Case仕:调用仕的走法生成函数 Case相:调用相的走法生成函数 Case马:调用马的走法生成函数 Case车:调用车的走法生成函数 Case炮:调用炮的走法生成函数 Case兵:调用兵的走法生成函数
为遍历棋盘,采用了两重循环从上至下依次访问90个位置。
程序代码
void GenAllMove() { short i, j; unsigned char p; //p:棋子位置 int SideTag; //走棋方,红方16,黑方32 SideTag = 16 + side * 16; for(i=3; i<13; i++)//10行 { for(j=3; j<12; j++) //9列 { p=(i<<4)+j; //棋子位置 if( !(board[p] & SideTag)) //对方的棋子 continue; switch(board[p] - SideTag) { case 0: //帅 KingMove(p); break; case 1: //仕 case 2: AdvisorMove(p); break; case 3: //相 case 4: BishopMove(p); break; case 5: //马 case 6: KnightMove(p); break; case 7: //车 case 8: RookMove(p); break; case 9: //炮 case 10: CannonMove(p); break; case 11://兵 case 12: case 13: case 14: case 15: PawnMove(p); break; } }
} } void OutputMove()//输出所有的走法 { int i; for(i=0; i<MoveNum; i++) { printf("from %3d to %3d\n",MoveArray[i].from,MoveArray[i].to); } printf("total move number:%d\n",MoveNum); }
代码技巧
程序中,棋盘数组为全局变量形式,所以函数GenAllMove()中不再有形参,而走法全部保存在一个全局数组中,因此GenAllMove()的返回值为void。
参见程序4-1.cpp。