X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=594809af9d74274c7b6d3e2a2076836a2b50ab5e;hp=279802387402906e969f1361eb2051a03a04efe7;hb=343544f3f7fe780a4231b78646ab2fd61760e294;hpb=13d1f0ae4301b86c610a58332c3c19d9101704da diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 27980238..594809af 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -229,7 +229,7 @@ namespace { // Function prototypes template - Value do_evaluate(const Position& pos); + Value do_evaluate(const Position& pos, Value& margin); template void init_eval_info(const Position& pos, EvalInfo& ei); @@ -238,7 +238,7 @@ namespace { Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score* mobility); template - Score evaluate_king(const Position& pos, const EvalInfo& ei); + Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]); template Score evaluate_threats(const Position& pos, const EvalInfo& ei); @@ -264,8 +264,8 @@ namespace Eval { /// values, an endgame score and a middle game score, and interpolates /// between them based on the remaining material. - Value evaluate(const Position& pos) { - return do_evaluate(pos); + Value evaluate(const Position& pos, Value& margin) { + return do_evaluate(pos, margin); } @@ -307,14 +307,19 @@ namespace Eval { namespace { template -Value do_evaluate(const Position& pos) { +Value do_evaluate(const Position& pos, Value& margin) { assert(!pos.checkers()); EvalInfo ei; + Value margins[COLOR_NB]; Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO }; Thread* th = pos.this_thread(); + // margins[] store the uncertainty estimation of position's evaluation + // that typically is used by the search for pruning decisions. + margins[WHITE] = margins[BLACK] = VALUE_ZERO; + // Initialize score by reading the incrementally updated scores included // in the position object (material + piece square tables) and adding // Tempo bonus. Score is computed from the point of view of white. @@ -327,7 +332,10 @@ Value do_evaluate(const Position& pos) { // If we have a specialized evaluation function for the current material // configuration, call it and return. if (ei.mi->specialized_eval_exists()) + { + margin = VALUE_ZERO; return ei.mi->evaluate(pos); + } // Probe the pawn hash table ei.pi = Pawns::probe(pos, th->pawnsTable); @@ -345,8 +353,8 @@ Value do_evaluate(const Position& pos) { // Evaluate kings after all other pieces because we need complete attack // information when computing the king safety evaluation. - score += evaluate_king(pos, ei) - - evaluate_king(pos, ei); + score += evaluate_king(pos, ei, margins) + - evaluate_king(pos, ei, margins); // Evaluate tactical threats, we need full attack information including king score += evaluate_threats(pos, ei) @@ -393,6 +401,7 @@ Value do_evaluate(const Position& pos) { sf = ScaleFactor(50); } + margin = margins[pos.side_to_move()]; Value v = interpolate(score, ei.mi->game_phase(), sf); // In case of tracing add all single evaluation contributions for both white and black @@ -405,7 +414,9 @@ Value do_evaluate(const Position& pos) { Score b = ei.mi->space_weight() * evaluate_space(pos, ei); Tracing::add(SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space])); Tracing::add(TOTAL, score); - Tracing::stream << "\nScaling: " << std::noshowpos + Tracing::stream << "\nUncertainty margin: White: " << to_cp(margins[WHITE]) + << ", Black: " << to_cp(margins[BLACK]) + << "\nScaling: " << std::noshowpos << std::setw(6) << 100.0 * ei.mi->game_phase() / 128.0 << "% MG, " << std::setw(6) << 100.0 * (1.0 - ei.mi->game_phase() / 128.0) << "% * " << std::setw(6) << (100.0 * sf) / SCALE_FACTOR_NORMAL << "% EG.\n" @@ -629,7 +640,7 @@ Value do_evaluate(const Position& pos) { // evaluate_king() assigns bonuses and penalties to a king of a given color template - Score evaluate_king(const Position& pos, const EvalInfo& ei) { + Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -724,8 +735,12 @@ Value do_evaluate(const Position& pos) { attackUnits = std::min(99, std::max(0, attackUnits)); // Finally, extract the king danger score from the KingDanger[] - // array and subtract the score from evaluation. + // array and subtract the score from evaluation. Set also margins[] + // value that will be used for pruning because this value can sometimes + // be very big, and so capturing a single attacking piece can therefore + // result in a score change far bigger than the value of the captured piece. score -= KingDanger[Us == Search::RootColor][attackUnits]; + margins[Us] += mg_value(KingDanger[Us == Search::RootColor][attackUnits]); } if (Trace) @@ -1009,7 +1024,8 @@ Value do_evaluate(const Position& pos) { stream << std::showpoint << std::showpos << std::fixed << std::setprecision(2); std::memset(scores, 0, 2 * (TOTAL + 1) * sizeof(Score)); - do_evaluate(pos); + Value margin; + do_evaluate(pos, margin); std::string totals = stream.str(); stream.str("");