www.pudn.com > 1223456.rar > Eveluation.cpp


// 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 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
//下面两个常量数组存放了兵在不同位置的附加值 
//基本上是过河之后越靠近老将分值越高 
////红兵的附加值矩阵 
//const int BA0[10][9]= 
//{ 
//	{0,0,0,0,0,0,0,0,0}, 
//	{90,90,110,120,120,120,110,90,90}, 
//	{90,90,110,120,120,120,110,90,90}, 
//	{70,90,110,110,110,110,110,90,70}, 
//	{70,70,70, 70,70, 70, 70,70,70}, 
//	{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}, 
//}; 
// 
////黑卒的附加值矩阵 
//const int BA1[10][9]= 
//{ 
//	{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}, 
//	{70,70,70, 70,70, 70, 70,70,70}, 
//	{70,90,110,110,110,110,110,90,70}, 
//	{90,90,110,120,120,120,110,90,90}, 
//	{90,90,110,120,120,120,110,90,90}, 
//	{0,0,0,0,0,0,0,0,0}, 
//}; 
 
//红兵的附加值矩阵 
const int BA0[10][9]= 
{ 
	{0,0,0,0,0,0,0,0,0}, 
	{120,120,140,150,150,150,140,120,120}, 
	{120,120,140,150,150,150,140,120,120}, 
	{100,120,140,140,140,140,140,120,100}, 
	{100,100,100,100,100,100,100,100,100}, 
	{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}, 
}; 
 
//黑卒的附加值矩阵 
const int BA1[10][9]= 
{ 
	{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}, 
	{100,100,100,100,100,100,100,100,100}, 
	{100,120,140,140,140,140,140,120,100}, 
	{120,120,140,150,150,150,140,120,120}, 
	{120,120,140,150,150,150,140,120,120}, 
	{0,0,0,0,0,0,0,0,0}, 
}; 
 
int CEveluation::GetBingValue(int x,int y,BYTE CurSituation[][9]) 
{ 
	if(CurSituation[y][x]==R_PAWN) 
		return BA0[y][x]; 
 
	if(CurSituation[y][x]==B_PAWN) 
		return BA1[y][x]; 
 
	return 0; 
} 
 
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; 
 
	m_nAccessCount=0; 
} 
 
CEveluation::~CEveluation() 
{ 
 
} 
 
