2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
4 Copyright (C) 2008-2012 Marco Costalba, Joona Kiiski, Tord Romstad
6 Stockfish is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 Stockfish is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "ucioption.h"
29 OptionsMap Options; // Global object
32 /// Our case insensitive less() function as required by UCI protocol
33 static bool ci_less(char c1, char c2) { return tolower(c1) < tolower(c2); }
35 bool CaseInsensitiveLess::operator() (const string& s1, const string& s2) const {
36 return lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), ci_less);
40 /// OptionsMap c'tor initializes the UCI options to their hard coded default
41 /// values and initializes the default value of "Threads" and "Min Split Depth"
42 /// parameters according to the number of CPU cores detected.
44 OptionsMap::OptionsMap() {
46 int cpus = std::min(cpu_count(), MAX_THREADS);
47 int msd = cpus < 8 ? 4 : 7;
48 OptionsMap& o = *this;
50 o["Use Search Log"] = UCIOption(false);
51 o["Search Log Filename"] = UCIOption("SearchLog.txt");
52 o["Book File"] = UCIOption("book.bin");
53 o["Best Book Move"] = UCIOption(false);
54 o["Mobility (Middle Game)"] = UCIOption(100, 0, 200);
55 o["Mobility (Endgame)"] = UCIOption(100, 0, 200);
56 o["Passed Pawns (Middle Game)"] = UCIOption(100, 0, 200);
57 o["Passed Pawns (Endgame)"] = UCIOption(100, 0, 200);
58 o["Space"] = UCIOption(100, 0, 200);
59 o["Aggressiveness"] = UCIOption(100, 0, 200);
60 o["Cowardice"] = UCIOption(100, 0, 200);
61 o["Min Split Depth"] = UCIOption(msd, 4, 7);
62 o["Max Threads per Split Point"] = UCIOption(5, 4, 8);
63 o["Threads"] = UCIOption(cpus, 1, MAX_THREADS);
64 o["Use Sleeping Threads"] = UCIOption(true);
65 o["Hash"] = UCIOption(32, 4, 8192);
66 o["Clear Hash"] = UCIOption(false, "button");
67 o["Ponder"] = UCIOption(true);
68 o["OwnBook"] = UCIOption(true);
69 o["MultiPV"] = UCIOption(1, 1, 500);
70 o["Skill Level"] = UCIOption(20, 0, 20);
71 o["Emergency Move Horizon"] = UCIOption(40, 0, 50);
72 o["Emergency Base Time"] = UCIOption(200, 0, 30000);
73 o["Emergency Move Time"] = UCIOption(70, 0, 5000);
74 o["Minimum Thinking Time"] = UCIOption(20, 0, 5000);
75 o["UCI_Chess960"] = UCIOption(false);
76 o["UCI_AnalyseMode"] = UCIOption(false);
80 /// operator<<() is used to output all the UCI options in chronological insertion
81 /// order (the idx field) and in the format defined by the UCI protocol.
82 std::ostream& operator<<(std::ostream& os, const OptionsMap& om) {
84 for (size_t idx = 0; idx < om.size(); idx++)
85 for (OptionsMap::const_iterator it = om.begin(); it != om.end(); ++it)
86 if (it->second.idx == idx)
88 const UCIOption& o = it->second;
89 os << "\noption name " << it->first << " type " << o.type;
91 if (o.type != "button")
92 os << " default " << o.defaultValue;
95 os << " min " << o.min << " max " << o.max;
103 /// UCIOption class c'tors
105 UCIOption::UCIOption(const char* v) : type("string"), min(0), max(0), idx(Options.size())
106 { defaultValue = currentValue = v; }
108 UCIOption::UCIOption(bool v, string t) : type(t), min(0), max(0), idx(Options.size())
109 { defaultValue = currentValue = (v ? "true" : "false"); }
111 UCIOption::UCIOption(int v, int minv, int maxv) : type("spin"), min(minv), max(maxv), idx(Options.size())
112 { std::ostringstream ss; ss << v; defaultValue = currentValue = ss.str(); }
115 /// UCIOption::operator=() updates currentValue. Normally it's up to the GUI to
116 /// check for option's limits, but we could receive the new value directly from
117 /// the user by teminal window, so let's check the bounds anyway.
119 void UCIOption::operator=(const string& v) {
121 assert(!type.empty());
124 && (type == "check" || type == "button") == (v == "true" || v == "false")
125 && (type != "spin" || (atoi(v.c_str()) >= min && atoi(v.c_str()) <= max)))