return make_score(bonus * weight * weight, 0);
}
+
+ // evaluate_initiative() computes the initiative correction value for the position, i.e.
+ // second order bonus/malus based on the known attacking/defending status of the players.
+ Score evaluate_initiative(const Position& pos, const EvalInfo& ei, const Score positional_score) {
+
+ int pawns = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
+ int king_separation = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
+ int asymmetry = ei.pi->pawn_asymmetry();
+
+ // Compute the initiative bonus for the attacking side
+ int attacker_bonus = 8 * (pawns + asymmetry + king_separation) - 120;
+
+ // Now apply the bonus: note that we find the attacking side by extracting the sign
+ // of the endgame value of "positional_score", and that we carefully cap the bonus so
+ // that the endgame score with the correction will never be divided by more than two.
+ int eg = eg_value(positional_score);
+ int value = ((eg > 0) - (eg < 0)) * std::max( attacker_bonus , -abs( eg / 2 ) );
+
+ return make_score( 0 , value ) ;
+ }
+
} // namespace
// Evaluate space for both sides, only during opening
if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
score += (evaluate_space<WHITE>(pos, ei) - evaluate_space<BLACK>(pos, ei)) * Weights[Space];
+
+ // Evaluate initiative
+ score += evaluate_initiative(pos, ei, score);
// Scale winning side if position is more drawish than it appears
Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
}
- // Scale endgame by number of pawns
- int p = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
- int v_eg = 1 + abs(int(eg_value(score)));
- sf = ScaleFactor(std::max(sf / 2, sf - 8 * SCALE_FACTOR_NORMAL * (12 - p) / v_eg));
-
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
Value v = mg_value(score) * int(me->game_phase())
+ eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
Bitboard pawn_attacks(Color c) const { return pawnAttacks[c]; }
Bitboard passed_pawns(Color c) const { return passedPawns[c]; }
int pawn_span(Color c) const { return pawnSpan[c]; }
+ int pawn_asymmetry() const { return asymmetry; }
int semiopen_file(Color c, File f) const {
return semiopenFiles[c] & (1 << f);
int semiopenFiles[COLOR_NB];
int pawnSpan[COLOR_NB];
int pawnsOnSquares[COLOR_NB][COLOR_NB]; // [color][light/dark squares]
+ int asymmetry;
};
typedef HashTable<Entry, 16384> Table;