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

📄 mantischessstd.cpp

📁 学习VC++游戏编程的 好程序 象棋代码 算法比较复杂
💻 CPP
字号:
 /***************************************************************
  MantisChessStd.cpp : MantisChess 标准函数

  版权所有(C) 共创软件联盟 CChessUG 项目开发小组成员 陈成涛 

  这一程序是自由软件,你可以遵照自由软件基金会出版的GNU通用公共
  许可证条款来修改和重新发布这一程序。或者用许可证的第二版,或者
  (根据你的选择)用任何更新的版本。

  发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特
  定目的的隐含的担保。更详细的情况请参阅GNU通用公共许可证。
  
  你应该已经和程序一起收到一份GNU通用公共许可证的副本。
  如果还没有,写信给:

  The Free Software Foundation,Inc,,675 Mass Ave, Cambridge,
  MAO2139,USA

  如果你在使用本软件时有什么问题或建议,用以下地址可以与我取得联
  系:

		http://thecct.51.net
		http://cosoft.org.com

  或发Email到:

		stove@eyou.com

******************************************************************/

#include "StdAfx.h"
#include "MantisChessDef.h"
#include "MantisChessStd.h"

/******************************************************************
CanGo:		判断一步棋合不合法

参数:
manmap:		棋位状态
man:		所移动的棋子
from:		所移动的棋子原始位置
to:			所要移动到的位置

返回值:		合法返回TRUE,不合法返回FALSE
******************************************************************/
BOOL  CanGo(int manmap[11][12],int man,const POINT &from,const POINT &to)
{
	static int i,j;

	if(!IsNormal(ManToType[man],to))	//这个棋子不能放在目标位置
	{
		//如果不是将/帅 (将/帅可以"照相")
		if(ManToType[man]!=RED_K&& ManToType[man]!=BLACK_K)return FALSE;

		else if(ManToType[man]==RED_K &&			//走的是帅
			ManToType[manmap[to.x][to.y]]==BLACK_K)	//目标是将
		{
			BOOL flag=FALSE;
			for(j= from.y-1;j>0;j--)
			{
				if (manmap[from.x][j]!=32)
				{
					if(ManToType[manmap[from.x][j]]==BLACK_K)	//照相
						flag=TRUE;
					break;				
				}
			}
			if(flag)return TRUE;
			else return FALSE;
		}
		else if(ManToType[manmap[to.x][to.y]]==RED_K)	//走的是将,目标是帅							
		{
			BOOL flag=FALSE;
			for(j= from.y+1;j<11;j++)
			{
				if (manmap[from.x][j]!=32)
				{
					if(ManToType[manmap[from.x][j]]==RED_K)	//照相
						flag=TRUE;	
					break;
				}
			}
			if(flag)return TRUE;
			else return FALSE;
		}
		else return FALSE;
	}

	//下面几行判断目标点是否己方的棋子:
	if(SideOfMan[man]==0)
	{
		if(manmap[to.x][to.y]!=32&& SideOfMan[manmap[to.x][to.y]]==0)return FALSE;		
	}
	else if(SideOfMan[man]==1)
	{
		if(manmap[to.x][to.y]!=32&& SideOfMan[manmap[to.x][to.y]]==1)return FALSE;		
	}
	//--------------------------------

	//以下是各棋子的规则:
	switch(ManToType[man])	
		{
		case RED_B:
			//兵不回头:
			if(to.y > from.y)return FALSE;
			//兵只走一步直线:
			if(from.y-to.y+abs(to.x-from.x)>1)return FALSE;	
			break;

		case BLACK_B:
			//卒不回头:
			if(to.y < from.y)return FALSE;
			//卒只走一步直线:
			if(to.y-from.y+abs(to.x-from.x)>1)return FALSE;	
			break;

		case RED_S:
		case BLACK_S:
			//士走斜线一步:
			if(abs(from.y-to.y)>1||abs(to.x-from.x)>1)return FALSE;	
			break;

		case RED_X:
		case BLACK_X:
			//相走田:
			if(abs(from.x-to.x)!=2||abs(from.y-to.y)!=2)return FALSE;
			//相心:
			if(manmap[(from.x+to.x)/2][(from.y+to.y)/2]!=32)return FALSE;
			break;

		case RED_K:
		case BLACK_K:
			//将帅只走一步直线:
			if(abs(from.y-to.y)+abs(to.x-from.x)>1)return FALSE;
			break;

		case RED_J:
		case BLACK_J:
			//车只能走直线:
			if(from.y!=to.y&&from.x!=to.x)return FALSE;	
			//车经过的路线中不能有棋子: -----------
			if(from.y==to.y)
			{
				if(from.x<to.x)
				{
					for(i=from.x+1;i<to.x;i++)
						if(manmap[i][from.y]!=32)return FALSE;
				}
				else
				{
					for(i=to.x+1;i<from.x;i++)
						if(manmap[i][from.y]!=32)return FALSE;
				}
			}
			else
			{
				if(from.y<to.y)
				{
					for(j=from.y+1;j<to.y;j++)
						if(manmap[from.x][j]!=32)return FALSE;
				}
				else
				{
					for(j=to.y+1;j<from.y;j++)
						if(manmap[from.x][j]!=32)return FALSE;
				}
			}
			//以上是车---------------------------------
			break;

		case RED_P:
		case BLACK_P:
			//炮只能走直线:
			if(from.y!=to.y&&from.x!=to.x)return FALSE;	
			//炮不吃子时经过的路线中不能有棋子:------------------
			if(manmap[to.x][to.y]==32)
			{
				if(from.y==to.y)
				{
					if(from.x<to.x)
					{
						for(i=from.x+1;i<to.x;i++)
							if(manmap[i][from.y]!=32)return FALSE;
					}
					else
					{
						for(i=to.x+1;i<from.x;i++)
							if(manmap[i][from.y]!=32)return FALSE;
					}
				}
				else
				{
					if(from.y<to.y)
					{
						for(j=from.y+1;j<to.y;j++)
							if(manmap[from.x][j]!=32)return FALSE;
					}
					else
					{
						for(j=to.y+1;j<from.y;j++)
							if(manmap[from.x][j]!=32)return FALSE;
					}
				}
			}
			//以上是炮不吃子-------------------------------------
			//吃子时:=======================================
			else	
			{
				int count=0;
				if(from.y==to.y)
				{
					if(from.x<to.x)
					{
						for(i=from.x+1;i<to.x;i++)
							if(manmap[i][from.y]!=32)count++;
						if(count!=1)return FALSE;
					}
					else
					{
						for(i=to.x+1;i<from.x;i++)
							if(manmap[i][from.y]!=32)count++;
						if(count!=1)return FALSE;
					}
				}
				else
				{
					if(from.y<to.y)
					{
						for(j=from.y+1;j<to.y;j++)
							if(manmap[from.x][j]!=32)count++;
						if(count!=1)return FALSE;
					}
					else
					{
						for(j=to.y+1;j<from.y;j++)
							if(manmap[from.x][j]!=32)count++;
						if(count!=1)return FALSE;
					}
				}
			}
			//以上是炮吃子时================================
			break;	

		case RED_M:
		case BLACK_M:
			//马走日:
			if(!(
				(abs(to.x-from.x)==1&&abs(to.y-from.y)==2)
				||(abs(to.x-from.x)==2&&abs(to.y-from.y)==1)
				))return FALSE;
			
			//找马脚:
			if		(to.x-from.x==2){i=from.x+1;j=from.y;}
			else if	(from.x-to.x==2){i=from.x-1;j=from.y;}
			else if	(to.y-from.y==2){i=from.x;j=from.y+1;}
			else if	(from.y-to.y==2){i=from.x;j=from.y-1;}
			
			//绊马脚:
			if(manmap[i][j]!=32)return FALSE;
			break;

		default:	
			break;
		}

	return TRUE;	//上面的规则全通过!
}

