📄 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
#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 + -