-////
-//// Local definitions
-////
-
-namespace {
-
- ///
- /// Types
- ///
-
- enum OptionType { SPIN, COMBO, CHECK, STRING, BUTTON };
-
- typedef std::vector<string> ComboValues;
-
- struct Option {
-
- string name, defaultValue, currentValue;
- OptionType type;
- size_t idx;
- int minValue, maxValue;
- ComboValues comboValues;
-
- Option();
- Option(const char* defaultValue, OptionType = STRING);
- Option(bool defaultValue, OptionType = CHECK);
- Option(int defaultValue, int minValue, int maxValue);
-
- bool operator<(const Option& o) const { return this->idx < o.idx; }
- };
-
- typedef std::map<string, Option> Options;
-
- ///
- /// Constants
- ///
-
- // load_defaults populates the options map with the hard
- // coded names and default values.
-
- void load_defaults(Options& o) {
-
- o["Use Search Log"] = Option(false);
- o["Search Log Filename"] = Option("SearchLog.txt");
- o["Book File"] = Option("book.bin");
- o["Mobility (Middle Game)"] = Option(100, 0, 200);
- o["Mobility (Endgame)"] = Option(100, 0, 200);
- o["Pawn Structure (Middle Game)"] = Option(100, 0, 200);
- o["Pawn Structure (Endgame)"] = Option(100, 0, 200);
- o["Passed Pawns (Middle Game)"] = Option(100, 0, 200);
- o["Passed Pawns (Endgame)"] = Option(100, 0, 200);
- o["Space"] = Option(100, 0, 200);
- o["Aggressiveness"] = Option(100, 0, 200);
- o["Cowardice"] = Option(100, 0, 200);
- o["King Safety Curve"] = Option("Quadratic", COMBO);
-
- o["King Safety Curve"].comboValues.push_back("Quadratic");
- o["King Safety Curve"].comboValues.push_back("Linear"); /*, "From File"*/
-
- o["King Safety Coefficient"] = Option(40, 1, 100);
- o["King Safety X Intercept"] = Option(0, 0, 20);
- o["King Safety Max Slope"] = Option(30, 10, 100);
- o["King Safety Max Value"] = Option(500, 100, 1000);
- o["Queen Contact Check Bonus"] = Option(3, 0, 8);
- o["Queen Check Bonus"] = Option(2, 0, 4);
- o["Rook Check Bonus"] = Option(1, 0, 4);
- o["Bishop Check Bonus"] = Option(1, 0, 4);
- o["Knight Check Bonus"] = Option(1, 0, 4);
- o["Discovered Check Bonus"] = Option(3, 0, 8);
- o["Mate Threat Bonus"] = Option(3, 0, 8);
- o["Check Extension (PV nodes)"] = Option(2, 0, 2);
- o["Check Extension (non-PV nodes)"] = Option(1, 0, 2);
- o["Single Reply Extension (PV nodes)"] = Option(2, 0, 2);
- o["Single Reply Extension (non-PV nodes)"] = Option(2, 0, 2);
- o["Mate Threat Extension (PV nodes)"] = Option(0, 0, 2);
- o["Mate Threat Extension (non-PV nodes)"] = Option(0, 0, 2);
- o["Pawn Push to 7th Extension (PV nodes)"] = Option(1, 0, 2);
- o["Pawn Push to 7th Extension (non-PV nodes)"] = Option(1, 0, 2);
- o["Passed Pawn Extension (PV nodes)"] = Option(1, 0, 2);
- o["Passed Pawn Extension (non-PV nodes)"] = Option(0, 0, 2);
- o["Pawn Endgame Extension (PV nodes)"] = Option(2, 0, 2);
- o["Pawn Endgame Extension (non-PV nodes)"] = Option(2, 0, 2);
- o["Full Depth Moves (PV nodes)"] = Option(14, 1, 100);
- o["Full Depth Moves (non-PV nodes)"] = Option(3, 1, 100);
- o["Threat Depth"] = Option(5, 0, 100);
- o["Futility Pruning (Main Search)"] = Option(true);
- o["Futility Pruning (Quiescence Search)"] = Option(true);
- o["LSN filtering"] = Option(true);
- o["LSN Time Margin (sec)"] = Option(4, 1, 10);
- o["LSN Value Margin"] = Option(200, 100, 600);
- o["Randomness"] = Option(0, 0, 10);
- o["Minimum Split Depth"] = Option(4, 4, 7);
- o["Maximum Number of Threads per Split Point"] = Option(5, 4, 8);
- o["Threads"] = Option(1, 1, 8);
- o["Hash"] = Option(32, 4, 4096);
- o["Clear Hash"] = Option(false, BUTTON);
- o["Ponder"] = Option(true);
- o["OwnBook"] = Option(true);
- o["MultiPV"] = Option(1, 1, 500);
- o["UCI_ShowCurrLine"] = Option(false);
- o["UCI_Chess960"] = Option(false);
-
- // Any option should know its name so to be easily printed
- for (Options::iterator it = o.begin(); it != o.end(); ++it)
- it->second.name = it->first;
- }
-
- ///
- /// Variables
- ///
-
- Options options;
-
- // stringify converts a value of type T to a std::string
- template<typename T>
- string stringify(const T& v) {
-
- std::ostringstream ss;
- ss << v;
- return ss.str();
- }
-
-
- // get_option_value implements the various get_option_value_<type>
- // functions defined later, because only the option value
- // type changes a template seems a proper solution.
-
- template<typename T>
- T get_option_value(const string& optionName) {
-
- T ret = T();
- if (options.find(optionName) == options.end())
- return ret;
-
- std::istringstream ss(options[optionName].currentValue);
- ss >> ret;
- return ret;
- }
-
-}
-
-////
-//// Functions
-////
-
-/// init_uci_options() initializes the UCI options. Currently, the only
-/// thing this function does is to initialize the default value of the
-/// "Threads" parameter to the number of available CPU cores.
-
-void init_uci_options() {
-
- load_defaults(options);
-
- // Limit the default value of "Threads" to 7 even if we have 8 CPU cores.
- // According to Ken Dail's tests, Glaurung plays much better with 7 than
- // with 8 threads. This is weird, but it is probably difficult to find out
- // why before I have a 8-core computer to experiment with myself.
- assert(options.find("Threads") != options.end());
- assert(options.find("Minimum Split Depth") != options.end());
-
- options["Threads"].defaultValue = stringify(Min(cpu_count(), 7));
- options["Threads"].currentValue = stringify(Min(cpu_count(), 7));
-
- // Increase the minimum split depth when the number of CPUs is big.
- // It would probably be better to let this depend on the number of threads
- // instead.
- if (cpu_count() > 4)
- {
- options["Minimum Split Depth"].defaultValue = "6";
- options["Minimum Split Depth"].currentValue = "6";
- }
-}
-
-
-/// print_uci_options() prints all the UCI options to the standard output,
-/// in the format defined by the UCI protocol.