如题,最近在研究一个象棋程序,按照中国象棋程序一书写的程序,
编译没有任何错误,可以运行,但是每次都是鼠标点击第二次的时候,
不能移动棋子,程序会卡崩溃。
调试发现是因为走法合理性检验
if (m_Board.LegalMove(mv))
这一步过不去,
跳进函数里面看是因为num = GenAllMove(mvArray);这个语句过不去,
但是GenAllMove(mvArray)这个函数是我自己编写的函数,应该没什么问题呀
想问问大家怎么回事。。。
ps.其中genallmove()函数和 LegalMove()函数是在一个cpp里,
然后在主对话框cpp里面调用
//这是对话框里面的代码
if (from != NOMOVE) //如果已经先选中本方棋子
{
move mv;
mv.from = ((from/9 +3) *16 + from%9 +3); //将10*9的棋盘位置转换成16*16的棋盘位置
mv.to = ((dest/9 +3) *16 + dest%9 +3);
int jy;
jy=m_Board.LegalMove(mv);
if (m_Board.LegalMove(mv)) //走法合理性检验,源位置z,目的位置k
{
m_Board.MakeMove(mv);
m_interface[dest] = m_interface[from];
m_interface[from] = 0;
m_SelectMoveTo = dest;
RequireDrawCell(dest);
m_SelectMoveFrom = from; //着重显示走法起始点
RequireDrawCell(from); //将源点及目的点重新显示
Beep(200,300);
num = m_Board.HasLegalMove(); //判断胜负
if (!num)
{
KillTimer(m_RedTimer);
m_gameState = GAMEOVER;
MessageBox("红方获胜", "系统消息");
return;
}
KillTimer(m_RedTimer);
m_gameState = BLACKTHINKING;
PostMessage(WM_COMMAND, IDM_LET_COMPUTERTHINK);
//这是判断走法合理性的代码
int CBoard::LegalMove(move mv) //判断走法是否合理
{
move mvArray[128];
int num,i;
num = GenAllMove(mvArray);
for(i=0; i<num; i++)
{
if(mv.from == mvArray[i].from && mv.to == mvArray[i].to)
return 1;
}
return 0;
}
//这是genallmove()的代码
int CBoard::GenAllMove(move *MoveArray)//生成所有走法
{
short i,j,k;
unsigned char p; //p->棋子位置
unsigned char n;//n 下一步可能行走的位置
unsigned char m;//马腿、象眼的位置
int SideTag;//走棋方标识,红16,黑32
int OverFlag;//炮翻山标识
move *mvArray = MoveArray;
SideTag = 16+16*side;
//将的走法
p=piece[SideTag];//将的位置
if(!p) //==if(p==null)
return 0;
for(k=0;k<4;k++)//4个方向
{
n=p+KingDir[k];
if(LegalPosition[side][n] & PositionMask[0])//if里为非0值或true执行
{
if(!(board[n] & SideTag))//目标位置上没有本方棋子
if(SaveMove(p,n,mvArray))
mvArray++;
}
}
//士的走法
for(i=1;i<=2;i++)
{
p = piece[SideTag+i];
if(!p)
continue;
for(k=0;k<4;k++)
{
n= p +AdvisorDir[k];
if(LegalPosition[side][n] & PositionMask[1])//位置是否合理
{
if(!(board[n] & SideTag))//没有本方棋子
if(SaveMove(p,n,mvArray))
mvArray++;
}
}
}
//象的走法
for(i=3;i>=4;i++)
{
p = piece[SideTag + i];
if(!p)
continue;
for(k=0;k<4;k++)
{
n = p +BishopDir[k];
if(!board[m]) //->if(board[m]=0)象眼位置没有棋子
{
if(!(board[n] & SideTag)) //目标位置上没有本方棋子
if(SaveMove(p,n,mvArray))
mvArray++;
}
}
}
//马的走法
for(i=5;i<=6;i++)
{
p= piece[SideTag + i];
if(!p)
continue;
for(k=0;k<8;k++)//8个可能走法
{
n = p+KnightDir[k];
if(LegalPosition[side][n] & PositionMask[3])
{
m = p+KnightCheck[k];
if(!board[m])//没有蹩脚
{
if(!(board[n] & SideTag))//目标位置没有自己棋子
if(SaveMove(p,n,mvArray))
mvArray++;
}
}
}
}
//车的走法
for(i=7;i<=8;i++)
{
p= piece[SideTag + i];
if(!p)
continue;
for(k=0;k<4;k++)//四个方向
{
for(j=1;j<10;j++)//横向最多8个可能位置,纵向最多9个可能位置
{
n=p+j*RookDir[k];
if(!(LegalPosition[side][n] & PositionMask[4]))
break;//如果位置不合理 结束
else if(!board[n] & SideTag)
break;//如果目标位置上是本方棋子 结束
else
{
if(SaveMove(p,n,mvArray))
mvArray++;
break;
}
}
}
}
//炮的走法
for(i=9;i<=10;i++)
{
p = piece[SideTag + i];
if(!p)
continue;
for(k=0;k<4;k++)
{
OverFlag = 0;//初始翻山标志
for(j=1;j<10;j++)
{
n = p+j*CannonDir[k];
if(!(LegalPosition[side][n] & PositionMask[5]))
break;//如果位置不合理 结束
if(!board[n])//如果目标位置没有棋子
{
if(!OverFlag)//未翻山
if(SaveMove(p,n,mvArray))
mvArray++;
//已翻山则不作处理,考察下一个位置
}
else//如果目标 位置有棋子
{
if(!OverFlag)
OverFlag = 1;
else
{
if(!(board[n] & SideTag))//是对方棋子
if(SaveMove(p, n, mvArray))
mvArray++;
break;
}
}
}
}
}
//兵的走法
for(i=11;i<=15;i++)
{
p=piece[SideTag + i];
if(!p)
continue;
for(k=0;k<3;k++)
{
n = p+PawnDir[side][k];
if(LegalPosition[side][n] & PositionMask[6])
{
if(!(board[n]) & SideTag)
if(SaveMove(p,n,mvArray))
mvArray++;
}
}
}
return mvArray - MoveArray;
}