mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 01:03:09 +00:00
Start to space inflate endgame.cpp
Still a lot to do, it's a big file! No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
bdbbc4e06b
commit
ec2927286a
2 changed files with 188 additions and 175 deletions
188
src/endgame.cpp
188
src/endgame.cpp
|
@ -34,73 +34,73 @@
|
||||||
|
|
||||||
/// Evaluation functions
|
/// Evaluation functions
|
||||||
|
|
||||||
// Generic "mate lone king" eval:
|
// Generic "mate lone king" eval
|
||||||
KXKEvaluationFunction EvaluateKXK = KXKEvaluationFunction(WHITE);
|
KXKEvaluationFunction EvaluateKXK = KXKEvaluationFunction(WHITE);
|
||||||
KXKEvaluationFunction EvaluateKKX = KXKEvaluationFunction(BLACK);
|
KXKEvaluationFunction EvaluateKKX = KXKEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KBN vs K:
|
// KBN vs K
|
||||||
KBNKEvaluationFunction EvaluateKBNK = KBNKEvaluationFunction(WHITE);
|
KBNKEvaluationFunction EvaluateKBNK = KBNKEvaluationFunction(WHITE);
|
||||||
KBNKEvaluationFunction EvaluateKKBN = KBNKEvaluationFunction(BLACK);
|
KBNKEvaluationFunction EvaluateKKBN = KBNKEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KP vs K:
|
// KP vs K
|
||||||
KPKEvaluationFunction EvaluateKPK = KPKEvaluationFunction(WHITE);
|
KPKEvaluationFunction EvaluateKPK = KPKEvaluationFunction(WHITE);
|
||||||
KPKEvaluationFunction EvaluateKKP = KPKEvaluationFunction(BLACK);
|
KPKEvaluationFunction EvaluateKKP = KPKEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KR vs KP:
|
// KR vs KP
|
||||||
KRKPEvaluationFunction EvaluateKRKP = KRKPEvaluationFunction(WHITE);
|
KRKPEvaluationFunction EvaluateKRKP = KRKPEvaluationFunction(WHITE);
|
||||||
KRKPEvaluationFunction EvaluateKPKR = KRKPEvaluationFunction(BLACK);
|
KRKPEvaluationFunction EvaluateKPKR = KRKPEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KR vs KB:
|
// KR vs KB
|
||||||
KRKBEvaluationFunction EvaluateKRKB = KRKBEvaluationFunction(WHITE);
|
KRKBEvaluationFunction EvaluateKRKB = KRKBEvaluationFunction(WHITE);
|
||||||
KRKBEvaluationFunction EvaluateKBKR = KRKBEvaluationFunction(BLACK);
|
KRKBEvaluationFunction EvaluateKBKR = KRKBEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KR vs KN:
|
// KR vs KN
|
||||||
KRKNEvaluationFunction EvaluateKRKN = KRKNEvaluationFunction(WHITE);
|
KRKNEvaluationFunction EvaluateKRKN = KRKNEvaluationFunction(WHITE);
|
||||||
KRKNEvaluationFunction EvaluateKNKR = KRKNEvaluationFunction(BLACK);
|
KRKNEvaluationFunction EvaluateKNKR = KRKNEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KQ vs KR:
|
// KQ vs KR
|
||||||
KQKREvaluationFunction EvaluateKQKR = KQKREvaluationFunction(WHITE);
|
KQKREvaluationFunction EvaluateKQKR = KQKREvaluationFunction(WHITE);
|
||||||
KQKREvaluationFunction EvaluateKRKQ = KQKREvaluationFunction(BLACK);
|
KQKREvaluationFunction EvaluateKRKQ = KQKREvaluationFunction(BLACK);
|
||||||
|
|
||||||
// KBB vs KN:
|
// KBB vs KN
|
||||||
KBBKNEvaluationFunction EvaluateKBBKN = KBBKNEvaluationFunction(WHITE);
|
KBBKNEvaluationFunction EvaluateKBBKN = KBBKNEvaluationFunction(WHITE);
|
||||||
KBBKNEvaluationFunction EvaluateKNKBB = KBBKNEvaluationFunction(BLACK);
|
KBBKNEvaluationFunction EvaluateKNKBB = KBBKNEvaluationFunction(BLACK);
|
||||||
|
|
||||||
// K and two minors vs K and one or two minors:
|
// K and two minors vs K and one or two minors
|
||||||
KmmKmEvaluationFunction EvaluateKmmKm = KmmKmEvaluationFunction(WHITE);
|
KmmKmEvaluationFunction EvaluateKmmKm = KmmKmEvaluationFunction(WHITE);
|
||||||
|
|
||||||
|
|
||||||
/// Scaling functions
|
/// Scaling functions
|
||||||
|
|
||||||
// KBP vs K:
|
// KBP vs K
|
||||||
KBPKScalingFunction ScaleKBPK = KBPKScalingFunction(WHITE);
|
KBPKScalingFunction ScaleKBPK = KBPKScalingFunction(WHITE);
|
||||||
KBPKScalingFunction ScaleKKBP = KBPKScalingFunction(BLACK);
|
KBPKScalingFunction ScaleKKBP = KBPKScalingFunction(BLACK);
|
||||||
|
|
||||||
// KQ vs KRP:
|
// KQ vs KRP
|
||||||
KQKRPScalingFunction ScaleKQKRP = KQKRPScalingFunction(WHITE);
|
KQKRPScalingFunction ScaleKQKRP = KQKRPScalingFunction(WHITE);
|
||||||
KQKRPScalingFunction ScaleKRPKQ = KQKRPScalingFunction(BLACK);
|
KQKRPScalingFunction ScaleKRPKQ = KQKRPScalingFunction(BLACK);
|
||||||
|
|
||||||
// KRP vs KR:
|
// KRP vs KR
|
||||||
KRPKRScalingFunction ScaleKRPKR = KRPKRScalingFunction(WHITE);
|
KRPKRScalingFunction ScaleKRPKR = KRPKRScalingFunction(WHITE);
|
||||||
KRPKRScalingFunction ScaleKRKRP = KRPKRScalingFunction(BLACK);
|
KRPKRScalingFunction ScaleKRKRP = KRPKRScalingFunction(BLACK);
|
||||||
|
|
||||||
// KRPP vs KRP:
|
// KRPP vs KRP
|
||||||
KRPPKRPScalingFunction ScaleKRPPKRP = KRPPKRPScalingFunction(WHITE);
|
KRPPKRPScalingFunction ScaleKRPPKRP = KRPPKRPScalingFunction(WHITE);
|
||||||
KRPPKRPScalingFunction ScaleKRPKRPP = KRPPKRPScalingFunction(BLACK);
|
KRPPKRPScalingFunction ScaleKRPKRPP = KRPPKRPScalingFunction(BLACK);
|
||||||
|
|
||||||
// King and pawns vs king:
|
// King and pawns vs king
|
||||||
KPsKScalingFunction ScaleKPsK = KPsKScalingFunction(WHITE);
|
KPsKScalingFunction ScaleKPsK = KPsKScalingFunction(WHITE);
|
||||||
KPsKScalingFunction ScaleKKPs = KPsKScalingFunction(BLACK);
|
KPsKScalingFunction ScaleKKPs = KPsKScalingFunction(BLACK);
|
||||||
|
|
||||||
// KBP vs KB:
|
// KBP vs KB
|
||||||
KBPKBScalingFunction ScaleKBPKB = KBPKBScalingFunction(WHITE);
|
KBPKBScalingFunction ScaleKBPKB = KBPKBScalingFunction(WHITE);
|
||||||
KBPKBScalingFunction ScaleKBKBP = KBPKBScalingFunction(BLACK);
|
KBPKBScalingFunction ScaleKBKBP = KBPKBScalingFunction(BLACK);
|
||||||
|
|
||||||
// KBP vs KN:
|
// KBP vs KN
|
||||||
KBPKNScalingFunction ScaleKBPKN = KBPKNScalingFunction(WHITE);
|
KBPKNScalingFunction ScaleKBPKN = KBPKNScalingFunction(WHITE);
|
||||||
KBPKNScalingFunction ScaleKNKBP = KBPKNScalingFunction(BLACK);
|
KBPKNScalingFunction ScaleKNKBP = KBPKNScalingFunction(BLACK);
|
||||||
|
|
||||||
// KNP vs K:
|
// KNP vs K
|
||||||
KNPKScalingFunction ScaleKNPK = KNPKScalingFunction(WHITE);
|
KNPKScalingFunction ScaleKNPK = KNPKScalingFunction(WHITE);
|
||||||
KNPKScalingFunction ScaleKKNP = KNPKScalingFunction(BLACK);
|
KNPKScalingFunction ScaleKKNP = KNPKScalingFunction(BLACK);
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ KPKPScalingFunction ScaleKPKPb = KPKPScalingFunction(BLACK);
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Table used to drive the defending king towards the edge of the board
|
// Table used to drive the defending king towards the edge of the board
|
||||||
// in KX vs K and KQ vs KR endgames:
|
// in KX vs K and KQ vs KR endgames.
|
||||||
const uint8_t MateTable[64] = {
|
const uint8_t MateTable[64] = {
|
||||||
100, 90, 80, 70, 70, 80, 90, 100,
|
100, 90, 80, 70, 70, 80, 90, 100,
|
||||||
90, 70, 60, 50, 50, 60, 70, 90,
|
90, 70, 60, 50, 50, 60, 70, 90,
|
||||||
|
@ -129,7 +129,7 @@ namespace {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Table used to drive the defending king towards a corner square of the
|
// Table used to drive the defending king towards a corner square of the
|
||||||
// right color in KBN vs K endgames:
|
// right color in KBN vs K endgames.
|
||||||
const uint8_t KBNKMateTable[64] = {
|
const uint8_t KBNKMateTable[64] = {
|
||||||
200, 190, 180, 170, 160, 150, 140, 130,
|
200, 190, 180, 170, 160, 150, 140, 130,
|
||||||
190, 180, 170, 160, 150, 140, 130, 140,
|
190, 180, 170, 160, 150, 140, 130, 140,
|
||||||
|
@ -142,18 +142,17 @@ namespace {
|
||||||
};
|
};
|
||||||
|
|
||||||
// The attacking side is given a descending bonus based on distance between
|
// The attacking side is given a descending bonus based on distance between
|
||||||
// the two kings in basic endgames:
|
// the two kings in basic endgames.
|
||||||
const int DistanceBonus[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
|
const int DistanceBonus[8] = { 0, 0, 100, 80, 60, 40, 20, 10 };
|
||||||
|
|
||||||
// Bitbase for KP vs K:
|
// Bitbase for KP vs K
|
||||||
uint8_t KPKBitbase[24576];
|
uint8_t KPKBitbase[24576];
|
||||||
|
|
||||||
// Penalty for big distance between king and knight for the defending king
|
// Penalty for big distance between king and knight for the defending king
|
||||||
// and knight in KR vs KN endgames:
|
// and knight in KR vs KN endgames.
|
||||||
const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
|
const int KRKNKingKnightDistancePenalty[8] = { 0, 0, 4, 10, 20, 32, 48, 70 };
|
||||||
|
|
||||||
// Various inline functions for accessing the above arrays:
|
// Various inline functions for accessing the above arrays
|
||||||
|
|
||||||
inline Value mate_table(Square s) {
|
inline Value mate_table(Square s) {
|
||||||
return Value(MateTable[s]);
|
return Value(MateTable[s]);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +169,7 @@ namespace {
|
||||||
return Value(KRKNKingKnightDistancePenalty[d]);
|
return Value(KRKNKingKnightDistancePenalty[d]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for probing the KP vs K bitbase:
|
// Function for probing the KP vs K bitbase
|
||||||
int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm);
|
int probe_kpk(Square wksq, Square wpsq, Square bksq, Color stm);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -182,8 +181,7 @@ namespace {
|
||||||
|
|
||||||
/// Constructors
|
/// Constructors
|
||||||
|
|
||||||
EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) {
|
EndgameEvaluationFunction::EndgameEvaluationFunction(Color c) : strongerSide(c) {
|
||||||
strongerSide = c;
|
|
||||||
weakerSide = opposite_color(strongerSide);
|
weakerSide = opposite_color(strongerSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,8 +196,7 @@ KBBKNEvaluationFunction::KBBKNEvaluationFunction(Color c) : EndgameEvaluationFun
|
||||||
KmmKmEvaluationFunction::KmmKmEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {}
|
KmmKmEvaluationFunction::KmmKmEvaluationFunction(Color c) : EndgameEvaluationFunction(c) {}
|
||||||
|
|
||||||
|
|
||||||
ScalingFunction::ScalingFunction(Color c) {
|
ScalingFunction::ScalingFunction(Color c) : strongerSide(c) {
|
||||||
strongerSide = c;
|
|
||||||
weakerSide = opposite_color(c);
|
weakerSide = opposite_color(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,18 +224,18 @@ Value KXKEvaluationFunction::apply(const Position &pos) {
|
||||||
Square winnerKSq = pos.king_square(strongerSide);
|
Square winnerKSq = pos.king_square(strongerSide);
|
||||||
Square loserKSq = pos.king_square(weakerSide);
|
Square loserKSq = pos.king_square(weakerSide);
|
||||||
|
|
||||||
Value result =
|
Value result = pos.non_pawn_material(strongerSide)
|
||||||
pos.non_pawn_material(strongerSide) +
|
+ pos.piece_count(strongerSide, PAWN) * PawnValueEndgame
|
||||||
pos.piece_count(strongerSide, PAWN) * PawnValueEndgame +
|
+ mate_table(loserKSq)
|
||||||
mate_table(loserKSq) +
|
+ distance_bonus(square_distance(winnerKSq, loserKSq));
|
||||||
distance_bonus(square_distance(winnerKSq, loserKSq));
|
|
||||||
|
|
||||||
if(pos.piece_count(strongerSide, QUEEN) > 0 || pos.piece_count(strongerSide, ROOK) > 0 ||
|
if ( pos.piece_count(strongerSide, QUEEN) > 0
|
||||||
pos.piece_count(strongerSide, BISHOP) > 1)
|
|| pos.piece_count(strongerSide, ROOK) > 0
|
||||||
|
|| pos.piece_count(strongerSide, BISHOP) > 1)
|
||||||
// TODO: check for two equal-colored bishops!
|
// TODO: check for two equal-colored bishops!
|
||||||
result += VALUE_KNOWN_WIN;
|
result += VALUE_KNOWN_WIN;
|
||||||
|
|
||||||
return (strongerSide == pos.side_to_move())? result : -result;
|
return (strongerSide == pos.side_to_move() ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,8 +246,7 @@ Value KBNKEvaluationFunction::apply(const Position &pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(weakerSide) == Value(0));
|
assert(pos.non_pawn_material(weakerSide) == Value(0));
|
||||||
assert(pos.piece_count(weakerSide, PAWN) == Value(0));
|
assert(pos.piece_count(weakerSide, PAWN) == Value(0));
|
||||||
assert(pos.non_pawn_material(strongerSide) ==
|
assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame + BishopValueMidgame);
|
||||||
KnightValueMidgame + BishopValueMidgame);
|
|
||||||
assert(pos.piece_count(strongerSide, BISHOP) == 1);
|
assert(pos.piece_count(strongerSide, BISHOP) == 1);
|
||||||
assert(pos.piece_count(strongerSide, KNIGHT) == 1);
|
assert(pos.piece_count(strongerSide, KNIGHT) == 1);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
||||||
|
@ -259,16 +255,17 @@ Value KBNKEvaluationFunction::apply(const Position &pos) {
|
||||||
Square loserKSq = pos.king_square(weakerSide);
|
Square loserKSq = pos.king_square(weakerSide);
|
||||||
Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0);
|
Square bishopSquare = pos.piece_list(strongerSide, BISHOP, 0);
|
||||||
|
|
||||||
if(square_color(bishopSquare) == BLACK) {
|
if (square_color(bishopSquare) == BLACK)
|
||||||
|
{
|
||||||
winnerKSq = flop_square(winnerKSq);
|
winnerKSq = flop_square(winnerKSq);
|
||||||
loserKSq = flop_square(loserKSq);
|
loserKSq = flop_square(loserKSq);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value result =
|
Value result = VALUE_KNOWN_WIN
|
||||||
VALUE_KNOWN_WIN + distance_bonus(square_distance(winnerKSq, loserKSq)) +
|
+ distance_bonus(square_distance(winnerKSq, loserKSq))
|
||||||
kbnk_mate_table(loserKSq);
|
+ kbnk_mate_table(loserKSq);
|
||||||
|
|
||||||
return (strongerSide == pos.side_to_move())? result : -result;
|
return (strongerSide == pos.side_to_move() ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,32 +281,36 @@ Value KPKEvaluationFunction::apply(const Position &pos) {
|
||||||
Square wksq, bksq, wpsq;
|
Square wksq, bksq, wpsq;
|
||||||
Color stm;
|
Color stm;
|
||||||
|
|
||||||
if(strongerSide == WHITE) {
|
if (strongerSide == WHITE)
|
||||||
|
{
|
||||||
wksq = pos.king_square(WHITE);
|
wksq = pos.king_square(WHITE);
|
||||||
bksq = pos.king_square(BLACK);
|
bksq = pos.king_square(BLACK);
|
||||||
wpsq = pos.piece_list(WHITE, PAWN, 0);
|
wpsq = pos.piece_list(WHITE, PAWN, 0);
|
||||||
stm = pos.side_to_move();
|
stm = pos.side_to_move();
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
wksq = flip_square(pos.king_square(BLACK));
|
wksq = flip_square(pos.king_square(BLACK));
|
||||||
bksq = flip_square(pos.king_square(WHITE));
|
bksq = flip_square(pos.king_square(WHITE));
|
||||||
wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
|
wpsq = flip_square(pos.piece_list(BLACK, PAWN, 0));
|
||||||
stm = opposite_color(pos.side_to_move());
|
stm = opposite_color(pos.side_to_move());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(square_file(wpsq) >= FILE_E) {
|
if (square_file(wpsq) >= FILE_E)
|
||||||
|
{
|
||||||
wksq = flop_square(wksq);
|
wksq = flop_square(wksq);
|
||||||
bksq = flop_square(bksq);
|
bksq = flop_square(bksq);
|
||||||
wpsq = flop_square(wpsq);
|
wpsq = flop_square(wpsq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(probe_kpk(wksq, wpsq, bksq, stm)) {
|
if (!probe_kpk(wksq, wpsq, bksq, stm))
|
||||||
Value result =
|
|
||||||
VALUE_KNOWN_WIN + PawnValueEndgame + Value(square_rank(wpsq));
|
|
||||||
return (strongerSide == pos.side_to_move())? result : -result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return VALUE_DRAW;
|
return VALUE_DRAW;
|
||||||
|
|
||||||
|
Value result = VALUE_KNOWN_WIN
|
||||||
|
+ PawnValueEndgame
|
||||||
|
+ Value(square_rank(wpsq));
|
||||||
|
|
||||||
|
return (strongerSide == pos.side_to_move() ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,7 +334,8 @@ Value KRKPEvaluationFunction::apply(const Position &pos) {
|
||||||
bksq = pos.king_square(weakerSide);
|
bksq = pos.king_square(weakerSide);
|
||||||
bpsq = pos.piece_list(weakerSide, PAWN, 0);
|
bpsq = pos.piece_list(weakerSide, PAWN, 0);
|
||||||
|
|
||||||
if(strongerSide == BLACK) {
|
if (strongerSide == BLACK)
|
||||||
|
{
|
||||||
wksq = flip_square(wksq);
|
wksq = flip_square(wksq);
|
||||||
wrsq = flip_square(wrsq);
|
wrsq = flip_square(wrsq);
|
||||||
bksq = flip_square(bksq);
|
bksq = flip_square(bksq);
|
||||||
|
@ -343,21 +345,22 @@ Value KRKPEvaluationFunction::apply(const Position &pos) {
|
||||||
Square queeningSq = make_square(square_file(bpsq), RANK_1);
|
Square queeningSq = make_square(square_file(bpsq), RANK_1);
|
||||||
Value result;
|
Value result;
|
||||||
|
|
||||||
// If the stronger side's king is in front of the pawn, it's a win:
|
// If the stronger side's king is in front of the pawn, it's a win
|
||||||
if (wksq < bpsq && square_file(wksq) == square_file(bpsq))
|
if (wksq < bpsq && square_file(wksq) == square_file(bpsq))
|
||||||
result = RookValueEndgame - Value(square_distance(wksq, bpsq));
|
result = RookValueEndgame - Value(square_distance(wksq, bpsq));
|
||||||
|
|
||||||
// If the weaker side's king is too far from the pawn and the rook,
|
// If the weaker side's king is too far from the pawn and the rook,
|
||||||
// it's a win:
|
// it's a win
|
||||||
else if(square_distance(bksq, bpsq) - (tempo^1) >= 3 &&
|
else if ( square_distance(bksq, bpsq) - (tempo^1) >= 3
|
||||||
square_distance(bksq, wrsq) >= 3)
|
&& square_distance(bksq, wrsq) >= 3)
|
||||||
result = RookValueEndgame - Value(square_distance(wksq, bpsq));
|
result = RookValueEndgame - Value(square_distance(wksq, bpsq));
|
||||||
|
|
||||||
// If the pawn is far advanced and supported by the defending king,
|
// If the pawn is far advanced and supported by the defending king,
|
||||||
// the position is drawish:
|
// the position is drawish
|
||||||
else if(square_rank(bksq) <= RANK_3 && square_distance(bksq, bpsq) == 1 &&
|
else if ( square_rank(bksq) <= RANK_3
|
||||||
square_rank(wksq) >= RANK_4 &&
|
&& square_distance(bksq, bpsq) == 1
|
||||||
square_distance(wksq, bpsq) - tempo > 2)
|
&& square_rank(wksq) >= RANK_4
|
||||||
|
&& square_distance(wksq, bpsq) - tempo > 2)
|
||||||
result = Value(80 - square_distance(wksq, bpsq) * 8);
|
result = Value(80 - square_distance(wksq, bpsq) * 8);
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -366,7 +369,7 @@ Value KRKPEvaluationFunction::apply(const Position &pos) {
|
||||||
+ Value(square_distance(bksq, bpsq + DELTA_S) * 8)
|
+ Value(square_distance(bksq, bpsq + DELTA_S) * 8)
|
||||||
+ Value(square_distance(bpsq, queeningSq) * 8);
|
+ Value(square_distance(bpsq, queeningSq) * 8);
|
||||||
|
|
||||||
return (strongerSide == pos.side_to_move())? result : -result;
|
return (strongerSide == pos.side_to_move() ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -382,7 +385,7 @@ Value KRKBEvaluationFunction::apply(const Position &pos) {
|
||||||
assert(pos.piece_count(weakerSide, BISHOP) == 1);
|
assert(pos.piece_count(weakerSide, BISHOP) == 1);
|
||||||
|
|
||||||
Value result = mate_table(pos.king_square(weakerSide));
|
Value result = mate_table(pos.king_square(weakerSide));
|
||||||
return (pos.side_to_move() == strongerSide)? result : -result;
|
return (pos.side_to_move() == strongerSide ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -414,6 +417,7 @@ Value KRKNEvaluationFunction::apply(const Position &pos) {
|
||||||
/// able to win KQ vs KR.
|
/// able to win KQ vs KR.
|
||||||
|
|
||||||
Value KQKREvaluationFunction::apply(const Position& pos) {
|
Value KQKREvaluationFunction::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
||||||
assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
|
assert(pos.non_pawn_material(weakerSide) == RookValueMidgame);
|
||||||
|
@ -422,14 +426,17 @@ Value KQKREvaluationFunction::apply(const Position &pos) {
|
||||||
Square winnerKSq = pos.king_square(strongerSide);
|
Square winnerKSq = pos.king_square(strongerSide);
|
||||||
Square loserKSq = pos.king_square(weakerSide);
|
Square loserKSq = pos.king_square(weakerSide);
|
||||||
|
|
||||||
Value result = QueenValueEndgame - RookValueEndgame +
|
Value result = QueenValueEndgame
|
||||||
mate_table(loserKSq) + distance_bonus(square_distance(winnerKSq, loserKSq));
|
- RookValueEndgame
|
||||||
|
+ mate_table(loserKSq)
|
||||||
|
+ distance_bonus(square_distance(winnerKSq, loserKSq));
|
||||||
|
|
||||||
return (strongerSide == pos.side_to_move())? result : -result;
|
return (strongerSide == pos.side_to_move())? result : -result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Value KBBKNEvaluationFunction::apply(const Position& pos) {
|
Value KBBKNEvaluationFunction::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.piece_count(strongerSide, BISHOP) == 2);
|
assert(pos.piece_count(strongerSide, BISHOP) == 2);
|
||||||
assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
|
||||||
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
|
assert(pos.piece_count(weakerSide, KNIGHT) == 1);
|
||||||
|
@ -450,7 +457,7 @@ Value KBBKNEvaluationFunction::apply(const Position &pos) {
|
||||||
// Bonus for restricting the knight's mobility
|
// Bonus for restricting the knight's mobility
|
||||||
result += Value((8 - count_1s_max_15(pos.piece_attacks<KNIGHT>(nsq))) * 8);
|
result += Value((8 - count_1s_max_15(pos.piece_attacks<KNIGHT>(nsq))) * 8);
|
||||||
|
|
||||||
return (strongerSide == pos.side_to_move())? result : -result;
|
return (strongerSide == pos.side_to_move() ? result : -result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -466,6 +473,7 @@ Value KmmKmEvaluationFunction::apply(const Position &pos) {
|
||||||
/// will be used.
|
/// will be used.
|
||||||
|
|
||||||
ScaleFactor KBPKScalingFunction::apply(const Position& pos) {
|
ScaleFactor KBPKScalingFunction::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, BISHOP) == 1);
|
assert(pos.piece_count(strongerSide, BISHOP) == 1);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) >= 1);
|
assert(pos.piece_count(strongerSide, PAWN) >= 1);
|
||||||
|
@ -476,35 +484,37 @@ ScaleFactor KBPKScalingFunction::apply(const Position &pos) {
|
||||||
Bitboard pawns = pos.pawns(strongerSide);
|
Bitboard pawns = pos.pawns(strongerSide);
|
||||||
File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
|
File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
|
||||||
|
|
||||||
if((pawnFile == FILE_A || pawnFile == FILE_H) &&
|
// All pawns are on a single rook file ?
|
||||||
(pawns & ~file_bb(pawnFile)) == EmptyBoardBB) {
|
if ( (pawnFile == FILE_A || pawnFile == FILE_H)
|
||||||
// All pawns are on a single rook file.
|
&& (pawns & ~file_bb(pawnFile)) == EmptyBoardBB)
|
||||||
|
{
|
||||||
Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
|
Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
|
||||||
Square queeningSq =
|
Square queeningSq = relative_square(strongerSide, make_square(pawnFile, RANK_8));
|
||||||
relative_square(strongerSide, make_square(pawnFile, RANK_8));
|
|
||||||
Square kingSq = pos.king_square(weakerSide);
|
Square kingSq = pos.king_square(weakerSide);
|
||||||
|
|
||||||
if(square_color(queeningSq) != square_color(bishopSq) &&
|
if ( square_color(queeningSq) != square_color(bishopSq)
|
||||||
file_distance(square_file(kingSq), pawnFile) <= 1) {
|
&& file_distance(square_file(kingSq), pawnFile) <= 1)
|
||||||
|
{
|
||||||
// The bishop has the wrong color, and the defending king is on the
|
// The bishop has the wrong color, and the defending king is on the
|
||||||
// file of the pawn(s) or the neighboring file. Find the rank of the
|
// file of the pawn(s) or the neighboring file. Find the rank of the
|
||||||
// frontmost pawn:
|
// frontmost pawn.
|
||||||
|
|
||||||
Rank rank;
|
Rank rank;
|
||||||
if(strongerSide == WHITE) {
|
if (strongerSide == WHITE)
|
||||||
for(rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--);
|
{
|
||||||
|
for (rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--) {}
|
||||||
assert(rank >= RANK_2 && rank <= RANK_7);
|
assert(rank >= RANK_2 && rank <= RANK_7);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
for(rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++);
|
{
|
||||||
rank = Rank(rank^7); // HACK
|
for(rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++) {}
|
||||||
|
rank = Rank(rank^7); // HACK to get the relative rank
|
||||||
assert(rank >= RANK_2 && rank <= RANK_7);
|
assert(rank >= RANK_2 && rank <= RANK_7);
|
||||||
}
|
}
|
||||||
// If the defending king has distance 1 to the promotion square or
|
// If the defending king has distance 1 to the promotion square or
|
||||||
// is placed somewhere in front of the pawn, it's a draw.
|
// is placed somewhere in front of the pawn, it's a draw.
|
||||||
if(square_distance(kingSq, queeningSq) <= 1 ||
|
if ( square_distance(kingSq, queeningSq) <= 1
|
||||||
relative_rank(strongerSide, kingSq) >= rank)
|
|| relative_rank(strongerSide, kingSq) >= rank)
|
||||||
return ScaleFactor(0);
|
return ScaleFactor(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -518,6 +528,7 @@ ScaleFactor KBPKScalingFunction::apply(const Position &pos) {
|
||||||
/// a pawn.
|
/// a pawn.
|
||||||
|
|
||||||
ScaleFactor KQKRPScalingFunction::apply(const Position& pos) {
|
ScaleFactor KQKRPScalingFunction::apply(const Position& pos) {
|
||||||
|
|
||||||
assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
|
assert(pos.non_pawn_material(strongerSide) == QueenValueMidgame);
|
||||||
assert(pos.piece_count(strongerSide, QUEEN) == 1);
|
assert(pos.piece_count(strongerSide, QUEEN) == 1);
|
||||||
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
assert(pos.piece_count(strongerSide, PAWN) == 0);
|
||||||
|
@ -525,11 +536,12 @@ ScaleFactor KQKRPScalingFunction::apply(const Position &pos) {
|
||||||
assert(pos.piece_count(weakerSide, PAWN) >= 1);
|
assert(pos.piece_count(weakerSide, PAWN) >= 1);
|
||||||
|
|
||||||
Square kingSq = pos.king_square(weakerSide);
|
Square kingSq = pos.king_square(weakerSide);
|
||||||
if(relative_rank(weakerSide, kingSq) <= RANK_2 &&
|
if ( relative_rank(weakerSide, kingSq) <= RANK_2
|
||||||
relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4 &&
|
&& relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4
|
||||||
(pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) &&
|
&& (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3))
|
||||||
(pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) &&
|
&& (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2))
|
||||||
(pos.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide))) {
|
&& (pos.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide)))
|
||||||
|
{
|
||||||
Square rsq = pos.piece_list(weakerSide, ROOK, 0);
|
Square rsq = pos.piece_list(weakerSide, ROOK, 0);
|
||||||
if (pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
|
if (pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
|
||||||
return ScaleFactor(0);
|
return ScaleFactor(0);
|
||||||
|
|
|
@ -143,7 +143,8 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's look if we have a specialized evaluation function for this
|
// Let's look if we have a specialized evaluation function for this
|
||||||
// particular material configuration.
|
// particular material configuration. First we look for a fixed
|
||||||
|
// configuration one, then a generic one if previous search failed.
|
||||||
if ((mi->evaluationFunction = funcs->getEEF(key)) != NULL)
|
if ((mi->evaluationFunction = funcs->getEEF(key)) != NULL)
|
||||||
return mi;
|
return mi;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue