📄 evalu.cpp
字号:
// ObjectWindows - (C) Copyright 1992 by Borland International
#include <math.h>
#include "wcdefs.h"
#include "externs.h"
MAXTYPE RootValue;
BOARDTYPE Board[0x78];
#undef max
#undef min
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define TOLERANCE 8 /* Tolerance width */
#define EXCHANGEVALUE 32
/* Value for exchanging pieces when ahead (not pawns) */
#define ISOLATEDPAWN 20
/* Isolated pawn. Double isolated pawn is 3 * 20 */
#define DOUBLEPAWN 8 /* Double pawn */
#define SIDEPAWN 6 /* Having a pawn on the side */
#define CHAINPAWN 3 /* Being covered by a pawn */
#define COVERPAWN 3 /* covering a pawn */
#define NOTMOVEPAWN 2 /* Penalty for moving pawn */
#define BISHOPBLOCKVALUE 20
/* Penalty for bishop blocking d2/e2 pawn */
#define ROOKBEHINDPASSPAWN 16 /* Bonus for Rook behind passed pawn */
typedef unsigned char FILETYPE; /* file numbers */
typedef unsigned char RANKTYPE; /* rank numbers */
typedef unsigned char SETOFFILE;
typedef struct
{
SETOFFILE one, dob;
} PAWNBITTYPE[2];
/*
* Global variables for this module
*/
int PieceValue[7] = {0, 0x1000, 0x900, 0x4c0, 0x300, 0x300, 0x100};
const char distan[8] = { 3, 2, 1, 0, 0, 1, 2, 3 };
/* The value of a pawn is the sum of Rank and file values.
The file value is equal to PawnFileFactor * (Rank Number + 2) */
const char pawnrank[8] = {0, 0, 0, 2, 4, 8, 30, 0};
const char passpawnrank[8] = {0, 0, 10, 20, 40, 60, 70, 0};
const char pawnfilefactor[8] = {0, 0, 2, 5, 6, 2, 0, 0};
const char castvalue[2] = {4, 32}; /* Value of castling */
const SETOFFILE filebittab[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
PAWNBITTYPE pawnbitt[MAXPLY + 2];
PAWNBITTYPE *pawnbit = &pawnbitt[1];
int totalmaterial, pawntotalmaterial, material;
/* Material level of the game
(early middlegame = 43 - 32, endgame = 0) */
int materiallevel;
const unsigned char squarerankvalue[8] = { 0, 0, 0, 0, 1, 2, 4, 4};
COLORTYPE tempcolor;
int temp, temp2; /* temporary junk */
/*
* count the number of set bits in b
*/
static int count(SETOFFILE b)
{
char cnt = 0;
while (b)
{
if (b % 2 == 1) cnt++;
b >>= 1;
}
return cnt;
}
/*
* Calculate value of the pawn structure in pawnbit[depth][color]
*/
static int pawnstrval(DEPTHTYPE depth, COLORTYPE color)
{
SETOFFILE iso; /* contains FILEs with isolated pawns */
iso = pawnbit[depth][color].one &
~((pawnbit[depth][color].one << 1) | (pawnbit[depth][color].one
>> 1));
return (-(count(pawnbit[depth][color].dob) * DOUBLEPAWN +
count(iso) * ISOLATEDPAWN + count(iso &
pawnbit[depth][color].dob) * ISOLATEDPAWN * 2));
}
/*
* calculate the value of the piece on the square
*/
inline int PiecePosVal(PIECETYPE piece, COLORTYPE color, SQUARETYPE square)
{
return (PieceValue[piece] + PVTable[color][piece][square]);
}
short mating; /* mating evaluation function is used */
/*
* calculates piece-value table for the static evaluation function
*/
void CalcPVTable(void)
{
typedef SETOFFILE PAWNTABTYPE[8];
PAWNTABTYPE pawntab[2];
/* Bit tables for static pawn structure evaluation */
SETOFFILE pawnfiletab, bit, oppasstab, behindoppass,
leftsidetab, rightsidetab, sidetab, leftchaintab,
rightchaintab, chaintab, leftcovertab, rightcovertab;
/* Importance of an attack of the square */
char attackvalue[2][0x78];
/* Value of squares controlled from the square */
int pvcontrol[2][5][0x78];
COLORTYPE losingcolor; /* the color which is being mated */
int posval; /* The positional value of piece */
int attval; /* The attack value of the square */
FILETYPE line; /* The file of the piece */
RANKTYPE rank; /* The rank of the piece */
char dist, kingdist; /* Distance to center, to opponents king */
CASTTYPE cast; /* Possible castlings */
short direct; /* Indicates direct attack */
int cnt; /* Counter for attack values */
int strval; /* Pawnstructure value */
COLORTYPE color, oppcolor; /* Color and opponents color */
PIECETYPE piececount; /* Piece counter */
SQUARETYPE square; /* Square counter */
DIRTYPE dir; /* Direction counter */
EDGESQUARETYPE sq; /* Square counter */
int temp, temp2; /* temporary junk */
/* Calculate SAMMAT, PAWNSAMMAT and Material */
material = pawntotalmaterial = totalmaterial = mating = 0;
for (square = 0; square < 0x78; square++)
if (!(square & 0x88))
if (Board[square].piece != empty)
if (Board[square].piece != king)
{
temp = PieceValue[Board[square].piece];
totalmaterial += temp;
if (Board[square].piece == pawn)
pawntotalmaterial += PieceValue[pawn];
if (Board[square].color == white) temp = -temp;
material -= temp;
}
materiallevel = max(0, totalmaterial - 0x2000) / 0x100;
/* Set mating if weakest player has less than the equivalence
of two bishops and the advantage is at least a rook for a bishop */
if (material < 0)
losingcolor = white;
else
losingcolor = black;
mating = ((totalmaterial - abs(material)) / 2 <= PieceValue[bishop] * 2)
&& (abs(material) >= PieceValue[rook] - PieceValue[bishop]);
/* Calculate ATTACKVAL (importance of each square) */
for (rank = 0; rank < 8; rank++)
for (line = 0; line < 8; line++)
{
square = (rank << 4) + line;
attval = max(0, 8 - 3 * (distan[rank] + distan[line]));
/* center importance */
/* Rank importrance */
for (color = white; color <= black; ((int)color)++)
{
attackvalue[color][square] = ((squarerankvalue[rank] * 3 *
(materiallevel + 8)) >> 5) + attval;
square ^= 0x70;
}
}
for (color = white; color <= black; ((int)color)++)
{
oppcolor = (COLORTYPE)(1 - color);
CalcCastling(oppcolor, &cast);
if (cast != shrt && materiallevel > 0)
/* Importance of the 8 squares around the opponent's King */
for (dir = 0; dir < 8; dir++)
{
sq = PieceTab[oppcolor][0].isquare + DirTab[dir];
if (!(sq & 0x88))
attackvalue[color][sq] += ((12 * (materiallevel + 8)) >> 5);
}
}
/* Calculate PVControl */
for (square = 0x77; square >=0; square--)
if(!(square & 0x88))
for (color = white; color <= black; ((int)color)++)
for (piececount = rook; piececount <= bishop; ((int)piececount)++)
pvcontrol[color][piececount][square] = 0;
for (square = 0x77; square >=0; square--)
if(!(square & 0x88))
for (color = white; color <= black; ((int)color)++)
{
for (dir = 7; dir >= 0; dir--)
{
if (dir < 4)
piececount = rook;
else
piececount = bishop;
/* Count value of all attacs from the square in
the Direction.
The Value of attacking a Square is Found in ATTACKVAL.
Indirect Attacks (e.g. a Rook attacking through
another Rook) counts for a Normal attack,
Attacks through another Piece counts half */
cnt = 0;
sq = square;
direct = 1;
do
{
sq += DirTab[dir];
if (sq & 0x88) goto TEN;
temp = attackvalue[color][sq];
if (direct)
cnt += temp;
else
cnt += (temp >> 1);
if (Board[sq].piece != empty)
if ((Board[sq].piece != piececount)
&& (Board[sq].piece != queen))
direct = 0;
} while (Board[sq].piece != pawn);
TEN: pvcontrol[color][piececount][square] += (cnt >> 2);
}
}
/* Calculate PVTable, value by value */
for (square = 0x77; square >= 0; square--)
if (!(square & 0x88))
{
for (color = white; color <= black; ((int)color)++)
{
oppcolor = (COLORTYPE)(1 - color);
line = square & 7;
rank = square >> 4;
if (color == black) rank = 7 - rank;
dist = distan[rank] + distan[line];
kingdist = abs((square >> 4) - (PieceTab[oppcolor][0].isquare
>> 4)) + ((square - PieceTab[oppcolor][0].isquare) & 7);
for (piececount = king; piececount <= pawn; ((int)piececount)++)
{
posval = 0; /* Calculate POSITIONAL Value for */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -