?? 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<nPosCount;k++) //對每一目標位置
{
nTargetType=position[RelatePos[k].y][RelatePos[k].x];//取目標棋子類型
if(nTargetType==NOCHESS)//如果是空白,靈活性增加
m_FlexibilityPos[i][j]++;
else//有棋子
{
if(IsSameSide(nChessType,nTargetType))
{
//己方棋子,目標受保護
m_GuardPos[RelatePos[k].y][RelatePos[k].x]++;
}
else
{
//敵方棋子,目標受威脅
m_AttackPos[RelatePos[k].y][RelatePos[k].x]++;
m_FlexibilityPos[i][j]++;//靈活性增加
switch(nTargetType)
{
case R_KING://紅帥
if(!bIsRedTurn)//輪到黑棋走
return 18888;//返回失敗極值
break;
case B_KING://黑將
if(bIsRedTurn)//輪到紅棋走
return 18888;//返回失敗極值
break;
default:
//根據威脅的棋子加上威脅分值
m_AttackPos[RelatePos[k].y][RelatePos[k].x]+=(30 +(m_BaseValue[nTargetType]- m_BaseValue[nChessType])/10)/10;
break;
}
}
}
}
}
}
//下面的循環統計掃描到的數據
for(i=0;i<10;i++)
for(j=0;j<9;j++)
{
if(position[i][j]!=NOCHESS)
{
nChessType=position[i][j];
m_chessValue[i][j]++;
//如果棋子存在其價值不為0,把每一棋子的靈活性價值加進棋子價值
m_chessValue[i][j]+=m_FlexValue[nChessType]*m_FlexibilityPos[i][j];
//加上兵的附加值
m_chessValue[i][j]+=GetBingValue(j,i,position);
}
}
//下面的循環繼續統計掃描到的數據
int nHalfvalue;
for(i=0;i<10;i++)
for(j=0;j<9;j++)
{
if(position[i][j]!=NOCHESS)
{
nChessType=position[i][j];
nHalfvalue=m_BaseValue[nChessType]/16; //棋子基本價值的1/16作為威脅/保護增量
m_chessValue[i][j]+=m_BaseValue[nChessType];//每個棋子的基本價值加入其總價值
if(IsRed(nChessType))//紅棋
{
if(m_AttackPos[i][j])//當前紅棋如果被威脅
{
if(bIsRedTurn)//輪到紅棋走
{
if(nChessType==R_KING)//如果是紅將
m_chessValue[i][j]-=20;//價值降低20
else
{
//價值減去2倍nHalfvalue
m_chessValue[i][j]-=nHalfvalue*2;
if(m_GuardPos[i][j])//是否被己方棋子保護
m_chessValue[i][j]+=nHalfvalue;//被保護再加上nHalfvalue
}
}
else//當前紅棋被威脅,輪到黑棋走
{
if(nChessType==R_KING)//是否是紅帥
return 18888;//返回失敗極值
m_chessValue[i][j]-=nHalfvalue*10;//減去10倍的nHalfvalue,表示威脅程度高
if(m_GuardPos[i][j])//如果被保護
m_chessValue[i][j]+=nHalfvalue*9;//被保護再加上9倍的nHalfvalue
}
//被威脅的棋子加上威脅差,防止一個兵威脅
//一個被保護的車,而估值函數沒有反映此類問題
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(!bIsRedTurn)
{
//輪到黑棋走
if(nChessType==B_KING)//如果是黑將
m_chessValue[i][j]-=20;//棋子價值降低20
else
{
//棋子價值降低2倍nHalfvalue
m_chessValue[i][j]-=nHalfvalue*2;
if(m_GuardPos[i][j])//如果受保護
m_chessValue[i][j] +=nHalfvalue;//棋子價值增加nHalfvalue
}
}
else
{
//輪到紅棋走
if(nChessType==B_KING)//是黑將
return 18888;//返回失敗極值
m_chessValue[i][j]-=nHalfvalue*10;//棋子價值減少10倍nHalfvalue
if(m_GuardPos[i][j])//受保護
m_chessValue[i][j]+=nHalfvalue*9;//被保護再加上9倍nHalfvalue
}
//被威脅的棋子再加上威脅差
//防止一個兵威脅一個被保護的車,而估值函數沒有反映此類的問題
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=position[i][j];
if(nChessType!=NOCHESS)
{
if(IsRed(nChessType))
nRedValue+=m_chessValue[i][j]; //把紅棋的值加總
else
nBlackValue+=m_chessValue[i][j];//把紅棋的值加總
}
}
if(nUserChessColor==REDCHESS)
{
if(bIsRedTurn)
return nRedValue-nBlackValue;//如果輪到紅棋走返回估值
return nBlackValue-nRedValue;//如果輪到黑棋走返回負估值
}
if(bIsRedTurn)
return nBlackValue-nRedValue;//如果輪到黑棋走返回負估值
return nRedValue-nBlackValue;//如果輪到紅棋走返回估值
}
int CEveluation::GetRelatePiece(BYTE position[][9], int j, int i)
{
nPosCount=0;
BYTE nChessID;
BYTE flag;
int x,y;
nChessID=position[i][j];
switch(nChessID)
{
case R_KING://紅帥
case B_KING://黑將
//循環檢查九宮之內哪些位置可到達/保護
//掃描兩邊就宮包含了照像的情況
for(y=0;y<3;y++)
for(x=3;x<6;x++)
if(CanTouch(position,j,i,x,y))//能否到達
AddPoint(x,y);//可達到/保護的位置加入數組
//循環檢查九宮之內哪些位置可到達/保護
//掃描兩邊就宮包含了照像的情況
for(y=7;y<10;y++)
for(x=3;x<6;x++)
if(CanTouch(position,j,i,x,y))//能否到達
AddPoint(x,y);//可達到/保護的位置加入數組
break;
case R_BISHOP://紅士
//循環檢查九宮之內哪些位置可到達/保護
for(y=7;y<10;y++)
for(x=3;x<6;x++)
if(CanTouch(position,j,i,x,y))
AddPoint(x,y);//可達到/保護的位置加入數組
break;
case B_BISHOP://黑士
//循環檢查九宮之內哪些位置可到達/保護
for(y=0;y<3;y++)
for(x=3;x<6;x++)
if(CanTouch(position,j,i,x,y))
AddPoint(x,y);//可達到/保護的位置加入數組
break;
case R_ELEPHANT://紅相
case B_ELEPHANT://黑象
//右下
x=j+2;
y=i+2;
if(x<9 && y<10 && CanTouch(position,j,i,x,y))
AddPoint(x,y);
//右上
x=j+2;
y=i-2;
if(x<9 && y>=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--;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -