Introduce 'on change' actions that are triggered as soon as
an UCI option is changed by the GUI. This allows to set hash
size before to start the game, helpful especially on very fast
TC and big TT size.
As a side effect remove the 'button' type option, that now
is managed as a 'check' type.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
#include <string>
#include "bitboard.h"
#include <string>
#include "bitboard.h"
#include "position.h"
#include "search.h"
#include "thread.h"
#include "position.h"
#include "search.h"
#include "thread.h"
kpk_bitbase_init();
Search::init();
Threads.init();
kpk_bitbase_init();
Search::init();
Threads.init();
+ TT.set_size(Options["Hash"]);
cout << engine_info() << endl;
cout << engine_info() << endl;
// Read UCI options: GUI could change UCI parameters during the game
read_evaluation_uci_options(pos.side_to_move());
// 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"];
UCIMultiPV = Options["MultiPV"];
SkillLevel = Options["Skill Level"];
void ThreadsManager::init() {
void ThreadsManager::init() {
cond_init(sleepCond);
lock_init(splitLock);
cond_init(sleepCond);
lock_init(splitLock);
#include "misc.h"
#include "thread.h"
#include "misc.h"
#include "thread.h"
#include "ucioption.h"
using std::string;
#include "ucioption.h"
using std::string;
OptionsMap Options; // Global object
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); }
/// Our case insensitive less() function as required by UCI protocol
static bool ci_less(char c1, char c2) { return tolower(c1) < tolower(c2); }
o["Space"] = UCIOption(100, 0, 200);
o["Aggressiveness"] = UCIOption(100, 0, 200);
o["Cowardice"] = UCIOption(100, 0, 200);
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["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);
o["Ponder"] = UCIOption(true);
o["OwnBook"] = UCIOption(true);
o["MultiPV"] = UCIOption(1, 1, 500);
/// UCIOption class c'tors
/// 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; }
{ 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"); }
{ 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(); }
{ std::ostringstream ss; ss << v; defaultValue = currentValue = ss.str(); }
assert(!type.empty());
if ( !v.empty()
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)))
&& (type != "spin" || (atoi(v.c_str()) >= min && atoi(v.c_str()) <= max)))
+
+ if (on_change_action)
+ (*on_change_action)(*this);
+ }
/// UCIOption class implements an option as defined by UCI protocol
class UCIOption {
/// UCIOption class implements an option as defined by UCI protocol
class UCIOption {
+
+ typedef void (Fn)(UCIOption&);
+
public:
UCIOption() {} // Required by std::map::operator[]
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"); }
void operator=(const std::string& v);
void operator=(bool v) { *this = std::string(v ? "true" : "false"); }
std::string defaultValue, currentValue, type;
int min, max;
size_t idx;
std::string defaultValue, currentValue, type;
int min, max;
size_t idx;