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

📄 eveluation.cpp

📁 一个简单的象棋游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Eveluation.cpp: implementation of the CEveluation class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "chess.h"
#include "Eveluation.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define IsBlack(x) (x>=B_BEGIN&&x<=B_END)
#define IsRed(x)   (x>=R_BEGIN&&x<=R_END)
#define lsSameSide(x,y) ((IsBlack(x)&&IsBlack(y))||(IsRed(x)&&IsRed(y)))
//#include "SetChess.h"
/////////
#define NOCHESS   0
#define B_KING 1 //  将
#define B_CAR  2  //车
#define B_HORSE 3  // 马
#define B_CANON 4  //  炮
#define B_BISHOP  5//士
#define B_ELEPHANT  6//象
#define B_PAWN    7//兵
#define R_KING 8//  将
#define R_CAR  9  //车
#define R_HORSE 10  // 马
#define R_CANON 11  //  炮
#define R_BISHOP  12//士
#define R_ELEPHANT 13//象
#define R_PAWN    14//兵
#define B_BEGIN B_KING
#define B_END B_PAWN
#define R_BEGIN R_KING
#define R_END R_PAWN
/////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CEveluation::CEveluation()
{
	//初始化基本价值
	m_BaseValue[B_KING]=BASEVALUE_KING;
	m_BaseValue[B_CAR]=BASEVALUE_CAR;
	m_BaseValue[B_HORSE]=BASEVALUE_HORSE;
	m_BaseValue[B_BISHOP]=BASEVALUE_BISHOP;
	m_BaseValue[B_ELEPHANT]=BASEVALUE_ELEPHANT;
	m_BaseValue[B_CANON]=BASEVALUE_CANON;
	m_BaseValue[B_PAWN]=BASEVALUE_PAWN;
	m_BaseValue[R_KING]=BASEVALUE_KING;
	m_BaseValue[R_CAR]=BASEVALUE_CAR;
	m_BaseValue[R_HORSE]=BASEVALUE_HORSE;
	m_BaseValue[R_BISHOP]=BASEVALUE_BISHOP;
	m_BaseValue[R_ELEPHANT]=BASEVALUE_ELEPHANT;
	m_BaseValue[R_CANON]=BASEVALUE_CANON;
	m_BaseValue[R_PAWN]=BASEVALUE_PAWN;
	//初始化灵活性
	m_FlexValue[B_KING]=FLEXIBILITY_KING;
	m_FlexValue[B_CAR]=FLEXIBILITY_CAR;
	m_FlexValue[B_HORSE]=FLEXIBILITY_HORSE;
	m_FlexValue[B_BISHOP]=FLEXIBILITY_BISHOP;
	m_FlexValue[B_ELEPHANT]=FLEXIBILITY_ELEPHANT;
	m_FlexValue[B_CANON]=FLEXIBILITY_CANON;
	m_FlexValue[B_PAWN]=FLEXIBILITY_PAWN;
	m_FlexValue[R_KING]=FLEXIBILITY_KING;
	m_FlexValue[R_CAR]=FLEXIBILITY_CAR;
	m_FlexValue[R_HORSE]=FLEXIBILITY_HORSE;
	m_FlexValue[R_BISHOP]=FLEXIBILITY_BISHOP;
	m_FlexValue[R_ELEPHANT]=FLEXIBILITY_ELEPHANT;
	m_FlexValue[R_CANON]=FLEXIBILITY_CANON;
	m_FlexValue[R_PAWN]=FLEXIBILITY_PAWN;
	//////

}
int count=0;//这是一个全局变量,用以记录调用了估值函数的叶子结点的个数
CEveluation::~CEveluation()
{

}

