diff --git a/src/search.cpp b/src/search.cpp index 50f3a01b5c2..ad54a726541 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -319,6 +319,16 @@ void Thread::search() { multiPV = std::min(multiPV, rootMoves.size()); int ct = Options["Contempt"] * PawnValueEg / 100; // From centipawns + + // In analysis mode, adjust contempt in accordance with user preference + if (Limits.infinite || Options["UCI_AnalyseMode"]) + ct = Options["Analysis Contempt"] == "Off" ? 0 + : Options["Analysis Contempt"] == "Both" ? ct + : Options["Analysis Contempt"] == "White" && us == BLACK ? -ct + : Options["Analysis Contempt"] == "Black" && us == WHITE ? -ct + : ct; + + // In evaluate.cpp the evaluation is from the white point of view contempt = (us == WHITE ? make_score(ct, ct / 2) : -make_score(ct, ct / 2)); @@ -358,13 +368,11 @@ void Thread::search() { alpha = std::max(previousScore - delta,-VALUE_INFINITE); beta = std::min(previousScore + delta, VALUE_INFINITE); - ct = Options["Contempt"] * PawnValueEg / 100; // From centipawns - // Adjust contempt based on root move's previousScore (dynamic contempt) - ct += int(std::round(48 * atan(float(previousScore) / 128))); + int dct = ct + int(std::round(48 * atan(float(previousScore) / 128))); - contempt = (us == WHITE ? make_score(ct, ct / 2) - : -make_score(ct, ct / 2)); + contempt = (us == WHITE ? make_score(dct, dct / 2) + : -make_score(dct, dct / 2)); } // Start with a small aspiration window and, in the case of a fail diff --git a/src/uci.h b/src/uci.h index 0b3550bd63e..0788bda28a3 100644 --- a/src/uci.h +++ b/src/uci.h @@ -50,11 +50,13 @@ class Option { Option(bool v, OnChange = nullptr); Option(const char* v, OnChange = nullptr); Option(int v, int minv, int maxv, OnChange = nullptr); + Option(const char* v, const char *cur, OnChange = nullptr); Option& operator=(const std::string&); void operator<<(const Option&); operator int() const; operator std::string() const; + bool operator==(const char*); private: friend std::ostream& operator<<(std::ostream&, const OptionsMap&); diff --git a/src/ucioption.cpp b/src/ucioption.cpp index bca4a1f1adb..d281d40d649 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -60,6 +60,7 @@ void init(OptionsMap& o) { o["Debug Log File"] << Option("", on_logger); o["Contempt"] << Option(12, -100, 100); + o["Analysis Contempt"] << Option("Both var Off var White var Black var Both", "Both"); o["Threads"] << Option(1, 1, 512, on_threads); o["Hash"] << Option(16, 1, MaxHashMB, on_hash_size); o["Clear Hash"] << Option(on_clear_hash); @@ -71,6 +72,7 @@ void init(OptionsMap& o) { o["Slow Mover"] << Option(84, 10, 1000); o["nodestime"] << Option(0, 0, 10000); o["UCI_Chess960"] << Option(false); + o["UCI_AnalyseMode"] << Option(false); o["SyzygyPath"] << Option("", on_tb_path); o["SyzygyProbeDepth"] << Option(1, 1, 100); o["Syzygy50MoveRule"] << Option(true); @@ -117,6 +119,9 @@ Option::Option(OnChange f) : type("button"), min(0), max(0), on_change(f) Option::Option(int v, int minv, int maxv, OnChange f) : type("spin"), min(minv), max(maxv), on_change(f) { defaultValue = currentValue = std::to_string(v); } +Option::Option(const char* v, const char* cur, OnChange f) : type("combo"), min(0), max(0), on_change(f) +{ defaultValue = v; currentValue = cur; } + Option::operator int() const { assert(type == "check" || type == "spin"); return (type == "spin" ? stoi(currentValue) : currentValue == "true"); @@ -127,6 +132,12 @@ Option::operator std::string() const { return currentValue; } +bool Option::operator==(const char* s) { + assert(type == "combo"); + return !CaseInsensitiveLess()(currentValue, s) + && !CaseInsensitiveLess()(s, currentValue); +} + /// operator<<() inits options and assigns idx in the correct printing order