www.pudn.com > 1223456.rar > MoveGenerator.cpp
// MoveGenerator.cpp: implementation of the CMoveGenerator class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "chess.h"
#include "MoveGenerator.h"
#ifdef _DEBUG
#undef THIS_FILE
static BYTE THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMoveGenerator::CMoveGenerator()
{
}
CMoveGenerator::~CMoveGenerator()
{
}
int CMoveGenerator::AddMove(int nFromX,int nFromY,int nToX,int nToY,int nPly,int nChessID)
{
m_MoveList[nPly][m_nMoveCount].From.x=nFromX;
m_MoveList[nPly][m_nMoveCount].From.y=nFromY;
m_MoveList[nPly][m_nMoveCount].To.x=nToX;
m_MoveList[nPly][m_nMoveCount].To.y=nToY;
m_MoveList[nPly][m_nMoveCount].nChessID=nChessID;
m_nMoveCount++;
return m_nMoveCount;
}
//nPly指明当前搜索的层数,每层将走法存在不同的位置,以免覆盖
//nSide指明产生哪一方的走法,TRUE为红方,FALSE是黑方
int CMoveGenerator::CreatePossibleMove(BYTE position[][9],int nPly,int nSide,int nUserChessColor)
{
int nChessID;
int i,j;
m_nMoveCount=0;
m_nUserChessColor=nUserChessColor;
for(j=0;j<9;j++)
for(i=0;i<10;i++)
{
if(position[i][j]!=NOCHESS)
{
nChessID=position[i][j];
if(nUserChessColor==REDCHESS)
{
if(!nSide && IsRed(nChessID))
continue;//如要产生黑棋走法,跳过红棋
if(nSide && IsBlack(nChessID))
continue;//如要产生红棋走法,跳过黑棋
}
else
{
if(nSide && IsRed(nChessID))
continue;//如要产生黑棋走法,跳过红棋
if(!nSide && IsBlack(nChessID))
continue;//如要产生红棋走法,跳过黑棋
}
switch(nChessID)
{
case R_KING://红帅
case B_KING://黑将
Gen_KingMove(position,i,j,nPly);
break;
case R_BISHOP://红士
Gen_RBishopMove(position,i,j,nPly);
break;
case B_BISHOP://黑士
Gen_BBishopMove(position,i,j,nPly);
break;
case R_ELEPHANT://红相
case B_ELEPHANT://黑象
Gen_ElephantMove(position,i,j,nPly);
break;
case R_HORSE://红马
case B_HORSE://黑马
Gen_HorseMove(position,i,j,nPly);
break;
case R_CAR://红车
case B_CAR://黑车
Gen_CarMove(position,i,j,nPly);
break;
case R_PAWN://红兵
Gen_RPawnMove(position,i,j,nPly);
break;
case B_PAWN://黑卒
Gen_BPawnMove(position,i,j,nPly);
break;
case B_CANON://黑炮
case R_CANON://红炮
Gen_CanonMove(position,i,j,nPly);
break;
default:
break;
}
}
}
return m_nMoveCount;
}
void CMoveGenerator::Gen_KingMove(BYTE position[10][9],int i,int j,int nPly)
{
int x,y;
for(y=0;y<3;y++)
for(x=3;x<6;x++)
if(IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
for(y=7;y<10;y++)
for(x=3;x<6;x++)
if(IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
}
//红士
void CMoveGenerator::Gen_RBishopMove(BYTE position[10][9],int i,int j,int nPly)
{
int x,y;
for(y=7;y<10;y++)
for(x=3;x<6;x++)
if(IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
}
//黑士
void CMoveGenerator::Gen_BBishopMove(BYTE position[10][9],int i,int j,int nPly)
{
int x,y;
for(y=0;y<3;y++)
for(x=3;x<6;x++)
if(IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
}
//象
void CMoveGenerator::Gen_ElephantMove(BYTE position[10][9],int i,int j,int nPly)
{
int x,y;
//插入右下方的有效走法
x=j+2;
y=i+2;
if(x<9 && y<10 && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入右上方的有效走法
x=j+2;
y=i-2;
if(x<9 && y>=0 && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入左下方的有效走法
x=j-2;
y=i+2;
if(x>=0 && y<10 && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入左上方的有效走法
x=j-2;
y=i-2;
if(x>=0 && y>=0 && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
}
//马
void CMoveGenerator::Gen_HorseMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
//插入右下方的有效走法
x=j+2;//右2
y=i+1;//下1
if((x<9 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入右上方的有效走法
x=j+2;//右2
y=i-1;//上1
if((x<9 && y>=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入左下方的有效走法
x=j-2;//左2
y=i+1;//下1
if((x>=0 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入左上方的有效走法
x=j-2;//左2
y=i-1;//上1
if((x>=0 && y>=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入右下方的有效走法
x=j+1;//右1
y=i+2;//下2
if((x<9 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入左下方的有效走法
x=j-1;//左1
y=i+2;//下2
if((x>=0 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入右上方的有效走法
x=j+1;//右1
y=i-2;//上2
if((x<9 && y >=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
//插入左上方的有效走法
x=j-1;//左1
y=i-2;//上2
if((x>=0 && y>=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor))
AddMove(j,i,x,y,nPly,position[i][j]);
}
//红兵
void CMoveGenerator::Gen_RPawnMove(BYTE position[10][9], int i, int j, int nPly)
{
int x,y;
int nChessID;
nChessID=position[i][j];
if(m_nUserChessColor==REDCHESS)
{
y=i-1;//向前
x=j;
if(y>0 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍
if(i<5)//是否已过河
{
y=i;
x=j+1;//右边
if(x<9 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
x=j-1;//左边
if(x>=0 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
}
}
else
{
y=i+1;//向前
x=j;
if(y>0 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍
if(i>4)//是否已过河
{
y=i;
x=j+1;//右边
if(x<9 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
x=j-1;//左边
if(x>=0 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
}
}
}
//黑卒
void CMoveGenerator::Gen_BPawnMove(BYTE position[10][9],int i,int j,int nPly)
{
int x,y;
int nChessID;
nChessID=position[i][j];
if(m_nUserChessColor==REDCHESS)
{
y=i+1;//向前
x=j;
if(y<10 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍
if(i>4)//是否已过河
{
y=i;
x=j+1;//右边
if(x<9 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
x=j-1;//左边
if(x>=0 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
}
}
else
{
y=i-1;//向前
x=j;
if(y<10 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍
if(i<5)//是否已过河
{
y=i;
x=j+1;//右边
if(x<9 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
x=j-1;//左边
if(x>=0 && !IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
}
}
}
//车
void CMoveGenerator::Gen_CarMove(BYTE position[10][9], int i, int j, int nPly)
{
int x,y;
int nChessID;
nChessID=position[i][j];
//插入向右的有效的走法
x=j+1;
y=i;
while(x<9)
{
if(NOCHESS==position[y][x])
AddMove(j,i,x,y,nPly,position[i][j]);
else
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
x++;
}
//插入向左的有效的走法
x=j-1;
y=i;
while(x>=0)
{
if(NOCHESS==position[y][x])
AddMove(j,i,x,y,nPly,position[i][j]);
else
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
x--;
}
//插入向下的有效的走法
x=j;
y=i+1;
while(y<10)
{
if(NOCHESS==position[y][x])
AddMove(j,i,x,y,nPly,position[i][j]);
else
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
y++;
}
//插入向上的有效的走法
x=j;
y=i-1;
while(y>=0)
{
if(NOCHESS==position[y][x])
AddMove(j,i,x,y,nPly,position[i][j]);
else
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
y--;
}
}
//炮
void CMoveGenerator::Gen_CanonMove(BYTE position[10][9], int i, int j, int nPly)
{
int x,y;
BOOL flag;
int nChessID;
nChessID=position[i][j];
//插入向右的有效的走法
x=j+1;
y=i;
flag=FALSE;
while(x<9)
{
if(NOCHESS==position[y][x])
{
if(!flag)//隔有棋子
AddMove(j,i,x,y,nPly,position[i][j]);
}
else
{
if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志
flag=TRUE;
else //隔有棋子,此处如为敌方棋子,则可走
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
}
x++;//继续下一个位置
}
//插入向左的有效的走法
x=j-1;
y=i;
flag=FALSE;
while(x>=0)
{
if(NOCHESS==position[y][x])
{
if(!flag)//隔有棋子
AddMove(j,i,x,y,nPly,position[i][j]);
}
else
{
if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志
flag=TRUE;
else //隔有棋子,此处如为敌方棋子,则可走
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
}
x--;//继续下一个位置
}
//插入向下的有效的走法
x=j;
y=i+1;
flag=FALSE;
while(y<10)
{
if(NOCHESS==position[y][x])
{
if(!flag)//隔有棋子
AddMove(j,i,x,y,nPly,position[i][j]);
}
else
{
if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志
flag=TRUE;
else //隔有棋子,此处如为敌方棋子,则可走
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
}
y++;//继续下一个位置
}
//插入向上的有效的走法
x=j;
y=i-1;
flag=FALSE;
while(y>=0)
{
if(NOCHESS==position[y][x])
{
if(!flag)//隔有棋子
AddMove(j,i,x,y,nPly,position[i][j]);
}
else
{
if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志
flag=TRUE;
else //隔有棋子,此处如为敌方棋子,则可走
{
if(!IsSameSide(nChessID,position[y][x]))
AddMove(j,i,x,y,nPly,position[i][j]);
break;
}
}
y--;//继续下一个位置
}
}
BOOL CMoveGenerator::IsValidMove(BYTE position[10][9], int nFromX, int nFromY, int nToX, int nToY,int nUserChessColor)
{
int i,j;
int nMoveChessID,nTargetID;
if(nFromX==nToX && nFromY==nToY)
return false;//目的与源相同,非法
nMoveChessID=position[nFromY][nFromX];
nTargetID=position[nToY][nToX];
if(IsSameSide(nMoveChessID,nTargetID))
return false;//吃自己的棋,非法
switch(nMoveChessID)
{
case B_KING://黑将
if(nUserChessColor==REDCHESS)
{
if(nTargetID==R_KING)//判断是否将帅见面
{
if(nFromX!=nToX)//横坐标不相等
return false;//将帅不在同一列
for(i=nFromY+1;i2 || nToX>5 || nToX<3)
return false;//目标点在九宫之外
if(abs(nFromY-nToY)+abs(nFromX-nToX)>1)
return false;//将帅只走一步直线
}
}
else
{
if(nTargetID==R_KING)//判断是否将帅见面
{
if(nFromX!=nToX)//横坐标不相等
return false;//将帅不在同一列
for(i=nFromY-1;i>nToY;i--)
if(position[i][nFromX]!=NOCHESS)
return false;//中间隔有棋子
}
else
{
if(nToY<7 || nToX>5 || nToX<3)
return false;//目标点在九宫之外
if(abs(nFromY-nToY)+abs(nFromX-nToX)>1)
return false;//将帅只走一步直线
}
}
break;
case R_KING://红帅
if(nUserChessColor==REDCHESS)
{
if(nTargetID==B_KING)//判断是否将帅见面
{
if(nFromX!=nToX)//横坐标不相等
return false;//将帅不在同一列
for(i=nFromY-1;i>nToY;i--)
if(position[i][nFromX]!=NOCHESS)
return false;//中间隔有棋子
}
else
{
if(nToY<7 || nToX>5 || nToX<3)
return false;//目标点在九宫之外
if(abs(nFromY-nToY)+abs(nFromX-nToX)>1)
return false;//将帅只走一步直线
}
}
else
{
if(nTargetID==B_KING)//判断是否将帅见面
{
if(nFromX!=nToX)//横坐标不相等
return false;//将帅不在同一列
for(i=nFromY+1;i2 || nToX>5 || nToX<3)
return false;//目标点在九宫之外
if(abs(nFromY-nToY)+abs(nFromX-nToX)>1)
return false;//将帅只走一步直线
}
}
break;
case R_BISHOP://红士
if(nUserChessColor==REDCHESS)
{
if(nToY<7 || nToX>5 || nToX<3)
return false;//士出九宫
}
else
{
if(nToY>2 || nToX>5 || nToX<3)
return false;//士出九宫
}
if(abs(nFromX-nToX)!=1 || abs(nFromY-nToY)!=1)
return false;//士走斜线
break;
case B_BISHOP://黑士
if(nUserChessColor==REDCHESS)
{
if(nToY>2 || nToX>5 || nToX<3)
return false;//士出九宫
}
else
{
if(nToY<7 || nToX>5 || nToX<3)
return false;//士出九宫
}
if(abs(nFromX-nToX)!=1 || abs(nFromY-nToY)!=1)
return false;//士走斜线
break;
case R_ELEPHANT://红相
if(nUserChessColor==REDCHESS)
{
if(nToY<5)
return false;//相不能过河
}
else
{
if(nToY>4)
return false;//相不能过河
}
if(abs(nFromX-nToX)!=2 || abs(nFromY-nToY)!=2)
return false;//相走田字
if(position[(nFromY +nToY)/2][(nFromX +nToX)/2]!=NOCHESS)
return FALSE;//相眼被塞
break;
case B_ELEPHANT://黑象
if(nUserChessColor==REDCHESS)
{
if(nToY>4)
return false;//象不能过河
}
else
{
if(nToY<5)
return false;//象不能过河
}
if(abs(nFromX-nToX)!=2 || abs(nFromY-nToY)!=2)
return false;//象走田字
if(position[(nFromY +nToY)/2][(nFromX +nToX)/2]!=NOCHESS)
return FALSE;//象眼被塞
break;
case B_PAWN://黑卒
if(nUserChessColor==REDCHESS)
{
if(nToYnFromY)
return false;//卒不能回头
if(nFromY>4 && nFromY==nToY)
return FALSE;//卒过河前只能直走
}
if(nToY-nFromY+abs(nToX-nFromX)>1)
return FALSE;//卒只走一步直线
break;
case R_PAWN://红兵
if(nUserChessColor==REDCHESS)
{
if(nToY>nFromY)
return false;//兵不能回头
if(nFromY>4 && nFromY==nToY)
return FALSE;//兵过河前只能直走
}
else
{
if(nToY1)
return FALSE;//兵只走一步直线
break;
case B_CAR://黑车
case R_CAR://红车
if(nFromY!=nToY && nFromX!=nToX)
return FALSE;//车走直线
if(nFromY==nToY)
{
if(nFromX