int CEveluation::Eveluate(int board[][9], bool blsRedTurn)
{
	//给出横坐标和纵坐标
	/*GetRelatePiece(board,1,2);
	GetRelatePiece(board,7,2);
	GetRelatePiece(board,4,8);
	GetRelatePiece(board,7,7);*/
	int i,j,k;
	int nChessType,nTargeType;
	count++;
	memset(m_ChessValue,0,360);
	memset(m_AttackPos,0,180);
	memset(m_GuardPos,0,90);
	memset(m_FlexiBilityPos,0,90);
	//扫描棋盘,找出每一个棋子,及其威胁/保护的棋子,还有其灵活性
	for(i=0;i<10;i++)
		for(j=0;j<9;j++)
		{
			if(board[i][j]!=NOCHESS)
			{
				nChessType=board[i][j];
				//fp=fopen("mid1.txt","w+");
				GetRelatePiece(board,j,i);
				for(k=0;k<nPosCount;k++)
				{
					//取目标棋子的类型
					nTargeType=board[RelatPos[k].y][RelatPos[k].x];
					if(nTargeType==NOCHESS)
						m_FlexiBilityPos[i][j]++;
					else
					{//是棋子
						if(lsSameSide(nChessType,nTargeType))
						{///受到保护
							m_GuardPos[RelatPos[k].y][RelatPos[k].x]++;
						}
						else
						{//受到威胁
							m_AttackPos[RelatPos[k].y][RelatPos[k].x]++;
							m_FlexiBilityPos[i][j]++;
							switch(nTargeType)
							{
							case R_KING:
								if(!blsRedTurn)
								{
									//strText.Format("%d    %d \n",nChessType,nTargeType);
									//fwrite(strText,sizeof(char),strText.GetLength(),fp);
									return 18888;
								}
								break;
							case B_KING:
								if(blsRedTurn)
								{
									//strText.Format("%d    %d \n",nChessType,nTargeType);
									//fwrite(strText,sizeof(char),strText.GetLength(),fp);
									return 18888;
								}
								break;
							default://不是将的棋
								//根据威胁的棋子加上其威胁值
								m_AttackPos[RelatPos[k].y][RelatPos[k].x]+=
									(30+(m_BaseValue[nTargeType]-m_BaseValue[nChessType])/10)/10;
								break;
							}
						}
					}
				}
			}
		}
		//以上扫描棋盘部分
		//下面统计扫描到的数据
		for(i=0;i<10;i++)
			for(j=0;j<9;j++)
			{
				if(board[i][j]!=NOCHESS)
				{
					nChessType=board[i][j];
					m_ChessValue[i][j]++;
					//把每个棋子的灵活性价值加进棋子的基本价值
					m_ChessValue[i][j]+=m_FlexValue[nChessType]*m_FlexiBilityPos[i][j];
					//加上兵的位置附加值
					m_ChessValue[i][j]+=GetBinValue(i,j,board);
				}
			}
		//下面的循环继续统计扫描的数据
	    int nHalfValue;
		for(i=0;i<10;i++)
			for(j=0;j<9;j++)
			{
				if(board[i][j]!=NOCHESS)
				{
					nChessType=board[i][j];
					//棋子价值的1/16作为其保护威胁增量
					nHalfValue=m_BaseValue[nChessType]/16;
					//把每个棋子的基本价值加入其总价值
					m_ChessValue[i][j]+=m_BaseValue[nChessType];
					if(IsRed(nChessType))
					{
						if(m_AttackPos[i][j])//受到威胁
						{
							if(blsRedTurn)
							{
								if(nChessType==R_KING)
								{
									m_ChessValue[i][j]-=20;
								}
								else
								{
									//价值减去二倍nHalfValue
									m_ChessValue[i][j]-=nHalfValue*4;
									if(m_GuardPos[i][j])
									{
										m_ChessValue[i][j]+=nHalfValue;
									}
								}
							}
							else
							{
								//当前红棋被威胁,轮到黑棋走
								if(nChessType==R_KING)
								{
									//strText.Format("%d    %d \n",nChessType,nTargeType);
									//fwrite(strText,sizeof(char),strText.GetLength(),fp);
									return 18888;
								}
								//减去10倍的nHalfValue表示威胁的程度高
								m_ChessValue[i][j]-=nHalfValue*16;
								if(m_GuardPos[i][j])
									m_ChessValue[i][j]+=nHalfValue*9;
							}
							//被威胁的棋子加入威胁差,防止一个兵威胁
						    //一个被保护的车,而估值函数没有反映的问题
							m_ChessValue[i][j]-=m_AttackPos[i][j];
						}
						else
						{//没受威胁加一点分
							if(m_GuardPos[i][j])
								m_ChessValue[i][j]+=5;
						}
					}
					else
					{//如果是黑棋
						if(m_AttackPos[i][j])//受到威胁
						{
							if(!blsRedTurn)
							{
								if(nChessType==B_KING)
								{
									m_ChessValue[i][j]-=20;
								}
								else
								{
									//价值减去二倍nHalfValue
									m_ChessValue[i][j]-=nHalfValue*4;
									if(m_GuardPos[i][j])
									{
										m_ChessValue[i][j]+=nHalfValue;
									}
								}
							}
							else
							{
								//当前黑棋被威胁,轮到红棋走
								if(nChessType==B_KING)
								{
									//strText.Format("%d    %d \n",nChessType,nTargeType);
									//fwrite(strText,sizeof(char),strText.GetLength(),fp);
									return 18888;
								}
								//减去10倍的nHalfValue表示威胁的程度高
								m_ChessValue[i][j]-=nHalfValue*16;
								if(m_GuardPos[i][j])
									m_ChessValue[i][j]+=nHalfValue*9;
							}
							//被威胁的棋子加入威胁差,防止一个兵威胁
						    //一个被保护的车,而估值函数没有反映的问题
							m_ChessValue[i][j]-=m_AttackPos[i][j];
						}
						else
						{//没受威胁加一点分
							if(m_GuardPos[i][j])
								m_ChessValue[i][j]+=5;
						}
					}
				}
			}
			//以上生成统计了每一个棋子的总价值
			//下面统计红黑两方总分
			int nRedValue=0;
			int nBlackValue=0;
			for(i=0;i<10;i++)
				for(j=0;j<9;j++)
				{
					nChessType=board[i][j];
					if(nChessType!=NOCHESS)
					{
						if(IsRed(nChessType))
							nRedValue+=m_ChessValue[i][j];
						else
							nBlackValue+=m_ChessValue[i][j];
					}
				}
	if(blsRedTurn)
		return nRedValue-nBlackValue;//轮到红棋走,返回正的估值
	else
		return nBlackValue-nRedValue;//轮到黑棋走,返回负的估值

}
//这个函数枚举了给定位置上棋子的所有相关位置
//包括可走到的位置和可保护的位置
//board是当前棋盘
//i是棋子的横坐标, j是棋子的纵坐标
int CEveluation::GetRelatePiece(int board[][9], int i, int j)
{
	nPosCount=0;
	int nChessID;
	bool flag;
	int x,y;
	nChessID=board[j][i];
	switch(nChessID)
	{
	case R_KING:
	case B_KING:
		for(y=0;y<3;y++)
		{
			for(x=3;x<6;x++)
			{
				if(CanTouch(i,j,x,y))
					AddPoint(x,y);
			}
		}
		for(y=7;y<10;y++)
		{
			for(x=3;x<6;x++)
			{
				if(CanTouch(i,j,x,y))
					AddPoint(x,y);
			}
		}
		break;
	case R_BISHOP:
		for(y=7;y<10;y++)
		{
			for(x=3;x<6;x++)
			{
				if(CanTouch(i,j,x,y))
					AddPoint(x,y);
			}
		}
		break;
	case B_BISHOP:
		for(y=0;y<3;y++)
		{
			for(x=3;x<6;x++)
			{
				if(CanTouch(i,j,x,y))
					AddPoint(x,y);
			}
		}
		break;
	case R_ELEPHANT:
	case B_ELEPHANT:
		//右下
		x=i+2;
		y=j+2;
		if(x<9&&y<10&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i-2;
		y=j+2;
		if(x>=0&&y<10&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i+2;
		y=j-2;
		if(x<9&&y>=0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i-2;
		y=j-2;
		if(x>=0&&y>=0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		break;
	case R_HORSE:
	case B_HORSE:
		x=i+2;
		y=j+1;
		if(x<9&&y<10&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i+2;
		y=j-1;
		if(x<9&&y>=0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i-2;
		y=j+1;
		if(x>=0&&y<10&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i-2;
		y=j-1;
		if(x>=0&&y>=0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i+1;
		y=j+2;
		if(x<9&&y<10&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i-1;
		y=j+2;
		if(x<9&&y>0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i+1;
		y=j-2;
		if(x<9&&y>0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		x=i-1;
		y=j-2;
		if(x<9&&y>0&&CanTouch(i,j,x,y))
			AddPoint(x,y);
		break;
	case R_CAR:
	case B_CAR:
		//检查向右可走的位置
		x=i+1;
		y=j;
		while(x<9)
		{
			if(board[y][x]==NOCHESS)
				AddPoint(x,y);
			else
			{
				//if(!lsSameSide(nChessID,board[y][x]))
					AddPoint(x,y);
				break;
			}
			x++;
		}
		x=i-1;
		y=j;
		while(x>=0)
		{
			if(board[y][x]==NOCHESS)
				AddPoint(x,y);
			else
			{
				//if(!lsSameSide(nChessID,board[y][x]))
					AddPoint(x,y);
				break;
			}
			x--;
		}
		x=i;
		y=j+1;
		while(y<10)
		{
			if(board[y][x]==NOCHESS)
				AddPoint(x,y);
			else
			{
				//if(!lsSameSide(nChessID,board[y][x]))
					AddPoint(x,y);

⌨️ 快捷键说明

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