- assert(!pos.checkers());
-
- Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
- EvalInfo ei;
-
- // Probe the material hash table
- ei.me = Material::probe(pos);
-
- // If we have a specialized evaluation function for the current material
- // configuration, call it and return.
- if (ei.me->specialized_eval_exists())
- return ei.me->evaluate(pos);
-
- // Initialize score by reading the incrementally updated scores included in
- // the position object (material + piece square tables) and the material
- // imbalance. Score is computed internally from the white point of view.
- Score score = pos.psq_score() + ei.me->imbalance();
-
- // Probe the pawn hash table
- ei.pe = Pawns::probe(pos);
- score += ei.pe->pawns_score();
-
- // We have taken into account all cheap evaluation terms.
- // If score exceeds a threshold return a lazy evaluation.
- Value lazy = lazy_eval(mg_value(score), eg_value(score));
- if (lazy)
- return pos.side_to_move() == WHITE ? lazy : -lazy;
-
- // Initialize attack and king safety bitboards
- eval_init<WHITE>(pos, ei);
- eval_init<BLACK>(pos, ei);
-
- // Evaluate all pieces but king and pawns
- score += evaluate_pieces<DoTrace>(pos, ei, mobility);
- score += mobility[WHITE] - mobility[BLACK];
-
- // Evaluate kings after all other pieces because we need full attack
- // information when computing the king safety evaluation.
- score += evaluate_king<WHITE, DoTrace>(pos, ei)
- - evaluate_king<BLACK, DoTrace>(pos, ei);
-
- // Evaluate tactical threats, we need full attack information including king
- score += evaluate_threats<WHITE, DoTrace>(pos, ei)
- - evaluate_threats<BLACK, DoTrace>(pos, ei);
-
- // Evaluate passed pawns, we need full attack information including king
- score += evaluate_passed_pawns<WHITE, DoTrace>(pos, ei)
- - evaluate_passed_pawns<BLACK, DoTrace>(pos, ei);
-
- // 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);
-
- // Evaluate position potential for the winning side
- score += evaluate_initiative(pos, ei.pe->pawn_asymmetry(), eg_value(score));
-
- // Evaluate scale factor for the winning side
- ScaleFactor sf = evaluate_scale_factor(pos, ei, eg_value(score));
-
- // Interpolate between a middlegame and a (scaled by 'sf') endgame score
- Value v = mg_value(score) * int(ei.me->game_phase())
- + eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
-
- v /= int(PHASE_MIDGAME);
-
- // In case of tracing add all remaining individual evaluation terms
- if (DoTrace)
- {
- Trace::add(MATERIAL, pos.psq_score());
- Trace::add(IMBALANCE, ei.me->imbalance());
- Trace::add(PAWN, ei.pe->pawns_score());
- Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
- if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
- Trace::add(SPACE, evaluate_space<WHITE>(pos, ei)
- , evaluate_space<BLACK>(pos, ei));
- Trace::add(TOTAL, score);
+ initialize<WHITE>();
+ initialize<BLACK>();
+
+ // Pieces should be evaluated first (populate attack tables)
+ score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
+ + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
+ + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
+ + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
+
+ score += mobility[WHITE] - mobility[BLACK];
+
+ score += king< WHITE>() - king< BLACK>()
+ + threats<WHITE>() - threats<BLACK>()
+ + passed< WHITE>() - passed< BLACK>()
+ + space< WHITE>() - space< BLACK>();
+
+ score += initiative(eg_value(score));
+
+ // Interpolate between a middlegame and a (scaled by 'sf') endgame score
+ ScaleFactor sf = scale_factor(eg_value(score));
+ v = mg_value(score) * int(me->game_phase())
+ + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
+
+ v /= int(PHASE_MIDGAME);
+
+ // In case of tracing add all remaining individual evaluation terms
+ if (T)
+ {
+ Trace::add(MATERIAL, pos.psq_score());
+ Trace::add(IMBALANCE, me->imbalance());
+ Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
+ Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
+ Trace::add(TOTAL, score);
+ }
+
+ return (pos.side_to_move() == WHITE ? v : -v) // Side to move point of view
+ + Eval::Tempo;