- template<Color Us, bool HasPopCnt>
- void evaluate_pieces_of_color(const Position& pos, EvalInfo& ei);
-
- template<Color Us, bool HasPopCnt>
- void evaluate_king(const Position& pos, EvalInfo& ei);
-
- template<Color Us>
- void evaluate_threats(const Position& pos, EvalInfo& ei);
-
- template<Color Us, bool HasPopCnt>
- int evaluate_space(const Position& pos, EvalInfo& ei);
-
- template<Color Us>
- void evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
-
- void evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei);
- void evaluate_trapped_bishop_a7h7(const Position& pos, Square s, Color us, EvalInfo& ei);
- void evaluate_trapped_bishop_a1h1(const Position& pos, Square s, Color us, EvalInfo& ei);
- inline Score apply_weight(Score v, Score weight);
- Value scale_by_game_phase(const Score& v, Phase ph, const ScaleFactor sf[]);
- Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight);
- void init_safety();
-}
-
-
-////
-//// Functions
-////
-
-/// evaluate() is the main evaluation function. It always computes two
-/// values, an endgame score and a middle game score, and interpolates
-/// between them based on the remaining material.
-Value evaluate(const Position& pos, EvalInfo& ei) {
-
- return CpuHasPOPCNT ? do_evaluate<true>(pos, ei)
- : do_evaluate<false>(pos, ei);
-}
-
-namespace {
-
-template<bool HasPopCnt>
-Value do_evaluate(const Position& pos, EvalInfo& ei) {
-
- ScaleFactor factor[2];
-
- assert(pos.is_ok());
- assert(pos.thread() >= 0 && pos.thread() < MAX_THREADS);
- assert(!pos.is_check());
-
- memset(&ei, 0, sizeof(EvalInfo));
-
- // Initialize by reading the incrementally updated scores included in the
- // position object (material + piece square tables)
- ei.value = pos.value();
-
- // Probe the material hash table
- ei.mi = MaterialTable[pos.thread()]->get_material_info(pos);
- ei.value += 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);
-
- // After get_material_info() call that modifies them
- factor[WHITE] = ei.mi->scale_factor(pos, WHITE);
- factor[BLACK] = ei.mi->scale_factor(pos, BLACK);
-
- // Probe the pawn hash table
- ei.pi = PawnTable[pos.thread()]->get_pawn_info(pos);
- ei.value += apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]);
-
- // Initialize attack bitboards with pawns evaluation
- init_attack_tables<WHITE, HasPopCnt>(pos, ei);
- init_attack_tables<BLACK, HasPopCnt>(pos, ei);
-
- // Evaluate pieces
- evaluate_pieces_of_color<WHITE, HasPopCnt>(pos, ei);
- evaluate_pieces_of_color<BLACK, HasPopCnt>(pos, ei);
-
- // Kings. Kings are evaluated after all other pieces for both sides,
- // because we need complete attack information for all pieces when computing
- // the king safety evaluation.
- evaluate_king<WHITE, HasPopCnt>(pos, ei);
- evaluate_king<BLACK, HasPopCnt>(pos, ei);
-
- // Evaluate tactical threats, we need full attack info including king
- evaluate_threats<WHITE>(pos, ei);
- evaluate_threats<BLACK>(pos, ei);
-
- // Evaluate passed pawns, we need full attack info including king
- evaluate_passed_pawns<WHITE>(pos, ei);
- evaluate_passed_pawns<BLACK>(pos, ei);
-
- // If one side has only a king, check whether exsists any unstoppable passed pawn
- if (!pos.non_pawn_material(WHITE) || !pos.non_pawn_material(BLACK))
- evaluate_unstoppable_pawns(pos, ei);
-
- Phase phase = ei.mi->game_phase();
-
- // Middle-game specific evaluation terms
- if (phase > PHASE_ENDGAME)
- {
- // Pawn storms in positions with opposite castling
- if ( square_file(pos.king_square(WHITE)) >= FILE_E
- && square_file(pos.king_square(BLACK)) <= FILE_D)