- score += apply_weight(mobility[WHITE] - mobility[BLACK], Weights[Mobility]);
-
- // Evaluate kings after all other pieces because we need complete attack
- // information when computing the king safety evaluation.
- score += evaluate_king<WHITE, Trace>(pos, ei)
- - evaluate_king<BLACK, Trace>(pos, ei);
-
- // Evaluate tactical threats, we need full attack information including king
- score += evaluate_threats<WHITE, Trace>(pos, ei)
- - evaluate_threats<BLACK, Trace>(pos, ei);
-
- // Evaluate passed pawns, we need full attack information including king
- 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);
-
- // Evaluate space for both sides, only in middlegame
- if (ei.mi->space_weight())
- {
- int s = evaluate_space<WHITE>(pos, ei) - evaluate_space<BLACK>(pos, ei);
- score += apply_weight(s * ei.mi->space_weight(), Weights[Space]);
- }
-
- // 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);
-
- // If we don't already have an unusual scale factor, check for opposite
- // colored bishop 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);
- }
- 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);
- }
-
- Value v = interpolate(score, ei.mi->game_phase(), sf);
-
- // In case of tracing add all single evaluation contributions for both white and black
- if (Trace)
- {
- Tracing::add_term(Tracing::PST, pos.psq_score());
- Tracing::add_term(Tracing::IMBALANCE, ei.mi->material_value());
- Tracing::add_term(PAWN, ei.pi->pawns_value());
- Score w = ei.mi->space_weight() * evaluate_space<WHITE>(pos, ei);
- Score b = ei.mi->space_weight() * evaluate_space<BLACK>(pos, ei);
- Tracing::add_term(Tracing::SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space]));
- Tracing::add_term(Tracing::TOTAL, score);
- Tracing::ei = ei;
- Tracing::sf = sf;
- }
-
- return pos.side_to_move() == WHITE ? v : -v;
-}
-
-
- // init_eval_info() initializes king bitboards for given color adding
- // pawn attacks. To be done at the beginning of the evaluation.
-
- template<Color Us>
- void init_eval_info(const Position& pos, EvalInfo& ei) {
-
- const Color Them = (Us == WHITE ? BLACK : WHITE);
- const Square Down = (Us == WHITE ? DELTA_S : DELTA_N);
-
- ei.pinnedPieces[Us] = pos.pinned_pieces(Us);
-
- Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from<KING>(pos.king_square(Them));
- ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us);
-
- // Init king safety tables only if we are going to use them
- if (pos.count<QUEEN>(Us) && pos.non_pawn_material(Us) > QueenValueMg + PawnValueMg)
- {
- ei.kingRing[Them] = b | shift_bb<Down>(b);
- b &= ei.attackedBy[Us][PAWN];
- ei.kingAttackersCount[Us] = b ? popcount<Max15>(b) : 0;
- ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0;