X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=5e3a3ff24daf28de218928466d85de70c87d8243;hp=540f402e7187bdbe6fbca0a1e9fe3bb81b62d8c5;hb=4220f191d8c1d597ff66e41f90af11367b0ebd7f;hpb=843a5961e1d9c938e692a115b6bc8774f20d5769 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 540f402e..5e3a3ff2 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -29,8 +29,6 @@ #include "thread.h" #include "ucioption.h" -Color EvalRootColor; - namespace { // Struct EvalInfo contains various information computed and collected @@ -221,8 +219,8 @@ namespace { std::stringstream TraceStream; enum TracedType { - PST = 8, IMBALANCE = 9, MOBILITY = 10, THREAT = 11, - PASSED = 12, UNSTOPPABLE = 13, SPACE = 14, TOTAL = 15 + PST = 8, IMBALANCE = 9, MOBILITY = 10, THREAT = 11, + PASSED = 12, UNSTOPPABLE = 13, SPACE = 14, TOTAL = 15 }; // Function prototypes @@ -254,13 +252,102 @@ namespace { Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight); double to_cp(Value v); void trace_add(int idx, Score term_w, Score term_b = SCORE_ZERO); + void trace_row(const char* name, int idx); } -/// 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, Value& margin) { return do_evaluate(pos, margin); } +namespace Eval { + + Color RootColor; + + /// 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, Value& margin) { + return do_evaluate(pos, margin); + } + + + /// init() computes evaluation weights from the corresponding UCI parameters + /// and setup king tables. + + void init() { + + Weights[Mobility] = weight_option("Mobility (Middle Game)", "Mobility (Endgame)", WeightsInternal[Mobility]); + Weights[PassedPawns] = weight_option("Passed Pawns (Middle Game)", "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]); + + // King safety is asymmetrical. Our king danger level is weighted by + // "Cowardice" UCI parameter, instead the opponent one by "Aggressiveness". + // If running in analysis mode, make sure we use symmetrical king safety. We + // do this by replacing both Weights[kingDangerUs] and Weights[kingDangerThem] + // by their average. + if (Options["UCI_AnalyseMode"]) + Weights[KingDangerUs] = Weights[KingDangerThem] = (Weights[KingDangerUs] + Weights[KingDangerThem]) / 2; + + 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)); + + KingDangerTable[1][i] = apply_weight(make_score(t, 0), Weights[KingDangerUs]); + KingDangerTable[0][i] = apply_weight(make_score(t, 0), Weights[KingDangerThem]); + } + } + + + /// trace() is like evaluate() but instead of a value returns a string suitable + /// to be print on stdout with the detailed descriptions and values of each + /// evaluation term. Used mainly for debugging. + + std::string trace(const Position& pos) { + + Value margin; + std::string totals; + + RootColor = pos.side_to_move(); + + TraceStream.str(""); + TraceStream << std::showpoint << std::showpos << std::fixed << std::setprecision(2); + memset(TracedScores, 0, 2 * 16 * sizeof(Score)); + + do_evaluate(pos, margin); + + totals = TraceStream.str(); + TraceStream.str(""); + + TraceStream << std::setw(21) << "Eval term " << "| White | Black | Total \n" + << " | MG EG | MG EG | MG EG \n" + << "---------------------+-------------+-------------+---------------\n"; + + trace_row("Material, PST, Tempo", PST); + trace_row("Material imbalance", IMBALANCE); + trace_row("Pawns", PAWN); + trace_row("Knights", KNIGHT); + trace_row("Bishops", BISHOP); + trace_row("Rooks", ROOK); + trace_row("Queens", QUEEN); + trace_row("Mobility", MOBILITY); + trace_row("King safety", KING); + trace_row("Threats", THREAT); + trace_row("Passed pawns", PASSED); + trace_row("Unstoppable pawns", UNSTOPPABLE); + trace_row("Space", SPACE); + + TraceStream << "---------------------+-------------+-------------+---------------\n"; + trace_row("Total", TOTAL); + TraceStream << totals; + + return TraceStream.str(); + } + +} // namespace Eval + namespace { @@ -387,49 +474,6 @@ Value do_evaluate(const Position& pos, Value& margin) { return pos.side_to_move() == WHITE ? v : -v; } -} // namespace - - -/// eval_init() reads evaluation weights from the corresponding UCI parameters -/// and setup weights and tables. -void eval_init() { - - const Value MaxSlope = Value(30); - const Value Peak = Value(1280); - Value t[100]; - - // King safety is asymmetrical. Our king danger level is weighted by - // "Cowardice" UCI parameter, instead the opponent one by "Aggressiveness". - Weights[Mobility] = weight_option("Mobility (Middle Game)", "Mobility (Endgame)", WeightsInternal[Mobility]); - Weights[PassedPawns] = weight_option("Passed Pawns (Middle Game)", "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]); - - // If running in analysis mode, make sure we use symmetrical king safety. We do this - // by replacing both Weights[kingDangerUs] and Weights[kingDangerThem] by their average. - if (Options["UCI_AnalyseMode"]) - Weights[KingDangerUs] = Weights[KingDangerThem] = (Weights[KingDangerUs] + Weights[KingDangerThem]) / 2; - - // First setup the base table - for (int i = 0; i < 100; i++) - { - t[i] = Value(int(0.4 * i * i)); - - if (i > 0) - t[i] = std::min(t[i], t[i - 1] + MaxSlope); - - t[i] = std::min(t[i], Peak); - } - - // Then apply the weights and get the final KingDangerTable[] array - for (Color c = WHITE; c <= BLACK; c++) - for (int i = 0; i < 100; i++) - KingDangerTable[c == WHITE][i] = apply_weight(make_score(t[i], 0), Weights[KingDangerUs + c]); -} - - -namespace { // init_eval_info() initializes king bitboards for given color adding // pawn attacks. To be done at the beginning of the evaluation. @@ -785,8 +829,8 @@ namespace { // 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 -= KingDangerTable[Us == EvalRootColor][attackUnits]; - margins[Us] += mg_value(KingDangerTable[Us == EvalRootColor][attackUnits]); + score -= KingDangerTable[Us == Eval::RootColor][attackUnits]; + margins[Us] += mg_value(KingDangerTable[Us == Eval::RootColor][attackUnits]); } if (Trace) @@ -1126,14 +1170,15 @@ namespace { void trace_add(int idx, Score wScore, Score bScore) { - TracedScores[WHITE][idx] = wScore; - TracedScores[BLACK][idx] = bScore; + TracedScores[WHITE][idx] = wScore; + TracedScores[BLACK][idx] = bScore; } + // trace_row() is an helper function used by tracing code to register the // values of a single evaluation term. - void trace_row(const char *name, int idx) { + void trace_row(const char* name, int idx) { Score wScore = TracedScores[WHITE][idx]; Score bScore = TracedScores[BLACK][idx]; @@ -1156,47 +1201,3 @@ namespace { } } } - - -/// trace_evaluate() is like evaluate() but instead of a value returns a string -/// suitable to be print on stdout with the detailed descriptions and values of -/// each evaluation term. Used mainly for debugging. - -std::string trace_evaluate(const Position& pos) { - - Value margin; - std::string totals; - - TraceStream.str(""); - TraceStream << std::showpoint << std::showpos << std::fixed << std::setprecision(2); - memset(TracedScores, 0, 2 * 16 * sizeof(Score)); - - do_evaluate(pos, margin); - - totals = TraceStream.str(); - TraceStream.str(""); - - TraceStream << std::setw(21) << "Eval term " << "| White | Black | Total \n" - << " | MG EG | MG EG | MG EG \n" - << "---------------------+-------------+-------------+---------------\n"; - - trace_row("Material, PST, Tempo", PST); - trace_row("Material imbalance", IMBALANCE); - trace_row("Pawns", PAWN); - trace_row("Knights", KNIGHT); - trace_row("Bishops", BISHOP); - trace_row("Rooks", ROOK); - trace_row("Queens", QUEEN); - trace_row("Mobility", MOBILITY); - trace_row("King safety", KING); - trace_row("Threats", THREAT); - trace_row("Passed pawns", PASSED); - trace_row("Unstoppable pawns", UNSTOPPABLE); - trace_row("Space", SPACE); - - TraceStream << "---------------------+-------------+-------------+---------------\n"; - trace_row("Total", TOTAL); - TraceStream << totals; - - return TraceStream.str(); -}