📄 evaluate.cpp
字号:
dist = 4;
if(wk == (0xA5) || wk == (0xB5))
{ // best case
if(COLOUR_IS_WHITE(turn))
dist--;
}
else if(wk == (0xB4) || ((wk == (0xA6) || wk == (0xB6)) && bq != (0xB4)))
{ // white loses a tempo
if(COLOUR_IS_BLACK(turn) && SQUARE_FILE(bq) != (0x5))
return false;
}
else
{
return false;
}
if(DISTANCE(bk, prom) > dist)
return true;
}
else if(wp == (0xA6))
{
prom = (0xB6);
dist = 4;
if(false) { }
else if(wk == (0xB6))
{ // dist = 0
dist++; // self-blocking penalty
if(COLOUR_IS_WHITE(turn))
dist--; // right-to-move bonus
}
else if(wk == (0xA5) || wk == (0xB5))
{ // dist = 1, right side
dist--; // right-side bonus
if(DELTA_INC_LINE(wp - bq) == wk - wp)
dist++; // pinned-pawn penalty
if(COLOUR_IS_WHITE(turn))
dist--; // right-to-move bonus
}
else if(wk == (0xA7) || wk == (0xB7))
{ // dist = 1, wrong side
if(DELTA_INC_LINE(wp - bq) == wk - wp)
dist++; // pinned-pawn penalty
if(COLOUR_IS_WHITE(turn))
dist--; // right-to-move bonus
}
else if((wk == (0xA4) || wk == (0xB4)) && bq != (0xB6))
{ // dist = 2, right side
if(COLOUR_IS_BLACK(turn) && SQUARE_FILE(bq) != (0x5))
return false;
dist--; // right-side bonus
}
else if((wk == (0xA8) || wk == (0xB8)) && bq != (0xB6))
{ // dist = 2, wrong side
if(COLOUR_IS_BLACK(turn) && SQUARE_FILE(bq) != (0x7))
return false;
}
else
{
return false;
}
if(DISTANCE(bk, prom) > dist)
return true;
}
return false;
}
// draw_kpkr()
static bool draw_kpkr(const int list [], int turn)
{
int wk, wp, bk, br;
int wk_file, wk_rank;
int wp_file, wp_rank;
int br_file, br_rank;
int inc;
int prom;
int dist;
// load
wk = *list++;
wp = *list++;
bk = *list++;
br = *list++;
// init
wk_file = SQUARE_FILE(wk);
wk_rank = SQUARE_RANK(wk);
wp_file = SQUARE_FILE(wp);
wp_rank = SQUARE_RANK(wp);
br_file = SQUARE_FILE(br);
br_rank = SQUARE_RANK(br);
inc = PAWN_MOVE_INC(0);
prom = PAWN_PROMOTE(wp, 0);
// conditions
if(false) { }
else if(DISTANCE(wk, wp) == 1) {
// no-op
}
else if(DISTANCE(wk, wp) == 2 && abs(wk_rank - wp_rank) <= 1)
{
if(COLOUR_IS_BLACK(turn) && br_file != (wk_file + wp_file) / 2)
return false;
}
else
{
return false;
}
// white features
dist = DISTANCE(wk, prom) + DISTANCE(wp, prom);
if(wk == prom)
dist++;
if(wk == wp + inc)
{ // king on pawn's "front square"
if(wp_file == (0x4))
return false;
dist++; // self-blocking penalty
}
// black features
if(br_file != wp_file && br_rank != (0xB))
{
dist--; // misplaced-rook bonus
}
// test
if(COLOUR_IS_WHITE(turn))
dist--; // right-to-move bonus
if(DISTANCE(bk, prom) > dist)
return true;
return false;
}
// draw_kpkb()
static bool draw_kpkb(const int list [], int turn)
{
int wk, wp, bk, bb;
int inc;
int end, to;
int delta, inc_2;
int sq;
// load
wk = *list++;
wp = *list++;
bk = *list++;
bb = *list++;
// blocked pawn?
inc = PAWN_MOVE_INC(0);
end = PAWN_PROMOTE(wp, 0) + inc;
for ( to = wp + inc; to != end; to += inc )
{
if(to == bb)
return true; // direct blockade
delta = to - bb;
if(PSEUDO_ATTACK(((1 << 5) | (1 << 1)), delta))
{
inc_2 = DELTA_INC_ALL(delta);
sq = bb;
do
{
sq += inc_2;
if(sq == to)
return true; // indirect blockade
} while (sq != bk);
}
}
return false;
}
// draw_kpkn()
static bool draw_kpkn(const int list [], int turn)
{
int wk, wp, bk, bn;
int inc;
int end;
int file;
int sq;
// load
wk = *list++;
wp = *list++;
bk = *list++;
bn = *list++;
// blocked pawn?
inc = PAWN_MOVE_INC(0);
end = PAWN_PROMOTE(wp, 0) + inc;
file = SQUARE_FILE(wp);
if(file == (0x4) || file == (0xB))
end -= inc;
for ( sq = wp + inc; sq != end; sq += inc )
{
if(sq == bn || PSEUDO_ATTACK(((1 << 4) | (1 << 1)), sq - bn))
return true; // blockade
}
return false;
}
// draw_knpk()
static bool draw_knpk(const int list [], int turn)
{
int wk, wn, wp, bk;
// load
wk = *list++;
wn = *list++;
wp = *list++;
bk = *list++;
// test
if(wp == (0xA4) && DISTANCE(bk, (0xB4)) <= 1)
return true;
return false;
}
// draw_krpkr()
static bool draw_krpkr(const int list [], int turn)
{
int wk, wr, wp, bk, br;
int wp_file, wp_rank;
int bk_file, bk_rank;
int br_file, br_rank;
int prom;
// load
wk = *list++;
wr = *list++;
wp = *list++;
bk = *list++;
br = *list++;
// test
wp_file = SQUARE_FILE(wp);
wp_rank = SQUARE_RANK(wp);
bk_file = SQUARE_FILE(bk);
bk_rank = SQUARE_RANK(bk);
br_file = SQUARE_FILE(br);
br_rank = SQUARE_RANK(br);
prom = PAWN_PROMOTE(wp, 0);
if(false) { }
else if(bk == prom)
{
// TODO: rook near (0x4) if wp_rank == (0x9)?
if(br_file > wp_file)
return true;
}
else if(bk_file == wp_file && bk_rank > wp_rank)
{
return true;
}
else if(wr == prom && wp_rank == (0xA) && (bk == (0xAA) || bk == (0xAB)) && br_file == wp_file)
{
if(br_rank <= (0x6))
{
if(DISTANCE(wk, wp) > 1)
return true;
}
else
{ // br_rank >= (0x7)
if(DISTANCE(wk, wp) > 2)
return true;
}
}
return false;
}
// draw_kbpkb()
static bool draw_kbpkb(const int list [], int turn)
{
int wk, wb, wp, bk, bb;
int inc;
int end, to;
int delta, inc_2;
int sq;
// load
wk = *list++;
wb = *list++;
wp = *list++;
bk = *list++;
bb = *list++;
// opposit color?
if(SQUARE_COLOUR(wb) == SQUARE_COLOUR(bb))
return false; // TODO
// blocked pawn?
inc = PAWN_MOVE_INC(0);
end = PAWN_PROMOTE(wp, 0) + inc;
for ( to = wp + inc; to != end; to += inc )
{
if(to == bb)
return true; // direct blockade
delta = to - bb;
if(PSEUDO_ATTACK(((1 << 5) | (1 << 1)), delta))
{
inc_2 = DELTA_INC_ALL(delta);
sq = bb;
do
{
sq += inc_2;
if(sq == to)
return true; // indirect blockade
} while (sq != bk);
}
}
return false;
}
// shelter_square()
static int shelter_square(const board_t *board, int square, int color)
{
int penalty;
int file, rank;
penalty = 0;
file = SQUARE_FILE(square);
rank = PAWN_RANK(square, color);
penalty += shelter_file(board, file, rank, color) * 2;
if(file != (0x4))
penalty += shelter_file(board, file - 1, rank, color);
if(file != (0xB))
penalty += shelter_file(board, file + 1, rank, color);
if(penalty == 0)
penalty = 11; // weak back rank
penalty += storm_file(board, file, color);
if(file != (0x4))
penalty += storm_file(board, file - 1, color);
if(file != (0xB))
penalty += storm_file(board, file + 1, color);
return penalty;
}
// shelter_file()
static int shelter_file(const board_t *board, int file, int rank, int color)
{
int dist;
int penalty;
dist = BIT_FIRST(board->pawn_file[color][file] & bit_ge[rank]);
dist = (0xB) - dist;
penalty = 36 - dist * dist;
return penalty;
}
// storm_file()
static int storm_file(const board_t *board, int file, int color)
{
int dist;
int penalty;
dist = BIT_LAST(board->pawn_file[COLOUR_OPP(color)][file]);
penalty = 0;
switch(dist)
{
case (0x7):
penalty = 10 * 1;
break;
case (0x8):
penalty = 10 * 2;
break;
case (0x9):
penalty = 10 * 3;
break;
}
return penalty;
}
// bishop_can_attack()
static bool bishop_can_attack(const board_t *board, int to, int color)
{
const sq_t *ptr;
int from;
int piece;
for ( ptr = &board->piece[color][1]; (from = *ptr) != 0; ptr++ )
{
piece = board->square[from];
if(PIECE_IS_BISHOP(piece) && SQUARE_COLOUR(from) == SQUARE_COLOUR(to))
{
return true;
}
}
return false;
}
// end of eval.cpp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -