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

📄 mantischessthink.cpp

📁 学习VC++游戏编程的 好程序 象棋代码 算法比较复杂
💻 CPP
📖 第 1 页 / 共 2 页
字号:
     /***************************************************************
  MantisChessThink.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 "MantisChessThink.h"
//-------------下面几项可以调试智能模块---------------------------
#define S_WIDTH 7
#define S_DEPTH 6

//                将  士  象  马  车  炮   兵
const base[7]=	{300,300,300,500, 850,500,300};	//平均价值
const range[7]=	{0  ,  0,  0, 20,  10,  0, 40};	//价值的变动范围

const int contactpercent1=20;	//防守的重视程度
const int contactpercent2=25;	//进攻的重视程度

/******************************************************************
例:把马设为平均价值200,变动范围±13%应设base[3]=200,range[3]=13
*******************************************************************/
//-----------------------------------------------------------------

const int BV1[7]=//基本价值
{  
	base[0]-base[0]*range[0]/100,
	base[1]-base[1]*range[1]/100,
	base[3]-base[2]*range[2]/100,
	base[3]-base[3]*range[3]/100,
	base[4]-base[4]*range[4]/100,
	base[5]-base[5]*range[5]/100,
	base[6]-base[6]*range[6]/100
};
const int BV2[7]=//活跃度
{ 
	2*base[0]*range[0]/100/4,
	2*base[1]*range[1]/100/4,
	2*base[2]*range[2]/100/4,
	2*base[3]*range[3]/100/8,
	2*base[4]*range[4]/100/17,
	2*base[5]*range[5]/100/17,
	0,
};

const int BV3[5]=//兵在不同位置的价值附加
{
	0*2*base[6]*range[6]/100/4,
	1*2*base[6]*range[6]/100/4,
	2*2*base[6]*range[6]/100/4,
	3*2*base[6]*range[6]/100/4,
	4*2*base[6]*range[6]/100/4,
};

#define NORED(i,j) (SideOfMan[tmap[i][j]]!=0)
#define NOBLACK(i,j) (SideOfMan[tmap[i][j]]!=1)
#define NOMAN(i,j) (tmap[i][j]==32)


//兵卒在不同位置的价值,数字越大价值越高
const int ManBPlus[2][12][11]=
{
	{
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  1,  2,  3,  4,  4,  4,  3,  2,  1,  0},
		{  0,  1,  2,  3,  4,  4,  4,  3,  2,  1,  0},
		{  0,  1,  2,  3,  3,  3,  3,  3,  2,  1,  0},
		{  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0},
		{  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0},
		{  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
	},
	{
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0},
		{  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0},
		{  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0},
		{  0,  1,  2,  3,  3,  3,  3,  3,  2,  1,  0},
		{  0,  1,  2,  3,  4,  4,  4,  3,  2,  1,  0},
		{  0,  1,  2,  3,  4,  4,  4,  3,  2,  1,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
		{  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
	}
};

//-------------------------------------------
static void ContactV(int tmap[11][12],POINT tmanposition[32],int &tside,int activity[32],int contact[32][32]);


/******************************************************************
Mantis_QuickSort:对走法列表进行快速排序

参数:
A:				关键值
chessman:		待排序的棋子列表
targetpoint:	待排序的目标点列表
low,high:		QuickSort上下限

返回值:			无
******************************************************************/
void Mantis_QuickSort(int A[],int chessman[],POINT targetpoint[],int low,int high)
{
	int pivot;
	int pivot_man;
	POINT pivot_point;
	int scanUp,scanDown;
	int mid,k;
	POINT point;
	if(high-low<=0)
	{
		return;
	}
	else
	{
		if(high-low==1)
		{
			if(A[high]>A[low])
			{
				k=A[high];
				A[high]=A[low];
				A[low]=k;
				k=chessman[high];
				chessman[high]=chessman[low];
				chessman[low]=k;
				point=targetpoint[high];
				targetpoint[high]=targetpoint[low];
				targetpoint[low]=point;
				return;
			}
		}
	}
	mid=(low +high)/2;
	pivot=A[mid];
	pivot_man=chessman[mid];
	pivot_point=targetpoint[mid];
	k=A[mid];
	A[mid]=A[low];
	A[low]=k;
	k=chessman[mid];
	chessman[mid]=chessman[low];
	chessman[low]=k;
	point=targetpoint[mid];
	targetpoint[mid]=targetpoint[low];
	targetpoint[low]=point;
	scanUp =low+1;
	scanDown = high;
	do{
		while(scanUp<=scanDown && A[scanUp]>=pivot)
			scanUp++;
		while(pivot>A[scanDown])
			scanDown--;
		if(scanUp<scanDown)
		{
			k=A[scanUp];
			A[scanUp]=A[scanDown];
			A[scanDown]=k;	
			k=chessman[scanUp];
			chessman[scanUp]=chessman[scanDown];
			chessman[scanDown]=k;
			point=targetpoint[scanUp];
			targetpoint[scanUp]=targetpoint[scanDown];
			targetpoint[scanDown]=point;
		}
	}while(scanUp<scanDown);
	A[low]=A[scanDown];
	A[scanDown]=pivot;
	chessman[low]=chessman[scanDown];
	chessman[scanDown]=pivot_man;
	targetpoint[low]=targetpoint[scanDown];
	targetpoint[scanDown]=pivot_point;

	if(low<scanDown-1)
		Mantis_QuickSort(A,chessman,targetpoint,low,scanDown-1);
	if(scanDown+1<high)
		Mantis_QuickSort(A,chessman,targetpoint,scanDown+1,high);
}

/******************************************************************
Value:			估值函数

参数:
tmap:			各棋位状态
tmanposition:	32棋子的坐标
tside:			轮到哪一放走

返回值:			局面的价值
******************************************************************/
int Value(int tmap[11][12],POINT tmanposition[32],int &tside)
{
	static int k;
	static int ManExtValue[32];
	static int ManBaseValue[32];
	static int ManContact[32][32];
	static int BeAteCount[32];
	static BOOL OwnSee[32];
	memset(ManContact,0,sizeof(int)<<10);
	memset(ManBaseValue,0,sizeof(int)<<5);
	memset(ManExtValue,0,sizeof(int)<<5);
	memset(BeAteCount,0,sizeof(int)<<5);
	memset(OwnSee,0,sizeof(int)<<5);
	int maxvalue=0;
	int i,j;
	ContactV(tmap,tmanposition,tside,ManBaseValue,ManContact);
//己方将军			
	for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
	{
		if(ManContact[i][FistOfSide[!tside]])
		{
			maxvalue=9700;
			return maxvalue;
		}
	}
	for(i=0;i<32;i++)
	{
		k=ManToType7[i];
		ManBaseValue[i]=BV1[k]+ManBaseValue[i]*BV2[k];
		switch(k)
		{	
		case 6:	ManBaseValue[i]+=BV3[ ManBPlus[SideOfMan[i]][tmanposition[i].y][tmanposition[i].x] ];
			break;
		}
	}
	for(i=0;i<32;i++)
	{
		for(j=0;j<32;j++)
		{
			if(ManContact[i][j])
			{
				if(SideOfMan[i]==SideOfMan[j])
				{
					BeAteCount[j]++;
					if(!OwnSee[j])
					{
						ManExtValue[i]+=ManBaseValue[j]*contactpercent1/100;//己方
						OwnSee[j]=TRUE;
					}
				}
				else
				{
					ManExtValue[i]+=ManBaseValue[j]*contactpercent2/100;//对方
					BeAteCount[j]--;
				}
			}
		}
	}
	for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
	{
		if(tmanposition[i].x)maxvalue+=ManBaseValue[i]+ManExtValue[i];			
	}
	static BOOL flag;
	flag=FALSE;k=32;		
	for(i=FistOfSide[!tside];i<=LastOfSide[!tside];i++)
	{
		if(tmanposition[i].x)maxvalue-=ManBaseValue[i]+ManExtValue[i];			
//对方将军
		if(ManContact[i][FistOfSide[tside]])
		{
			flag=TRUE;
			k=i;
			break;
		}
	}
	if(flag&&BeAteCount[k]>=0)//被将,所将军的棋子不能被吃掉
	{
		j=0;
		for(i=FistOfSide[tside];i<=LastOfSide[tside];i++)
		{
			if(BeAteCount[i]<0 && ManBaseValue[i]>j)
				j=ManBaseValue[i];
		}
		maxvalue -=j;
	}
	else
	{
		j=0;
		for(i=FistOfSide[!tside];i<=LastOfSide[!tside];i++)
		{
			if(BeAteCount[i]<0 && ManBaseValue[i]>j)
				j=ManBaseValue[i];
		}
		maxvalue +=j;
	}
	return maxvalue;
}

/******************************************************************
EnumList:		列出所有走法

参数:
tmap:			各棋位状态
tmanposition:	32棋子的坐标
tside:			轮到哪一放走
chessman:		指向棋子列表的指针(存放结果)
move:			指向棋子所走到位置的指针,与chessman一起组成走法列表
				(存放结果)
count:			走法的总数(存放结果)

返回值:			“照相”返回TRUE,否则返回FALSE
******************************************************************/
BOOL EnumList(int tmap[11][12],POINT tmanposition[32],int &tside,int *chessman,POINT *move,int &count)
{
	#define ADD(man,tx,ty) {chessman[count]=man;move[count].x=tx;move[count].y=ty;count++;if(tmap[tx][ty]==FistOfSide[!tside])goto _NOKING;}
	static int i,j,n,x,y;
	static BOOL	flag;
	count=0;
	for(n=FistOfSide[tside];n<=LastOfSide[tside];n++)
	{
		x=tmanposition[n].x;
		if(!x)continue;
		y=tmanposition[n].y;
		switch(n)
		{
		case 0:
			if(tmanposition[0].x==tmanposition[16].x)		//将帅在同一列
			{
				flag=FALSE;
				for(j=tmanposition[16].y+1;j<tmanposition[0].y;j++)
				{
					if(tmap[x][j]!=32)
					{
						flag=TRUE;
						break;
					}
				}
				if (!flag)	
				{
					ADD(0,x,tmanposition[16].y);
				}
			}
			j=y+1;if(j<=10 && NORED(x,j))	ADD(0,x,j)
			j=y-1;if(j>=8  && NORED(x,j))	ADD(0,x,j)
			i=x+1;if(i<=6  && NORED(i,y))	ADD(0,i,y)
			i=x-1;if(i>=4  && NORED(i,y))	ADD(0,i,y)
			break;
		case 16:
			if(tmanposition[0].x==tmanposition[16].x)		//将帅在同一列
			{
				flag=FALSE;
				for(j=tmanposition[16].y+1;j<tmanposition[0].y;j++)
				{
					if(tmap[x][j]!=32)
					{
						flag=TRUE;
						break;
					}
				}
				if (!flag)	
				{
					ADD(16,x,tmanposition[0].y);
				}
			}
			j=y+1;if(j<=3 && NOBLACK(x,j))	ADD(16,x,j)
			j=y-1;if(j>=1  && NOBLACK(x,j))	ADD(16,x,j)
			i=x+1;if(i<=6  && NOBLACK(i,y))	ADD(16,i,y)
			i=x-1;if(i>=4  && NOBLACK(i,y))	ADD(16,i,y)
			break;
		case 1:
		case 2:
			i=x+1;j=y+1;if(i<=6 && j<=10 && NORED(i,j))	ADD(n,i,j)
			i=x+1;j=y-1;if(i<=6 && j>=8  && NORED(i,j))	ADD(n,i,j)
			i=x-1;j=y+1;if(i>=4 && j<=10 && NORED(i,j))	ADD(n,i,j)
			i=x-1;j=y-1;if(i>=4 && j>=8  && NORED(i,j))	ADD(n,i,j)
			break;
		case 17:
		case 18:
			i=x+1;j=y+1;if(i<=6 && j<=3 && NOBLACK(i,j))	ADD(n,i,j)
			i=x+1;j=y-1;if(i<=6 && j>=1 && NOBLACK(i,j))	ADD(n,i,j)
			i=x-1;j=y+1;if(i>=4 && j<=3	&& NOBLACK(i,j))	ADD(n,i,j)
			i=x-1;j=y-1;if(i>=4 && j>=1 && NOBLACK(i,j))	ADD(n,i,j)
			break;
		case 3:
		case 4:
			i=x+2;j=y+2;if(i<=9 && j<=10   && NORED(i,j))	if(NOMAN(x+1,y+1))	ADD(n,i,j)
			i=x+2;j=y-2;if(i<=9 && j>=6    && NORED(i,j))	if(NOMAN(x+1,y-1))	ADD(n,i,j)
			i=x-2;j=y+2;if(i>=1 && j<=10   && NORED(i,j))	if(NOMAN(x-1,y+1))	ADD(n,i,j)
			i=x-2;j=y-2;if(i>=1 && j>=6    && NORED(i,j))	if(NOMAN(x-1,y-1))	ADD(n,i,j)
			break;
		case 19:
		case 20:
			i=x+2;j=y+2;if(i<=9 && j<=5  && NOBLACK(i,j))	if(NOMAN(x+1,y+1))	ADD(n,i,j)
			i=x+2;j=y-2;if(i<=9 && j>=1  && NOBLACK(i,j))	if(NOMAN(x+1,y-1))	ADD(n,i,j)
			i=x-2;j=y+2;if(i>=1 && j<=5  && NOBLACK(i,j))	if(NOMAN(x-1,y+1))	ADD(n,i,j)
			i=x-2;j=y-2;if(i>=1 && j>=1  && NOBLACK(i,j))	if(NOMAN(x-1,y-1))	ADD(n,i,j)
			break;
		case 5:
		case 6:
			i=x+1;
			if(NOMAN(i,y))
			{
				i=x+2;j=y+1;if(i<=9 && j<=10 && NORED(i,j))	ADD(n,i,j)
				i=x+2;j=y-1;if(i<=9 && j>=1  && NORED(i,j))	ADD(n,i,j)
			}
			i=x-1;
			if(NOMAN(i,y))
			{
				i=x-2;j=y+1;if(i>=1 && j<=10 && NORED(i,j))	ADD(n,i,j)
				i=x-2;j=y-1;if(i>=1 && j>=1  && NORED(i,j))	ADD(n,i,j)
			}
			j=y+1;
			if(NOMAN(x,j))
			{
				i=x+1;j=y+2;if(i<=9 && j<=10 && NORED(i,j))	ADD(n,i,j)
				i=x-1;j=y+2;if(i>=1 && j<=10 && NORED(i,j))	ADD(n,i,j)
			}
			j=y-1;
			if(NOMAN(x,j))
			{
				i=x+1;j=y-2;if(i<=9 && j>=1 && NORED(i,j))	ADD(n,i,j)
				i=x-1;j=y-2;if(i>=1 && j>=1 && NORED(i,j))	ADD(n,i,j)
			}
			break;
		case 21:
		case 22:
			i=x+1;
			if(NOMAN(i,y))
			{
				i=x+2;j=y+1;if(i<=9 && j<=10 && NOBLACK(i,j))	ADD(n,i,j)
				i=x+2;j=y-1;if(i<=9 && j>=1  && NOBLACK(i,j))	ADD(n,i,j)
			}
			i=x-1;
			if(NOMAN(i,y))
			{
				i=x-2;j=y+1;if(i>=1 && j<=10 && NOBLACK(i,j))	ADD(n,i,j)
				i=x-2;j=y-1;if(i>=1 && j>=1  && NOBLACK(i,j))	ADD(n,i,j)
			}
			j=y+1;
			if(NOMAN(x,j))
			{
				i=x+1;j=y+2;if(i<=9 && j<=10 && NOBLACK(i,j))	ADD(n,i,j)
				i=x-1;j=y+2;if(i>=1 && j<=10 && NOBLACK(i,j))	ADD(n,i,j)
			}
			j=y-1;
			if(NOMAN(x,j))
			{
				i=x+1;j=y-2;if(i<=9 && j>=1 && NOBLACK(i,j))	ADD(n,i,j)
				i=x-1;j=y-2;if(i>=1 && j>=1 && NOBLACK(i,j))	ADD(n,i,j)
			}
			break;

		case 7:
		case 8:
				i=x+1;
				while(i<=9)
				{
					if (NOMAN(i,y))	ADD(n,i,y)
					else
					{
						if(NORED(i,y))	ADD(n,i,y)
						break;
					}
					i++;
				}
				i=x-1;
				while(i>=1)
				{
					if (NOMAN(i,y))	ADD(n,i,y)
					else
					{
						if(NORED(i,y))	ADD(n,i,y)
						break;
					}
					i--;
				}
				j=y+1;
				while(j<=10)
				{
					if (NOMAN(x,j))	ADD(n,x,j)
					else
					{
						if(NORED(x,j))	ADD(n,x,j)
						break;
					}
					j++;
				}
				j=y-1;
				while(j>=1)
				{
					if (NOMAN(x,j))	ADD(n,x,j)
					else
					{
						if(NORED(x,j))	ADD(n,x,j)
						break;
					}
					j--;
				}
				break;
		case 23:
		case 24:
				i=x+1;
				while(i<=9)
				{
					if (NOMAN(i,y))	ADD(n,i,y)
					else
					{
						if(NOBLACK(i,y))	ADD(n,i,y)
						break;
					}
					i++;
				}
				i=x-1;
				while(i>=1)
				{
					if (NOMAN(i,y))	ADD(n,i,y)
					else
					{
						if(NOBLACK(i,y))	ADD(n,i,y)
						break;
					}
					i--;
				}
				j=y+1;
				while(j<=10)
				{
					if (NOMAN(x,j))	ADD(n,x,j)					
					else
					{
						if(NOBLACK(x,j))	ADD(n,x,j)
						break;
					}
					j++;
				}
				j=y-1;
				while(j>=1)
				{
					if (NOMAN(x,j))	ADD(n,x,j)
					else
					{
						if(NOBLACK(x,j))	ADD(n,x,j)
						break;
					}
					j--;
				}
				break;
		case 9:
		case 10:
			i=x+1;flag=FALSE;
			while(i<=9)
			{
				if(NOMAN(i,y))
				{
					if(!flag)	ADD(n,i,y)
				}
				else
				{
					if(!flag)flag=TRUE;
					else 
					{
						if(NORED(i,y))	ADD(n,i,y)
						break;
					}
				}
				i++;
			}

			i=x-1;flag=FALSE;
			while(i>=1)
			{
				if(NOMAN(i,y)) 
				{
					if(!flag)	ADD(n,i,y)
				}
				else
				{
					if(!flag)flag=TRUE;
					else 
					{
						if(NORED(i,y))	ADD(n,i,y)
						break;
					}
				}
				i--;
			}

			j=y+1;flag=FALSE;
			while(j<=10)
			{
				if(NOMAN(x,j)) 
				{
					if(!flag)	ADD(n,x,j)
				}
				else
				{
					if(!flag)flag=TRUE;
					else 
					{
						if(NORED(x,j))	ADD(n,x,j)
						break;
					}
				}
				j++;
			}

			j=y-1;flag=FALSE;
			while(j>=1)
			{
				if(NOMAN(x,j)) 
				{
					if(!flag)	ADD(n,x,j)
				}
				else
				{
					if(!flag)flag=TRUE;
					else 
					{
						if(NORED(x,j))	ADD(n,x,j)
						break;
					}
				}
				j--;
			}
			break;

		case 25:
		case 26:
			i=x+1;flag=FALSE;
			while(i<=9)
			{
				if(NOMAN(i,y))
				{
					if(!flag)	ADD(n,i,y)
				}
				else
				{
					if(!flag)flag=TRUE;
					else
					{
						if(NOBLACK(i,y))	ADD(n,i,y)
						break;
					}
				}
				i++;
			}

			i=x-1;flag=FALSE;
			while(i>=1)
			{
				if(NOMAN(i,y)) 
				{
					if(!flag)	ADD(n,i,y)
				}
				else
				{
					if(!flag)flag=TRUE;
					else 
					{
						if(NOBLACK(i,y))	ADD(n,i,y)
						break;
					}

⌨️ 快捷键说明

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