/******************************************************************
IsNormal:		mantype类型的棋子放在point位置是否合法

参数:
mantype:		棋子类型
point:			位置

返回值:			合法返回TRUE,不合法返回FALSE
******************************************************************/
BOOL  IsNormal(const int & mantype,const POINT &point)
{
	if(point.x<1||point.x>9||point.y<1||point.y>10)return FALSE;
	switch(mantype)
	{
	case RED_K:	
		//帅不能在红方宫外:
		if( point.x>6|| point.x<4|| point.y<8)return FALSE;
		break;

	case RED_S:	
		//仕只能在宫内特定点:
		if(!(
			( point.x==4&& point.y==10)||
			( point.x==4&& point.y==8)||
			( point.x==5&& point.y==9)||
			( point.x==6&& point.y==10)||
			( point.x==6&& point.y==8)
			))return FALSE;
		break;

	case RED_X:
		//七个相位:
		if(!(
			( point.x==1&& point.y==8)||
			( point.x==3&& point.y==10)||
			( point.x==3&& point.y==6)||
			( point.x==5&& point.y==8)||
			( point.x==7&& point.y==10)||
			( point.x==7&& point.y==6)||
			( point.x==9&& point.y==8)
			))return FALSE;
		break;

	case RED_B:
		//兵不能在兵位后:
		if( point.y>7)return FALSE;
		//兵过河前不能左右移动:
		if( point.y>5&& point.x%2==0)return FALSE;
		break;

	case BLACK_K:
		//帅不能在红方宫外:
		if( point.x>6|| point.x<4|| point.y>3)return FALSE;
		break;

	case BLACK_S:
		//仕只能在宫内特定点:
		if(!(
			( point.x==4&& point.y==1)||
			( point.x==4&& point.y==3)||
			( point.x==5&& point.y==2)||
			( point.x==6&& point.y==1)||
			( point.x==6&& point.y==3)
			))return FALSE;
		break;

	case BLACK_X:
		//七个相位:
		if(!(
			( point.x==1&& point.y==3)||
			( point.x==3&& point.y==1)||
			( point.x==3&& point.y==5)||
			( point.x==5&& point.y==3)||
			( point.x==7&& point.y==1)||
			( point.x==7&& point.y==5)||
			( point.x==9&& point.y==3)
			))return FALSE;
		break;

	case BLACK_B:
		//兵不能在兵位后:
		if( point.y<4)return FALSE;
		//兵过河前不能左右移动:
		if( point.y<6&& point.x%2==0)return FALSE;
		break;

	default:
		break;
	}
	return TRUE;
}

/******************************************************************
FixManMap:		根据棋子坐标计算棋位状态

参数:
map:			棋位状态(存放结果)
manpoint:		棋子坐标
side:			轮到哪一方走

返回值:			无
******************************************************************/
void  FixManMap(int map[11][12],POINT manpoint[32],int side)
{
	memcpy(map,_defaultmap,132*sizeof(int));

	static POINT * pman;
	static int i;
	for(i=0;i<32;i++)
	{
		pman = & manpoint[i];
		if(pman->x)
			map[pman->x][pman->y]=i;
	}
}

⌨️ 快捷键说明

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