int CEveluation::Eveluate(BYTE position[][9], BOOL bIsRedTurn,int nUserChessColor) 
{ 
	int i,j,k; 
	int nChessType,nTargetType; 
	 
	m_nAccessCount++;//每调用一次就增加一次 
 
	//初始化 
	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(position[i][j]!=NOCHESS) 
			{ 
				nChessType=position[i][j];   //取棋子类型 
				GetRelatePiece(position,j,i);//找出该棋子所有相关位置 
				for(k=0;k=0 && CanTouch(position,j,i,x,y)) 
			AddPoint(x,y); 
 
		//左下 
		x=j-2; 
		y=i+2; 
		if(x>=0 && y<10 && CanTouch(position,j,i,x,y)) 
			AddPoint(x,y); 
 
		//左上 
		x=j-2; 
		y=i-2; 
		if(x>=0 && y>=0 && CanTouch(position,j,i,x,y)) 
			AddPoint(x,y); 
 
		break; 
 
		case R_HORSE://红马 
		case B_HORSE://黑马 
			//检查右下方能否到达/保护 
			x=j+2; 
			y=i+1; 
			if((x<9 && y<10)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查右上方能否到达/保护 
			x=j+2; 
			y=i-1; 
			if((x<9 && y>=0)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查左下方能否到达/保护 
			x=j-2; 
			y=i+1; 
			if((x>=0 && y<10)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查左上方能否到达/保护 
			x=j-2; 
			y=i-1; 
			if((x>=0 && y>=0)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查右下方能否到达/保护 
			x=j+1; 
			y=i+2; 
			if((x<9 && y<10)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查右上方能否到达/保护 
			x=j+1; 
			y=i-2; 
			if((x<9 && y>=0)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查左下方能否到达/保护 
			x=j-1; 
			y=i+2; 
			if((x>=0 && y<10)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			//检查左上方能否到达/保护 
			x=j-1; 
			y=i-2; 
			if((x>=0 && y>=0)&&CanTouch(position,j,i,x,y)) 
				AddPoint(x,y); 
 
			break; 
 
		case R_CAR://红车 
		case B_CAR://黑车 
			//检查向右能否到达/保护 
			x=j+1; 
			y=i; 
			while(x<9) 
			{ 
				if(NOCHESS==position[y][x])//空白 
					AddPoint(x,y); 
				else{ 
					//碰到第一个棋子 
					AddPoint(x,y); 
					break;//后面的位置不能走了 
				} 
				x++; 
			} 
 
			//检查向左能否到达/保护 
			x=j-1; 
			y=i; 
			while(x>=0) 
			{ 
				if(NOCHESS==position[y][x])//空白 
					AddPoint(x,y); 
				else{ 
					//碰到第一个棋子 
					AddPoint(x,y); 
					break;//后面的位置不能走了 
				} 
				x--; 
			} 
 
			//检查向下能否到达/保护 
			x=j; 
			y=i+1; 
			while(y<10) 
			{ 
				if(NOCHESS==position[y][x])//空白 
					AddPoint(x,y); 
				else{ 
					//碰到第一个棋子 
					AddPoint(x,y); 
					break;//后面的位置不能走了 
				} 
				y++; 
			} 
 
			//检查向上能否到达/保护 
			x=j; 
			y=i-1; 
			while(y>=0) 
			{ 
				if(NOCHESS==position[y][x])//空白 
					AddPoint(x,y); 
				else{ 
					//碰到第一个棋子 
					AddPoint(x,y); 
					break;//后面的位置不能走了 
				} 
				y--; 
			} 
 
			break; 
 
		case R_PAWN://红兵 
			//观看向前是否到底 
			y=i-1; 
			x=j; 
			if(y>=0) 
				AddPoint(x,y);//没到底,可走 
			if(i<5) 
			{ 
				//如已过河 
				y=i; 
				x=j+1;//向右 
				if(x<9) 
					AddPoint(x,y);//未到右边,可走 
				x=j-1;//向左 
				if(x>=0) 
					AddPoint(x,y);//未到左边,可走 
			} 
 
			break; 
 
		case B_PAWN://黑卒 
			//观看向前是否到底 
			y=i+1; 
			x=j; 
			if(y<10) 
				AddPoint(x,y);//没到底,可走 
			if(i>4) 
			{ 
				//如已过河 
				y=i; 
				x=j+1;//向右 
				if(x<9) 
					AddPoint(x,y);//未到右边,可走 
				x=j-1;//向左 
				if(x>=0) 
					AddPoint(x,y);//未到左边,可走 
			} 
 
			break; 
 
		case B_CANON://黑炮 
		case R_CANON://红炮 
			//检查向右能否到达/保护的位置 
			x=j+1; 
			y=i; 
			flag=FALSE; 
			while(x<9) 
			{ 
				if(NOCHESS==position[y][x]) 
				{ 
					//空白位置 
					if(!flag) 
						AddPoint(x,y); 
				} 
				else 
				{ 
					if(!flag) 
						flag=TRUE;//是第一个棋子 
					else 
					{ 
						//是第二个棋子 
						AddPoint(x,y); 
						break; 
					} 
				} 
				x++;//继续向右 
			} 
 
			//检查向左能否到达/保护的位置 
			x=j-1; 
			y=i; 
			flag=FALSE; 
			while(x>=0) 
			{ 
				if(NOCHESS==position[y][x]) 
				{ 
					//空白位置 
					if(!flag) 
						AddPoint(x,y); 
				} 
				else 
				{ 
					if(!flag) 
						flag=TRUE;//是第一个棋子 
					else 
					{ 
						//是第二个棋子 
						AddPoint(x,y); 
						break; 
					} 
				} 
				x--;//继续向左 
			} 
 
			//检查向下能否到达/保护的位置 
			x=j; 
			y=i+1; 
			flag=FALSE; 
			while(y<10) 
			{ 
				if(NOCHESS==position[y][x]) 
				{ 
					//空白位置 
					if(!flag) 
						AddPoint(x,y); 
				} 
				else 
				{ 
					if(!flag) 
						flag=TRUE;//是第一个棋子 
					else 
					{ 
						//是第二个棋子 
						AddPoint(x,y); 
						break; 
					} 
				} 
				y++;//继续向下 
			} 
 
			//检查向上能否到达/保护的位置 
			x=j; 
			y=i-1; 
			flag=FALSE; 
			while(y>=0) 
			{ 
				if(NOCHESS==position[y][x]) 
				{ 
					//空白位置 
					if(!flag) 
						AddPoint(x,y); 
				} 
				else 
				{ 
					if(!flag) 
						flag=TRUE;//是第一个棋子 
					else 
					{ 
						//是第二个棋子 
						AddPoint(x,y); 
						break; 
					} 
				} 
				y--;//继续向上 
			} 
 
			break; 
 
		default: 
			break; 
		} 
 
	return nPosCount; 
} 
 
bool CEveluation::CanTouch(BYTE position[][9], int nFromX, int nFromY, int nToX, int nToY) 
{ 
	int i,j; 
	int nMoveChessID,nTargetID; 
 
	if(nFromX==nToX && nFromY==nToY) 
		return false;//目的与源相同,非法 
 
	nMoveChessID=position[nFromX][nFromY]; 
	nTargetID=position[nToX][nToY]; 
 
	if(IsSameSide(nMoveChessID,nTargetID)) 
		return false;//吃自己的棋,非法 
 
	switch(nMoveChessID) 
	{ 
	case B_KING://黑将 
		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;//将帅只走一步直线 
		} 
 
		break; 
 
	case R_KING://红帅 
		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;//将帅只走一步直线 
		} 
 
		break; 
 
	case R_BISHOP://红士 
		if(nToY<7 || nToX>5 || nToX<3) 
			return false;//士出九宫 
 
		if(abs(nFromX-nToX)!=1 || abs(nFromY-nToY)!=1) 
			return false;//士走斜线 
 
		break; 
 
	case B_BISHOP://黑士 
		if(nToY>2 || nToX>5 || nToX<3) 
			return false;//士出九宫 
 
		if(abs(nFromX-nToX)!=1 || abs(nFromY-nToY)!=1) 
			return false;//士走斜线 
 
		break; 
 
	case R_ELEPHANT://红相 
		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_ELEPHANT://黑象 
		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_PAWN://黑卒 
		if(nToY1) 
			return FALSE;//卒只走一步直线 
 
		break; 
 
	case R_PAWN://红兵 
		if(nToY4 && nFromY==nToY) 
			return FALSE;//兵过河前只能直走 
 
		if(nToY-nFromY+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