📄 evaluate.cpp
字号:
// penalty
penalty = (penalty_1 + penalty_2) / 2;
}
file = SQUARE_FILE(KING_POS(board, 1));
penalty += storm_file(board, file, 1);
if(file != (0x4))
penalty += storm_file(board, file - 1, 1);
if(file != (0xB))
penalty += storm_file(board, file + 1, 1);
op[me] -= (penalty * 256) / 256;
}
// king attacks
for ( color = 0; color < 2; color++ )
{
if((mat_info->cflags[color]&(1 << 3)) != 0)
{
me = color;
opp = COLOUR_OPP(me);
king = KING_POS(board, me);
king_file = SQUARE_FILE(king);
king_rank = SQUARE_RANK(king);
// piece attacks
attack_tot = 0;
piece_nb = 0;
for ( ptr = &board->piece[opp][1]; (from = *ptr) != 0; ptr++ )
{
piece = board->square[from];
if(piece_attack_king(board, piece, from, king))
{
piece_nb++;
attack_tot += king_attack_unit[piece];
}
}
// scoring
op[color] -= (attack_tot * 20 * king_attack_weight[piece_nb]) / 256;
}
}
// update
*opening += op[0] - op[1];
*endgame += eg[0] - eg[1];
}
// eval_passer()
static void eval_passer(const board_t *board, const pawn_info_t *pawn_info, int *opening, int *endgame)
{
int color;
int op[2], eg[2];
int att, def;
int bits;
int file, rank;
int sq;
int min, max;
int delta;
int white_passed_nb, black_passed_nb;
// init
for ( color = 0; color < 2; color++ )
{
op[color] = 0;
eg[color] = 0;
}
white_passed_nb = 0;
black_passed_nb = 0;
// passed pawns
for ( color = 0; color < 2; color++ )
{
att = color;
def = COLOUR_OPP(att);
for ( bits = pawn_info->passed_bits[att]; bits != 0; bits &= bits - 1 )
{
file = BIT_FIRST(bits);
rank = BIT_LAST(board->pawn_file[att][file]);
sq = SQUARE_MAKE(file, rank);
if(COLOUR_IS_BLACK(att))
sq = SQUARE_RANK_MIRROR(sq);
// opening scoring
op[att] += quad(10, 70, rank);
// endgame scoring init
min = 20;
max = 140;
delta = max - min;
// "dangerous" bonus
if(board->piece_size[def] <= 1 // defender has no piece
&& (unstoppable_passer(board, sq, att) || king_passer(board, sq, att)))
{
delta += 800;
}
else if(free_passer(board, sq, att))
{
delta += 60;
}
// king-distance bonus
delta -= pawn_att_dist(sq, KING_POS(board, att), att) * 5;
delta += pawn_def_dist(sq, KING_POS(board, def), att) * 20;
// endgame scoring
eg[att] += min;
if(delta > 0)
eg[att] += quad(0, delta, rank);
}
}
// update
*opening += op[0] - op[1];
*endgame += eg[0] - eg[1];
}
// eval_pattern()
static void eval_pattern(const board_t *board, int *opening, int *endgame)
{
// trapped bishop (7th rank)
if((board->square[(0xA4)] == ((1 << 5) | (1 << 0)) && board->square[(0x95)] == ((1 << 3) | (1 << 1)))
|| (board->square[(0xB5)] == ((1 << 5) | (1 << 0)) && board->square[(0xA6)] == ((1 << 3) | (1 << 1))))
{
*opening -= 100;
*endgame -= 100;
}
if((board->square[(0xAB)] == ((1 << 5) | (1 << 0)) && board->square[(0x9A)] == ((1 << 3) | (1 << 1)))
|| (board->square[(0xBA)] == ((1 << 5) | (1 << 0)) && board->square[(0xA9)] == ((1 << 3) | (1 << 1))))
{
*opening -= 100;
*endgame -= 100;
}
if((board->square[(0x54)] == ((1 << 5) | (1 << 1)) && board->square[(0x65)] == ((1 << 2) | (1 << 0)))
|| (board->square[(0x45)] == ((1 << 5) | (1 << 1)) && board->square[(0x56)] == ((1 << 2) | (1 << 0))))
{
*opening += 100;
*endgame += 100;
}
if((board->square[(0x5B)] == ((1 << 5) | (1 << 1)) && board->square[(0x6A)] == ((1 << 2) | (1 << 0)))
|| (board->square[(0x4A)] == ((1 << 5) | (1 << 1)) && board->square[(0x59)] == ((1 << 2) | (1 << 0))))
{
*opening += 100;
*endgame += 100;
}
// trapped bishop (6th rank)
if(board->square[(0x94)] == ((1 << 5) | (1 << 0)) && board->square[(0x85)] == ((1 << 3) | (1 << 1)))
{
*opening -= 100 / 2;
*endgame -= 100 / 2;
}
if(board->square[(0x9B)] == ((1 << 5) | (1 << 0)) && board->square[(0x8A)] == ((1 << 3) | (1 << 1)))
{
*opening -= 100 / 2;
*endgame -= 100 / 2;
}
if(board->square[(0x64)] == ((1 << 5) | (1 << 1)) && board->square[(0x75)] == ((1 << 2) | (1 << 0)))
{
*opening += 100 / 2;
*endgame += 100 / 2;
}
if(board->square[(0x6B)] == ((1 << 5) | (1 << 1)) && board->square[(0x7A)] == ((1 << 2) | (1 << 0)))
{
*opening += 100 / 2;
*endgame += 100 / 2;
}
// blocked bishop
if(board->square[(0x57)] == ((1 << 2) | (1 << 0)) && board->square[(0x67)] != 0
&& board->square[(0x46)] == ((1 << 5) | (1 << 0)))
{
*opening -= 50;
}
if(board->square[(0x58)] == ((1 << 2) | (1 << 0)) && board->square[(0x68)] != 0
&& board->square[(0x49)] == ((1 << 5) | (1 << 0)))
{
*opening -= 50;
}
if(board->square[(0xA7)] == ((1 << 3) | (1 << 1)) && board->square[(0x97)] != 0
&& board->square[(0xB6)] == ((1 << 5) | (1 << 1)))
{
*opening += 50;
}
if(board->square[(0xA8)] == ((1 << 3) | (1 << 1)) && board->square[(0x98)] != 0
&& board->square[(0xB9)] == ((1 << 5) | (1 << 1)))
{
*opening += 50;
}
// blocked rook
if((board->square[(0x46)] == ((1 << 7) | (1 << 0)) || board->square[(0x45)] == ((1 << 7) | (1 << 0)))
&& (board->square[(0x44)] == ((1 << 6) | (1 << 0)) || board->square[(0x54)] == ((1 << 6) | (1 << 0))
|| board->square[(0x45)] == ((1 << 6) | (1 << 0))))
{
*opening -= 50;
}
if((board->square[(0x49)] == ((1 << 7) | (1 << 0)) || board->square[(0x4A)] == ((1 << 7) | (1 << 0)))
&& (board->square[(0x4B)] == ((1 << 6) | (1 << 0)) || board->square[(0x5B)] == ((1 << 6) | (1 << 0))
|| board->square[(0x4A)] == ((1 << 6) | (1 << 0))))
{
*opening -= 50;
}
if((board->square[(0xB6)] == ((1 << 7) | (1 << 1)) || board->square[(0xB5)] == ((1 << 7) | (1 << 1)))
&& (board->square[(0xB4)] == ((1 << 6) | (1 << 1)) || board->square[(0xA4)] == ((1 << 6) | (1 << 1))
|| board->square[(0xB5)] == ((1 << 6) | (1 << 1))))
{
*opening += 50;
}
if((board->square[(0xB9)] == ((1 << 7) | (1 << 1)) || board->square[(0xBA)] == ((1 << 7) | (1 << 1)))
&& (board->square[(0xBB)] == ((1 << 6) | (1 << 1)) || board->square[(0xAB)] == ((1 << 6) | (1 << 1))
|| board->square[(0xBA)] == ((1 << 6) | (1 << 1))))
{
*opening += 50;
}
}
// unstoppable_passer()
static bool unstoppable_passer(const board_t *board, int pawn, int color)
{
int me, opp;
int file, rank;
int king;
int prom;
const sq_t *ptr;
int sq;
int dist;
me = color;
opp = COLOUR_OPP(me);
file = SQUARE_FILE(pawn);
rank = PAWN_RANK(pawn, me);
king = KING_POS(board, opp);
// clear promotion path?
for ( ptr = &board->piece[me][0]; (sq = *ptr) != 0; ptr++ )
{
if(SQUARE_FILE(sq) == file && PAWN_RANK(sq, me) > rank)
{
return false; // "friendly" blocker
}
}
// init
if(rank == (0x5))
{
pawn += PAWN_MOVE_INC(me);
rank++;
}
prom = PAWN_PROMOTE(pawn, me);
dist = DISTANCE(pawn, prom);
if(board->turn == opp)
dist++;
if(DISTANCE(king, prom) > dist)
return true; // not in the square
return false;
}
// king_passer()
static bool king_passer(const board_t *board, int pawn, int color)
{
int me;
int king;
int file;
int prom;
me = color;
king = KING_POS(board, me);
file = SQUARE_FILE(pawn);
prom = PAWN_PROMOTE(pawn, me);
if(DISTANCE(king, prom) <= 1 && DISTANCE(king, pawn) <= 1
&& (SQUARE_FILE(king) != file || (file != (0x4) && file != (0xB))))
{
return true;
}
return false;
}
// free_passer()
static bool free_passer(const board_t *board, int pawn, int color)
{
int me, opp;
int inc;
int sq;
int move;
me = color;
opp = COLOUR_OPP(me);
inc = PAWN_MOVE_INC(me);
sq = pawn + inc;
if(board->square[sq] != 0)
return false;
move = MOVE_MAKE(pawn, sq);
if(see_move(move, board) < 0)
return false;
return true;
}
// pawn_att_dist()
static int pawn_att_dist(int pawn, int king, int color)
{
int me;
int inc;
int target;
me = color;
inc = PAWN_MOVE_INC(me);
target = pawn + inc;
return DISTANCE(king, target);
}
// pawn_def_dist()
static int pawn_def_dist(int pawn, int king, int color)
{
int me;
int inc;
int target;
me = color;
inc = PAWN_MOVE_INC(me);
target = pawn + inc;
return DISTANCE(king, target);
}
// draw_init_list()
static void draw_init_list(int list [], const board_t *board, int pawn_colour)
{
int pos;
int att, def;
const sq_t *ptr;
int sq;
int pawn;
int i;
// init
pos = 0;
att = pawn_colour;
def = COLOUR_OPP(att);
// att
for ( ptr = &board->piece[att][0]; (sq = *ptr) != 0; ptr++ )
{
list[pos++] = sq;
}
for ( ptr = &board->pawn[att][0]; (sq = *ptr) != 0; ptr++ )
{
list[pos++] = sq;
}
// def
for ( ptr = &board->piece[def][0]; (sq = *ptr) != 0; ptr++ )
{
list[pos++] = sq;
}
for ( ptr = &board->pawn[def][0]; (sq = *ptr) != 0; ptr++ )
{
list[pos++] = sq;
}
// end marker
list[pos] = 0;
// file flip?
pawn = board->pawn[att][0];
if(SQUARE_FILE(pawn) >= (0x8))
{
for ( i = 0; i < pos; i++ )
{
list[i] = SQUARE_FILE_MIRROR(list[i]);
}
}
// rank flip?
if(COLOUR_IS_BLACK(pawn_colour))
{
for ( i = 0; i < pos; i++ )
{
list[i] = SQUARE_RANK_MIRROR(list[i]);
}
}
}
// draw_kpkq()
static bool draw_kpkq(const int list [], int turn)
{
int wk, wp, bk, bq;
int prom;
int dist;
// load
wk = *list++;
wp = *list++;
bk = *list++;
bq = *list++;
// test
if(false) { }
else if(wp == (0xA4))
{
prom = (0xB4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -