⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 movegenerator.cpp

📁 中国象棋源程序,该程序采用多种搜索算法实现了人机对弈的功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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;i<nToY;i++)
					if(position[i][nFromX]!=NOCHESS)
						return false;//中间隔有棋子
			}
			else
			{
				if(nToY>2 || 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;i<nToY;i++)
					if(position[i][nFromX]!=NOCHESS)
						return false;//中间隔有棋子
			}
			else
			{
				if(nToY>2 || 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(nToY<nFromY)
				return false;//卒不能回头
			
			if(nFromY<5 && nFromY==nToY)
				return FALSE;//卒过河前只能直走
		}
		else
		{
			if(nToY>nFromY)
				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(nToY<nFromY)
				return false;//兵不能回头
			
			if(nFromY<5 && nFromY==nToY)
				return FALSE;//兵过河前只能直走
		}

		if(nFromY-nToY+abs(nToX-nFromX)>1)
			return FALSE;//兵只走一步直线

		break;

	case B_CAR://黑车
	case R_CAR://红车
		if(nFromY!=nToY && nFromX!=nToX)
			return FALSE;//车走直线

		if(nFromY==nToY)
		{
			if(nFromX<nToX)
			{
				for(i=nFromX+1;i<nToX;i++)
					if(position[nFromY][i]!=NOCHESS)
						return FALSE;
			}
			else
			{
				for(i=nToX+1;i<nFromX;i++)
					if(position[nFromY][i]!=NOCHESS)
						return FALSE;
			}
		}
		else
		{
			if(nFromY<nToY)
			{
				for(j=nFromY+1;j<nToY;j++)
					if(position[j][nFromX]!=NOCHESS)
						return FALSE;
			}
			else
			{
				for(j=nToY+1;j<nFromY;j++)
					if(position[j][nFromX]!=NOCHESS)
						return FALSE;
			}
		}
		
		break;

	case B_HORSE://黑马
	case R_HORSE://红马
		if(!((abs(nToX-nFromX)==1 && abs(nToY -nFromY)==2) || (abs(nToX-nFromX)==2&&abs(nToY -nFromY)==1)))
			return FALSE;//马走日字

		if(nToX-nFromX==2)
		{
			i=nFromX+1;
			j=nFromY;
		}
		else
			if(nFromX-nToX==2)
			{
				i=nFromX-1;
				j=nFromY;
			}
			else
				if(nToY-nFromY==2)
				{
					i=nFromX;
					j=nFromY+1;
				}
				else
					if(nFromY-nToY==2)
					{
						i=nFromX;
						j=nFromY-1;
					}

		if(position[j][i]!=NOCHESS)
			return FALSE;//绊马腿
		
		break;

	case B_CANON://黑炮
	case R_CANON://红炮
		if(nFromY!=nToY && nFromX!=nToX)
			return FALSE;//炮走直线

		//炮吃子时经过的路线中不能有棋子
		if(position[nToY][nToX]==NOCHESS)
		{
			if(nFromY==nToY)
			{
				if(nFromX<nToX)
				{
					for(i=nFromX+1;i<nToX;i++)
						if(position[nFromY][i]!=NOCHESS)
							return FALSE;
				}
				else
				{
					for(i=nToX+1;i<nFromX;i++)
						if(position[nFromY][i]!=NOCHESS)
							return FALSE;
				}
			}
			else
			{
				if(nFromY<nToY)
				{
					for(j=nFromY+1;j<nToY;j++)
						if(position[j][nFromX]!=NOCHESS)
							return FALSE;
				}
				else
				{
					for(j=nToY+1;j<nFromY;j++)
						if(position[j][nFromX]!=NOCHESS)
							return FALSE;
				}
			}
		}		
		else//炮吃子时
		{
			int j=0;
			if(nFromY==nToY)
			{
				if(nFromX<nToX)
				{
					for(i=nFromX+1;i<nToX;i++)
						if(position[nFromY][i]!=NOCHESS)
							j++;
						if(j!=1)
							return FALSE;
				}
				else
				{
					for(i=nToX+1;i<nFromX;i++)
						if(position[nFromY][i]!=NOCHESS)
							j++;
						if(j!=1)
							return FALSE;
				}
			}
			else
			{
				if(nFromY<nToY)
				{
					for(i=nFromY+1;i<nToY;i++)
						if(position[i][nFromX]!=NOCHESS)
							j++;
					if(j!=1)
						return FALSE;
				}
				else
				{
					for(i=nToY+1;i<nFromY;i++)
						if(position[i][nFromX]!=NOCHESS)
							j++;
					if(j!=1)
						return FALSE;
				}
			}
		}
		
		break;

	default:
		return false;
	}
		
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -