- // Function prototypes
- template<bool Trace>
- Value do_evaluate(const Position& pos);
-
- template<Color Us>
- void init_eval_info(const Position& pos, EvalInfo& ei);
-
- template<Color Us, bool Trace>
- Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility);
-
- template<Color Us, bool Trace>
- Score evaluate_king(const Position& pos, const EvalInfo& ei);
-
- template<Color Us, bool Trace>
- Score evaluate_threats(const Position& pos, const EvalInfo& ei);
-
- template<Color Us, bool Trace>
- Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei);
-
- template<Color Us>
- int evaluate_space(const Position& pos, const EvalInfo& ei);
-
- Score evaluate_unstoppable_pawns(const Position& pos, Color us, const EvalInfo& ei);
-
- Value interpolate(const Score& v, Phase ph, ScaleFactor sf);
- Score apply_weight(Score v, const Weight& w);
- Weight weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight);
-}
-
-
-namespace Eval {
-
- /// evaluate() is the main evaluation function. It always computes two
- /// values, an endgame score and a middlegame score, and interpolates
- /// between them based on the remaining material.
-
- Value evaluate(const Position& pos) {
- return do_evaluate<false>(pos);
- }
-
-
- /// trace() is like evaluate(), but instead of returning a value, it returns
- /// a string (suitable for outputting to stdout) that contains the detailed
- /// descriptions and values of each evaluation term. It's mainly used for
- /// debugging.
- std::string trace(const Position& pos) {
- return Tracing::do_trace(pos);
- }
-
-
- /// init() computes evaluation weights from the corresponding UCI parameters
- /// and setup king tables.
-
- void init() {
-
- Weights[Mobility] = weight_option("Mobility (Midgame)", "Mobility (Endgame)", WeightsInternal[Mobility]);
- Weights[PawnStructure] = weight_option("Pawn Structure (Midgame)", "Pawn Structure (Endgame)", WeightsInternal[PawnStructure]);
- Weights[PassedPawns] = weight_option("Passed Pawns (Midgame)", "Passed Pawns (Endgame)", WeightsInternal[PassedPawns]);
- Weights[Space] = weight_option("Space", "Space", WeightsInternal[Space]);
- Weights[KingDangerUs] = weight_option("Cowardice", "Cowardice", WeightsInternal[KingDangerUs]);
- Weights[KingDangerThem] = weight_option("Aggressiveness", "Aggressiveness", WeightsInternal[KingDangerThem]);
-
- const int MaxSlope = 30;
- const int Peak = 1280;
-
- for (int t = 0, i = 1; i < 100; ++i)
- {
- t = std::min(Peak, std::min(int(0.4 * i * i), t + MaxSlope));
-
- KingDanger[1][i] = apply_weight(make_score(t, 0), Weights[KingDangerUs]);
- KingDanger[0][i] = apply_weight(make_score(t, 0), Weights[KingDangerThem]);
- }
- }
-
-} // namespace Eval
-
-
-namespace {
-
-template<bool Trace>
-Value do_evaluate(const Position& pos) {
-
- assert(!pos.checkers());
-
- EvalInfo ei;
- Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO };
- Thread* thisThread = pos.this_thread();
-
- // Initialize score by reading the incrementally updated scores included
- // in the position object (material + piece square tables) and adding a
- // Tempo bonus. Score is computed from the point of view of white.
- score = pos.psq_score() + (pos.side_to_move() == WHITE ? Tempo : -Tempo);
-
- // Probe the material hash table
- ei.mi = Material::probe(pos, thisThread->materialTable, thisThread->endgames);
- score += ei.mi->material_value();
-
- // If we have a specialized evaluation function for the current material
- // configuration, call it and return.
- if (ei.mi->specialized_eval_exists())
- return ei.mi->evaluate(pos);
-
- // Probe the pawn hash table
- ei.pi = Pawns::probe(pos, thisThread->pawnsTable);
- score += apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]);