// ThreatenedByPawn[PieceType] contains a penalty according to which piece
// type is attacked by an enemy pawn.
const Score ThreatenedByPawn[] = {
- S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118)
+ S(0, 0), S(0, 0), S(80, 119), S(80, 119), S(117, 199), S(127, 218)
};
// Hanging contains a bonus for each enemy hanging piece
// scores, indexed by a calculated integer number.
Score KingDanger[128];
+ const int ScalePawnSpan[2] = { 38, 56 };
// apply_weight() weighs score 'v' by weight 'w' trying to prevent overflow
Score apply_weight(Score v, const Weight& w) {
// Add a bonus according if the attacking pieces are minor or major
if (weakEnemies)
{
- b = weakEnemies & (ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
+ b = weakEnemies & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
if (b)
score += Threat[0][type_of(pos.piece_on(lsb(b)))];
// evaluate_unstoppable_pawns() scores the most advanced among the passed and
- // candidate pawns. In case opponent has no pieces but pawns, this is somewhat
- // related to the possibility that pawns are unstoppable.
+ // candidate pawns. In case both players have no pieces but pawns, this is
+ // somewhat related to the possibility that pawns are unstoppable.
- Score evaluate_unstoppable_pawns(const Position& pos, Color us, const EvalInfo& ei) {
+ Score evaluate_unstoppable_pawns(Color us, const EvalInfo& ei) {
Bitboard b = ei.pi->passed_pawns(us) | ei.pi->candidate_pawns(us);
- if (!b || pos.non_pawn_material(~us))
- return SCORE_ZERO;
-
- return Unstoppable * int(relative_rank(us, frontmost_sq(us, b)));
+ return b ? Unstoppable * int(relative_rank(us, frontmost_sq(us, b))) : SCORE_ZERO;
}
score += evaluate_passed_pawns<WHITE, Trace>(pos, ei)
- evaluate_passed_pawns<BLACK, Trace>(pos, ei);
- // If one side has only a king, score for potential unstoppable pawns
- if (!pos.non_pawn_material(WHITE) || !pos.non_pawn_material(BLACK))
- score += evaluate_unstoppable_pawns(pos, WHITE, ei)
- - evaluate_unstoppable_pawns(pos, BLACK, ei);
+ // If both sides have only pawns, score for potential unstoppable pawns
+ if (!pos.non_pawn_material(WHITE) && !pos.non_pawn_material(BLACK))
+ score += evaluate_unstoppable_pawns(WHITE, ei)
+ - evaluate_unstoppable_pawns(BLACK, ei);
// Evaluate space for both sides, only in middlegame
if (ei.mi->space_weight())
}
// Scale winning side if position is more drawish than it appears
- ScaleFactor sf = eg_value(score) > VALUE_DRAW ? ei.mi->scale_factor(pos, WHITE)
- : ei.mi->scale_factor(pos, BLACK);
+ Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
+ ScaleFactor sf = ei.mi->scale_factor(pos, strongSide);
- // If we don't already have an unusual scale factor, check for opposite
- // colored bishop endgames, and use a lower scale for those.
+ // If we don't already have an unusual scale factor, check for certain
+ // types of endgames, and use a lower scale for those.
if ( ei.mi->game_phase() < PHASE_MIDGAME
- && pos.opposite_bishops()
&& (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN))
{
- // Ignoring any pawns, do both sides only have a single bishop and no
- // other pieces?
- 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.
- bool one_pawn = (pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK) == 1);
- sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32);
+ if (pos.opposite_bishops()) {
+ // Ignoring any pawns, do both sides only have a single bishop and no
+ // other pieces?
+ 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.
+ 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 ( abs(eg_value(score)) <= BishopValueEg &&
+ 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