C/C++中国象棋程序入门与提高
上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。