Scale down endgames with pawns on one or two adjacent files

This commit is contained in:
shane31
2014-06-25 16:01:00 -04:00
committed by Gary Linscott
parent ab580106fd
commit 6c9f4cf36f
3 changed files with 32 additions and 23 deletions

View File

@@ -197,6 +197,7 @@ namespace {
// scores, indexed by a calculated integer number. // scores, indexed by a calculated integer number.
Score KingDanger[128]; Score KingDanger[128];
const int ScalePawnSpan[2] = { 38, 56 };
// apply_weight() weighs score 'v' by weight 'w' trying to prevent overflow // apply_weight() weighs score 'v' by weight 'w' trying to prevent overflow
Score apply_weight(Score v, const Weight& w) { Score apply_weight(Score v, const Weight& w) {
@@ -726,29 +727,33 @@ namespace {
} }
// Scale winning side if position is more drawish than it appears // Scale winning side if position is more drawish than it appears
ScaleFactor sf = eg_value(score) > VALUE_DRAW ? ei.mi->scale_factor(pos, WHITE) Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
: ei.mi->scale_factor(pos, BLACK); ScaleFactor sf = ei.mi->scale_factor(pos, strongSide);
// If we don't already have an unusual scale factor, check for opposite // If we don't already have an unusual scale factor, check for certain
// colored bishop endgames, and use a lower scale for those. // types of endgames, and use a lower scale for those.
if ( ei.mi->game_phase() < PHASE_MIDGAME if ( ei.mi->game_phase() < PHASE_MIDGAME
&& pos.opposite_bishops()
&& (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN)) && (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN))
{ {
// Ignoring any pawns, do both sides only have a single bishop and no if (pos.opposite_bishops()) {
// other pieces? // Ignoring any pawns, do both sides only have a single bishop and no
if ( pos.non_pawn_material(WHITE) == BishopValueMg // other pieces?
&& pos.non_pawn_material(BLACK) == BishopValueMg) if ( pos.non_pawn_material(WHITE) == BishopValueMg
{ && pos.non_pawn_material(BLACK) == BishopValueMg)
// Check for KBP vs KB with only a single pawn that is almost {
// certainly a draw or at least two pawns. // Check for KBP vs KB with only a single pawn that is almost
bool one_pawn = (pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK) == 1); // certainly a draw or at least two pawns.
sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32); bool one_pawn = (pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK) == 1);
sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32);
}
else
// Endgame with opposite-colored bishops, but also other pieces. Still
// a bit drawish, but not as drawish as with only the two bishops.
sf = ScaleFactor(50 * sf / SCALE_FACTOR_NORMAL);
} else if ( ei.pi->pawn_span(strongSide) <= 1 &&
!pos.pawn_passed(~strongSide, pos.king_square(~strongSide))) {
sf = ScaleFactor(ScalePawnSpan[ei.pi->pawn_span(strongSide)]);
} }
else
// Endgame with opposite-colored bishops, but also other pieces. Still
// a bit drawish, but not as drawish as with only the two bishops.
sf = ScaleFactor(50 * sf / SCALE_FACTOR_NORMAL);
} }
// Interpolate between a middlegame and a (scaled by 'sf') endgame score // Interpolate between a middlegame and a (scaled by 'sf') endgame score

View File

@@ -204,13 +204,12 @@ namespace {
} }
} }
b = e->semiopenFiles[Us] ^ 0xFF;
e->pawnSpan[Us] = b ? int(msb(b) - lsb(b)) : 0;
// In endgame it's better to have pawns on both wings. So give a bonus according // In endgame it's better to have pawns on both wings. So give a bonus according
// to file distance between left and right outermost pawns. // to file distance between left and right outermost pawns.
if (pos.count<PAWN>(Us) > 1) value += PawnsFileSpan * e->pawnSpan[Us];
{
b = e->semiopenFiles[Us] ^ 0xFF;
value += PawnsFileSpan * int(msb(b) - lsb(b));
}
return value; return value;
} }

View File

@@ -45,6 +45,10 @@ struct Entry {
return semiopenFiles[c] & (leftSide ? (1 << f) - 1 : ~((1 << (f + 1)) - 1)); return semiopenFiles[c] & (leftSide ? (1 << f) - 1 : ~((1 << (f + 1)) - 1));
} }
int pawn_span(Color c) const {
return pawnSpan[c];
}
int pawns_on_same_color_squares(Color c, Square s) const { int pawns_on_same_color_squares(Color c, Square s) const {
return pawnsOnSquares[c][!!(DarkSquares & s)]; return pawnsOnSquares[c][!!(DarkSquares & s)];
} }
@@ -71,6 +75,7 @@ struct Entry {
int minKPdistance[COLOR_NB]; int minKPdistance[COLOR_NB];
int castlingRights[COLOR_NB]; int castlingRights[COLOR_NB];
int semiopenFiles[COLOR_NB]; int semiopenFiles[COLOR_NB];
int pawnSpan[COLOR_NB];
int pawnsOnSquares[COLOR_NB][COLOR_NB]; // [color][light/dark squares] int pawnsOnSquares[COLOR_NB][COLOR_NB]; // [color][light/dark squares]
}; };