diff --git a/src/main.cpp b/src/main.cpp index 5a32ae3d..920d9481 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,7 @@ #include #include "bitboard.h" +#include "ucioption.h" #include "position.h" #include "search.h" #include "thread.h" @@ -38,6 +39,7 @@ int main(int argc, char* argv[]) { kpk_bitbase_init(); Search::init(); Threads.init(); + TT.set_size(Options["Hash"]); cout << engine_info() << endl; diff --git a/src/search.cpp b/src/search.cpp index 03df6d78..ea777dcc 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -278,14 +278,6 @@ void Search::think() { // Read UCI options: GUI could change UCI parameters during the game read_evaluation_uci_options(pos.side_to_move()); - Threads.read_uci_options(); - - TT.set_size(Options["Hash"]); - if (Options["Clear Hash"]) - { - Options["Clear Hash"] = false; - TT.clear(); - } UCIMultiPV = Options["MultiPV"]; SkillLevel = Options["Skill Level"]; diff --git a/src/thread.cpp b/src/thread.cpp index 7ffc3dfe..358ced5d 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -216,6 +216,8 @@ void ThreadsManager::set_size(int cnt) { void ThreadsManager::init() { + read_uci_options(); + cond_init(sleepCond); lock_init(splitLock); diff --git a/src/ucioption.cpp b/src/ucioption.cpp index c754353e..2f4d6f46 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -22,6 +22,7 @@ #include "misc.h" #include "thread.h" +#include "tt.h" #include "ucioption.h" using std::string; @@ -29,6 +30,12 @@ using std::string; OptionsMap Options; // Global object +/// 'On change' actions, triggered by an option's change event +static void on_threads(UCIOption&) { Threads.read_uci_options(); } +static void on_hash_size(UCIOption& o) { TT.set_size(o); } +static void on_clear_hash(UCIOption& o) { TT.clear(); o = false; } // UCI button + + /// Our case insensitive less() function as required by UCI protocol static bool ci_less(char c1, char c2) { return tolower(c1) < tolower(c2); } @@ -58,12 +65,12 @@ OptionsMap::OptionsMap() { o["Space"] = UCIOption(100, 0, 200); o["Aggressiveness"] = UCIOption(100, 0, 200); o["Cowardice"] = UCIOption(100, 0, 200); - o["Min Split Depth"] = UCIOption(msd, 4, 7); - o["Max Threads per Split Point"] = UCIOption(5, 4, 8); + o["Min Split Depth"] = UCIOption(msd, 4, 7, on_threads); + o["Max Threads per Split Point"] = UCIOption(5, 4, 8, on_threads); o["Threads"] = UCIOption(cpus, 1, MAX_THREADS); - o["Use Sleeping Threads"] = UCIOption(true); - o["Hash"] = UCIOption(32, 4, 8192); - o["Clear Hash"] = UCIOption(false, "button"); + o["Use Sleeping Threads"] = UCIOption(true, on_threads); + o["Hash"] = UCIOption(32, 4, 8192, on_hash_size); + o["Clear Hash"] = UCIOption(false, on_clear_hash); o["Ponder"] = UCIOption(true); o["OwnBook"] = UCIOption(true); o["MultiPV"] = UCIOption(1, 1, 500); @@ -103,13 +110,13 @@ std::ostream& operator<<(std::ostream& os, const OptionsMap& om) { /// UCIOption class c'tors -UCIOption::UCIOption(const char* v) : type("string"), min(0), max(0), idx(Options.size()) +UCIOption::UCIOption(const char* v, Fn* f) : type("string"), min(0), max(0), idx(Options.size()), on_change_action(f) { defaultValue = currentValue = v; } -UCIOption::UCIOption(bool v, string t) : type(t), min(0), max(0), idx(Options.size()) +UCIOption::UCIOption(bool v, Fn* f) : type("check"), min(0), max(0), idx(Options.size()), on_change_action(f) { defaultValue = currentValue = (v ? "true" : "false"); } -UCIOption::UCIOption(int v, int minv, int maxv) : type("spin"), min(minv), max(maxv), idx(Options.size()) +UCIOption::UCIOption(int v, int minv, int maxv, Fn* f) : type("spin"), min(minv), max(maxv), idx(Options.size()), on_change_action(f) { std::ostringstream ss; ss << v; defaultValue = currentValue = ss.str(); } @@ -122,7 +129,12 @@ void UCIOption::operator=(const string& v) { assert(!type.empty()); if ( !v.empty() - && (type == "check" || type == "button") == (v == "true" || v == "false") + && (type == "check") == (v == "true" || v == "false") && (type != "spin" || (atoi(v.c_str()) >= min && atoi(v.c_str()) <= max))) + { currentValue = v; + + if (on_change_action) + (*on_change_action)(*this); + } } diff --git a/src/ucioption.h b/src/ucioption.h index f80ff86e..8150bb0b 100644 --- a/src/ucioption.h +++ b/src/ucioption.h @@ -29,11 +29,14 @@ struct OptionsMap; /// UCIOption class implements an option as defined by UCI protocol class UCIOption { + + typedef void (Fn)(UCIOption&); + public: UCIOption() {} // Required by std::map::operator[] - UCIOption(const char* v); - UCIOption(bool v, std::string type = "check"); - UCIOption(int v, int min, int max); + UCIOption(const char* v, Fn* = NULL); + UCIOption(bool v, Fn* = NULL); + UCIOption(int v, int min, int max, Fn* = NULL); void operator=(const std::string& v); void operator=(bool v) { *this = std::string(v ? "true" : "false"); } @@ -54,6 +57,7 @@ private: std::string defaultValue, currentValue, type; int min, max; size_t idx; + Fn* on_change_action; };