From: Marco Costalba Date: Tue, 6 Mar 2012 09:09:37 +0000 (+0100) Subject: Introduce Eval namespace X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=4220f191d8c1d597ff66e41f90af11367b0ebd7f Introduce Eval namespace Wrap evaluation related stuff and reshuffle a bit the code. No functional change. Signed-off-by: Marco Costalba --- 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(); -} diff --git a/src/evaluate.h b/src/evaluate.h index 5ff9643a..a0418b79 100644 --- a/src/evaluate.h +++ b/src/evaluate.h @@ -24,10 +24,14 @@ class Position; +namespace Eval { + +extern Color RootColor; + +extern void init(); extern Value evaluate(const Position& pos, Value& margin); -extern std::string trace_evaluate(const Position& pos); -extern void eval_init(); +extern std::string trace(const Position& pos); -extern Color EvalRootColor; +} #endif // !defined(EVALUATE_H_INCLUDED) diff --git a/src/main.cpp b/src/main.cpp index 37a031cb..0c94ed89 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,7 +40,7 @@ int main(int argc, char* argv[]) { kpk_bitbase_init(); Search::init(); Threads.init(); - eval_init(); + Eval::init(); TT.set_size(Options["Hash"]); cout << engine_info() << endl; diff --git a/src/search.cpp b/src/search.cpp index 82b7c55c..9386e453 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -48,6 +48,7 @@ namespace Search { using std::string; using std::cout; using std::endl; +using Eval::evaluate; using namespace Search; namespace { @@ -251,7 +252,7 @@ void Search::think() { Position& pos = RootPosition; Chess960 = pos.is_chess960(); - EvalRootColor = pos.side_to_move(); + Eval::RootColor = pos.side_to_move(); SearchTime.restart(); TimeMgr.init(Limits, pos.startpos_ply_counter()); TT.new_search(); diff --git a/src/uci.cpp b/src/uci.cpp index a9ace955..3a522a88 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -105,10 +105,7 @@ void uci_loop() { pos.flip_me(); else if (token == "eval") - { - EvalRootColor = pos.side_to_move(); - cout << trace_evaluate(pos) << endl; - } + cout << Eval::trace(pos) << endl; else if (token == "key") cout << "key: " << hex << pos.key() diff --git a/src/ucioption.cpp b/src/ucioption.cpp index 6fb4747f..51987d03 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -33,7 +33,7 @@ OptionsMap Options; // Global object namespace { /// 'On change' actions, triggered by an option's value change -void on_eval(UCIOption&) { eval_init(); } +void on_eval(UCIOption&) { Eval::init(); } void on_threads(UCIOption&) { Threads.read_uci_options(); } void on_hash_size(UCIOption& o) { TT.set_size(o); } void on_clear_hash(UCIOption& o) { TT.clear(); o = false; } // UCI button