4.2 车炮马象(相)士(仕)卒(兵)将(帅)走法生成
每种棋子都有自己的行走规则,计算机程序进行走法生成,都是先穷举再排除。即先列举出全部可能的位置,再一个一个除去不合规则的走法,剩下的就是合理的走法。
不同棋子走法生成的共同点是:
● 找出棋子的下一可能位置n。
● 判断n是否在棋盘上。
● 判断n是否被本方棋子占据。
不同棋子应考虑的特殊问题:
● 将、士是否走出九宫。
● 象是否过河,象眼是否被堵。
● 马是否蹩脚。
● 炮要翻山吃子。
● 兵过河前只能前进,过河后可以前进和左右移动。
4.2.1 马的走法生成
马有八个可能行走的位置,其特殊点在于起点与终点之间的马腿位置不能被其他棋子占据。如图4-1所示为马的走棋规则示意图。
图4-1 马走法示意图
图中黑三角形位置是马腿位置,1、2位置的马腿位置相同,3和4,5和6,7和8的马腿位置也相同。由于马是固定最多有八个可能位置,所以可以将这八个位置用一个数组保存走来。同样,每一个可能位置的马腿位置也是固定的,也用一个数组保存起来,而且它与方向数组相对应。
八个可行方向的数组表示
KnightDir[8] ={ +0x0e, -0x12,-0x21,-0x1f, -0x0e, +0x12,+0x1f,+0x21},
每个方向对应的马腿位置数组表示
KnightCheck[8] = {-0x01, -0x01,-0x10,-0x10, +0x01, +0x01,+0x10,+0x10},
KnightDir[i]位置对应的马腿位置即为KnightCheck[i]。
算法4-1:生成马的走法
输入:马的位置p 输出:马的所有可能走法 1现在位置p 2八个可行方向(i=0 … 7) 3计算下一位置n 4 n是否在棋盘上 是,转第5步 不是,转第2步 5 从p到n的马腿位置m上是否有棋子 有,转第2步 没有,转第6步 6 n是否被本方棋子占据 是,转第2步 不是,保存可行的走法,考虑下一位置转第2步
程序代码
typedef struct { unsigned char from, to; }move; move MoveArray[128];//走法数组 int MoveNum;//走法总数 void InitGen()//清空走法 { MoveNum = 0; } void SaveMove(unsigned char from, unsigned char to)//保存走法 { MoveArray[MoveNum].from = from; MoveArray[MoveNum].to = to; MoveNum++; } void KnightMove(unsigned char p)//生成马的走法 { int k; unsigned char n;//下一步可能行走的位置 unsigned char m;//马腿位置
int SideTag = 16 + side * 16; //走棋方,红方16,黑方32 for(k=0; k<8; k++)//8个方向 { n = p + KnightDir[k]; //n为新的可能走到的位置 if(KnightPosition[n])//是否在棋盘上 { m = p + KnightCheck[k]; if(!board[m]) //马腿位置无棋子占据 { if( !(board[n] & SideTag)) //目标位置上没有本方棋子 SaveMove(p, n); } } } }
代码技巧
下一位置n:n = p+ KnightDir [i]
如何判断n是否在棋盘上:
横坐标x = n /16(整除)
纵坐标y = n % 16
x>=3 && x<=12 && y>=3 && y<=11
要做两个除法运算,四个逻辑判断运算,效率比较低。
可以设置一个辅助数组,表示哪些位置是马在棋盘上的合理位置。
const char KnightPosition[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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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 };
要判断n是否在棋盘上,则只需要运算if(KnightPosition [n])
马腿位置m: m = p + KnightCheck[i]
马腿位置m上是否有棋子:if(board[m])
n是否被本方棋子占据:对红方:board[n] & 16 !=0即被本方棋子占据;对黑方:board[n]& 32 !=0即被本方棋子占据。在本程序中设置一个SideTag,走棋为红方时SideTag=16,走棋为黑方时SideTag=32
算法描述中,生成的走法作为算法的输出。生成的走法不只一个,函数不可能返回多个值。在实际程序设计时,用数组来保存生成的所有走法。并且将这个走法定义为一个全局的变量。设一维数组move gen[1024]表示走法,设整型变量int num表示生成走法个数。一旦生成一个走法,保存走法则执行下面三行代码。
Gen[num].from = p; gen[num].to = n; num++;
4.2.2 将(帅)的走法生成
将有四个可能走的位置,如图4-2所示为将走法示意图。
图4-2 将走法示意图
把这四个方向用一个数组表示起来。
KingDir[8] ={-0×10, +0×01, +0×10, -0×01, 0, 0, 0, 0}
算法4-2:生成将的走法
输入:将的位置p 输出:将的所有可能走法 1现在位置p 2四个可行方向 3计算下一位置n 4 n是否在九宫内 是,转第5步 不是,转第2步 5 n是否被本方棋子占据 是,转第2步 不是,保存可行的走法,考虑下一位置转第2步
程序代码
void KingMove(unsigned char p) { int k; unsigned char n;//下一步可能行走的位置 int SideTag = 16 + side * 16; //走棋方,红方16,黑方32 for(k=0; k<4; k++)//4个方向 { n = p + KingDir[k];//n为新的可能走到的位置 if(KingPosition[n]) { if( !(board[n] & SideTag)) //目标位置上没有本方棋子 SaveMove(p, n); } } }
代码技巧
判断是否在九宫:设置一个数组,表示将所有合理的位置
const char KingPisition[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 };
判断是否在九宫,即只需执行if(KingPosition[n])。
对生成走法的保存处理与前面一样。
4.2.3 士(仕)的走法生成
士有四个可能走的位置,如图4-3的示为士走法示意图。
图4-3 士走法示意图
把这四个方向用一个数组表示起来。
Advisor Dir[8]={-0×11, -0×0f, +0×11, +0×0f, 0, 0, 0, 0}
算法4-3:生成士的走法
输入:士的位置p 输出:士的所有可能走法 1现在位置p 2四个可行方向 3计算下一位置n 4 n是否在九宫内 是,转第5步 不是,转第2步 5 n是否被本方棋子占据 是,转第2步 不是,保存可行的走法,考虑下一位置转第2步
程序代码
void AdvisorMove(unsigned char p) { int k; unsigned char n;//下一步可能行走的位置 int SideTag = 16 + side * 16; //走棋方,红方16,黑方32 for(k=0; k<4; k++)//4个方向 { n = p + AdvisorDir[k]; //n为新的可能走到的位置 if(AdvisorPisition[n]) {
if( !(board[n] & SideTag)) //目标位置上没有本方棋子 SaveMove(p, n); } } }
代码技巧
判断士是否在九宫:设置一个数组,表示将所有合理的位置
const char AdvisorPisition[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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
判断士是否在九宫,即只需执行if(AdvisorPosition[n])
4.2.4 象(相)的走法生成
象有四个可能走的位置,如图4-4所示。
图4-4 象走法示意图
黑三角形位置就是对应位置的象眼。象眼被棋子占住,俗称象眼被塞,不能走到对应的位置。
把象的可行方向及对应的象眼位置分别用数组存储。
四个可行方向
BishopDir[8]={ -0×22, -0×1e, +0×22, +0×1e, 0, 0, 0, 0}
四个方向对应的象眼位置
BishopCheck[8] = {-0×11,-0×0f, +0×11,+0×0f, 0,0,0,0},
算法4-4:生成象的走法
输入:象的位置p 输出:象的所有可能走法 1现在位置p 2四个可行方向 3计算下一位置n 4 n是否在棋盘上 是,转第5步 不是,转第2步 5 从p到n的象眼位置m上是否有棋子 有,转第2步 没有,转第6步 6 n是否被本方棋子占据 是,转第2步 不是,保存可行的走法,考虑下一位置转第2步
程序代码
void BishopMove(unsigned char p) { int k; unsigned char n;//下一步可能行走的位置 unsigned char m;//象眼位置 int SideTag = 16 + side * 16; //走棋方,红方16,黑方32 for(k=0; k<4; k++)//4个方向 { n = p + BishopDir[k]; //n为新的可能走到的位置 if(BishopPosition[n]) { m = p + BishopCheck[k]; if(!board[m]) //象眼位置无棋子占据 {
if( !(board[n] & SideTag)) //目标位置上没有本方棋子 SaveMove(p, n); } } } }
代码技巧
设置数组表示象的合理位置
const char BishopPosition[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, 1, 0, 0, 0, 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, 1, 0, 0, 0, 1, 0, 0, 0, 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, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 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, 1, 0, 0, 0, 1, 0, 0, 0, 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, 1, 0, 0, 0, 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 };
4.2.5 车的走法生成
如图4-5所示车可以沿着四条直线走,每个方向可一直向前走,直到:
1. 走出棋盘
2. 碰到本方棋子
3. 吃掉对方棋子。
在上图4-5中,1、4位置表示一直走到边界,2位置表示遇到本方棋子,3位置表示遇到对方棋子。
同样,把车的四个可行方向用数组存储起来
RookDir[8]={-0×01, -0×10, +0×01, +0×10, 0, 0, 0, 0},
但是,车沿着这个方向可以一直向前走,直到走出棋盘/碰到本方棋子/吃掉对方棋子。这样在算法或程序的处理时,与马、象等是有区别的。
图4-5 车走法示意图
算法4-5:生成车的走法
输入:车的位置p 输出:车的所有可能走法 1现在位置p 2四个可行方向 //第一重循环 3沿这个方向继续前进一步(最多前进9步) //第二重循环 4计算下一位置n 5 n是否在棋盘上 是,转第6步 不是,转第2步 6 n位置上是否有棋子 没有,保存可行的走法,考虑下一位置转第3步(不吃子走法) 有棋子则,该棋子是本方棋子 是,转第3步 不是,保存可行的走法,考虑下一位置转第3步(吃子走法)
程序代码
void RookMove(unsigned char p) { int k,j; unsigned char n;//下一步可能行走的位置 int SideTag = 16 + side * 16; //走棋方,红方16,黑方32
for(k=0; k<4; k++) //4个方向 { for(j=1; j<10; j++)//横的最多有8个可能走的位置,纵向最多有9个位置 { n = p + j * RookDir[k]; if(! KnightPosition[n])//不合理的位置 break; if(! board[n] )//目标位置上无子 SaveMove(p, n); else if ( board[n] & SideTag) //目标位置上有本方棋子 break; else //目标位置上有对方棋子 { SaveMove(p, n); break; } } } }
代码技巧
车的算法中有两重循环,因为沿每一方向都可有很多的位置可走。
车能走到的地方,也是马可以到达的地方,所以判断车的位置是否合理的数组与马的相同。
4.2.6 炮的走法生成
如图4-6所示炮也是沿着四条直线走,每个可行方向可一直向前走,直到走出棋盘、碰到棋子后可再向前吃掉对方棋子。
在上图4-6中,1表示一直走到边界,2位置翻山后遇到本方棋子,3表示翻山后遇到对方棋子,4表示翻山后走到边界。
图4-6 炮走法示意图
同样,把炮的四个可行方向用数组存储起来
CannonDir[8]={-0×01, +0×01, -0×10, +0×10, 0, 0, 0, 0},
炮与车行棋规则既相似,又不同。炮也可以沿着一个方向一直向前走,遇到一个棋子后,如果是对方棋子炮不能直接吃掉。不论遇到的是何方棋子,炮可以翻过去向前,俗称翻山。翻山后,炮只能吃对方的棋子,不能落到空的位置,当然也不能吃掉本方棋子。
算法4-6:生成炮的走法
输入:炮的位置p 输出:炮的所有可能走法 1现在位置p 2四个可行方向 //第一重循环 翻山标志置0, OverFlag =0 3沿这个方向继续前进一步(最多前进9步) //第二重循环 4计算下一位置n 5 n是否在棋盘上 是,转第6步 不是,转第2步 6 n位置上是否有棋子 没有棋子 如果OverFlag==0,保存可行的走法(不吃子走法),转第3步 否则,转第3步 有棋子则, 如果OverFlag==0,则令OverFlag=1。(翻山) 否则,如果该棋子是本方棋子 不是,保存可行的走法(吃子走法),转第2步 是,转第2步。
程序代码
void CannonMove(unsigned char p) { int k,j; unsigned char n;//下一步可能行走的位置 int SideTag = 16 + side * 16; //走棋方,红方16,黑方32 int OverFlag; for(k=0; k<4; k++) //4个方向 {
OverFlag = 0; for(j=1; j<10; j++)//横的最多有8个可能走的位置,纵向最多有9个位置 { n = p + j * CannonDir[k]; if(!KnightPosition[n]) //不合理的位置 break; if(! board[n] )//目标位置上无子 { if(!OverFlag) //未翻山 SaveMove(p, n); //已翻山则不做处理,自动考察向下一个位置 } else//目标位置上有子 { if (!OverFlag) //未翻山则置翻山标志 OverFlag = 1; else //已翻山 { if(! (board[n] & SideTag))//对方棋子 SaveMove(p, n); break; //不论吃不吃子,都退出此方向搜索 } } } } }
代码技巧
炮的算法中有两重循环,因为沿每一方向都可有很多的位置可走。炮的算法与车的不同之处在于,炮沿一个方向行进碰到一棋子,不是直接吃掉,而是越过此棋子继续向前行进。一旦越过一棋子,则只能吃掉下一棋子,而不能停留在没有棋子的位置上。所以,在向一个方向前进时,必须增加一个变量int OverFlag,用以表示当前是否已经翻山。炮行进时没有翻山时只能停留在空闲的交叉点上,而翻山后只能落在被对方棋子占据的交叉点上并吃掉对方的棋子。
炮能走到的地方,也是马可以到达的地方,判断炮的位置是否合理的数组与马的相同。
4.2.7 卒(兵)的走法生成
兵未过河之间只能向前,过河之后可以横向移动,如图4-7所示。
兵的走法与前面所有的棋子走法有一个最大的区别就是,红兵和黑卒是不一样的。红马和黑马的走法是没有区别的,在同一个位置,红马可以去的地方,黑马也可以去。士象将虽然也有红黑之分,即红相能到的地方,黑象是绝对到不了的,红仕能到的地方,黑士是绝对到不了的,红帅能到的地方,黑将是绝对到不了的。但是就其行进的方位来讲是相同的,象是前后左右四个田字,士是四个斜线方向,将是上下左右四个方向。
图4-7 红兵走法示意图
站在红方的角度,红兵前进的方向,就是黑卒后退的方向。所以黑卒与红兵一定得分开处理。用一个二维数组表示它们不同的方向。
PawnDir[2][8]={{-0×01, +0×01, -0×10, 0, 0, 0, 0, 0}, {-0×01, +0×01, +0×10, 0, 0, 0, 0, 0}},
PawnDir[0]表示红方的方向,PawnDir[1]表示黑方的方向。
算法4-7:生成兵的走法
输入:兵的位置p 输出:兵的所有可能走法 1现在位置p 2三个可行方向 3计算下一位置n = p + PawnDir[side][n]; 4 n是否在棋盘上 是,转第5步 不是,转第2步 5 是否未过河横向移动 是,转第2步 不是,转第6步 6 n是否被本方棋子占据 是,转第2步 不是,保存可行的走法,考虑下一位置转第2步
程序代码
void PawnMove(unsigned char p) { int k; unsigned char n;//下一步可能行走的位置 int SideTag = 16 + side * 16; //走棋方,红方16,黑方32 for(k=0; k<3; k++)//3个方向 { n = p + PawnDir[side][k]; //n为新的可能走到的位置 if(PawnPosition[side][n]) { if( !(board[n] & SideTag)) //目标位置上没有本方棋子 SaveMove(p, n); } } }
代码技巧
同样可以设置兵的合理位置数组
short PawnPosition[2][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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { //黑卒 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 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 } };
黑卒位置是否在棋盘上及是否未过河横向移动,均可用此数组判断。
If (PawnPosition[1][n]) 则是合理的移动位置 红兵则是If (PawnPosition[0][n])