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