Line data Source code
1 : #include "option.hpp"
2 :
3 : #include "com.hpp"
4 : #include "dynamicConfig.hpp"
5 : #include "logging.hpp"
6 : #include "opponent.hpp"
7 : #include "searcher.hpp"
8 : #include "searchConfig.hpp"
9 : #include "threading.hpp"
10 : #include "uci.hpp"
11 :
12 : #ifdef WITH_NNUE
13 : #include "nnue.hpp"
14 : #endif
15 :
16 : namespace Options {
17 :
18 : enum KeyType : uint8_t { k_bad = 0, k_bool, k_depth, k_int, k_score, k_ull, k_string };
19 : enum WidgetType : uint8_t { w_check = 0, w_string, w_spin, w_combo, w_button, w_max };
20 : struct KeyBase {
21 : template<typename T>
22 66 : KeyBase(
23 : KeyType t,
24 : WidgetType w,
25 : const std::string& k,
26 : T* v,
27 : const std::function<void(void)>& cb = [] {}):
28 66 : type(t), wtype(w), key(k), value(static_cast<void*>(v)) {
29 66 : callBack = cb;
30 66 : }
31 : template<typename T>
32 839 : KeyBase(
33 : KeyType t,
34 : WidgetType w,
35 : const std::string& k,
36 : T* v,
37 : const T& _vmin,
38 : const T& _vmax,
39 : const std::function<void(void)>& cb = [] {}):
40 839 : type(t), wtype(w), key(k), value(static_cast<void*>(v)), vmin(_vmin), vmax(_vmax) {
41 839 : callBack = cb;
42 839 : }
43 : template<typename T>
44 22 : KeyBase(
45 : KeyType t,
46 : WidgetType w,
47 : const std::string& k,
48 : T* v,
49 : std::vector<std::string> vals,
50 : const std::function<void(void)>& cb = [] {}):
51 22 : type(t), wtype(w), key(k), value(static_cast<void*>(v)), values(vals) {
52 22 : callBack = cb;
53 22 : }
54 : KeyType type;
55 : WidgetType wtype;
56 : std::string key;
57 : void* value;
58 : int vmin = 0, vmax = 0; // assume int type is covering all the case (string excluded ...)
59 : std::vector<std::string> values; // only use for combo
60 : bool hotPlug = false;
61 : std::function<void(void)> callBack;
62 : };
63 :
64 : std::vector<std::string> args;
65 : std::vector<KeyBase> _keys;
66 :
67 : constexpr array1d<std::string_view, w_max> widgetXboardNames = {"check", "string", "spin", "combo", "button"};
68 :
69 565 : KeyBase& GetKey(const std::string& key) {
70 : bool keyFound = false;
71 : static int dummy = 0;
72 571 : static KeyBase badKey(k_bad, w_button, "bad_default_key", &dummy, 0, 0);
73 : KeyBase* keyRef = &badKey;
74 12128 : for (auto & e : _keys) {
75 12128 : if (key == e.key) {
76 : keyRef = &e;
77 : keyFound = true;
78 : break;
79 : }
80 : }
81 565 : if (!keyFound) Logging::LogIt(Logging::logWarn) << "Key not found " << key;
82 565 : return *keyRef;
83 : }
84 :
85 481 : int GetValue(const std::string& key) { // assume we can convert to int safely (not valid for string of course !)
86 481 : const KeyBase& k = GetKey(key);
87 481 : switch (k.type) {
88 156 : case k_bool: return static_cast<int>(*static_cast<bool*>(k.value));
89 0 : case k_depth: return static_cast<int>(*static_cast<DepthType*>(k.value));
90 286 : case k_int: return static_cast<int>(*static_cast<int*>(k.value));
91 39 : case k_score: return static_cast<int>(*static_cast<ScoreType*>(k.value));
92 0 : case k_ull: return static_cast<int>(*static_cast<uint64_t*>(k.value));
93 : case k_string:
94 : case k_bad:
95 0 : default: Logging::LogIt(Logging::logError) << "Bad key type"; return false;
96 : }
97 : }
98 :
99 47 : std::string GetValueString(const std::string& key) { // the one for string
100 47 : const KeyBase& k = GetKey(key);
101 47 : if (k.type != k_string) Logging::LogIt(Logging::logError) << "Bad key type (string expected)";
102 47 : return *static_cast<std::string*>(k.value);
103 : }
104 :
105 : template <typename Range, typename Value = typename Range::value_type>
106 1 : std::string join(Range const& elements, const char *const delimiter) {
107 1 : std::ostringstream os;
108 : auto b = begin(elements);
109 : auto e = end(elements);
110 :
111 1 : os << delimiter;
112 :
113 1 : if (b != e) {
114 : std::copy(b, prev(e), std::ostream_iterator<Value>(os, delimiter));
115 : b = prev(e);
116 : }
117 1 : if (b != e) {
118 : os << *b;
119 : }
120 :
121 1 : return os.str();
122 1 : }
123 :
124 1 : std::string GetComboVar(const std::string& key) { // the one for string with combo
125 1 : const KeyBase& k = GetKey(key);
126 1 : if (k.wtype != w_combo) Logging::LogIt(Logging::logError) << "Bad key wtype (combo expected)";
127 1 : return join(k.values, " var ");
128 : }
129 :
130 10 : void displayOptionsDebug() {
131 430 : for (const auto & it : _keys)
132 420 : if (it.type == k_string)
133 120 : Logging::LogIt(Logging::logInfo) << "option=\"" << it.key << " -" << widgetXboardNames[it.wtype] << " " << GetValueString(it.key) << "\"";
134 380 : else if (it.type == k_bool)
135 260 : Logging::LogIt(Logging::logInfo) << "option=\"" << it.key << " -" << widgetXboardNames[it.wtype] << " "
136 130 : << (GetValue(it.key) ? "true" : "false") << "\"";
137 : else
138 750 : Logging::LogIt(Logging::logInfo) << "option=\"" << it.key << " -" << widgetXboardNames[it.wtype] << " " << GetValue(it.key) << " "
139 : << it.vmin << " " << it.vmax << "\"";
140 10 : }
141 :
142 1 : void displayOptionsXBoard() {
143 43 : for (const auto & it : _keys)
144 42 : if (it.type == k_string){
145 4 : if ( it.wtype == w_combo){
146 : ///@todo
147 : }
148 : else {
149 9 : Logging::LogIt(Logging::logGUI) << "feature option=\"" << it.key << " -" << widgetXboardNames[it.wtype] << " " << GetValueString(it.key)
150 : << "\"";
151 : }
152 : }
153 38 : else if (it.type == k_bool)
154 39 : Logging::LogIt(Logging::logGUI) << "feature option=\"" << it.key << " -" << widgetXboardNames[it.wtype] << " " << bool(GetValue(it.key))
155 : << "\"";
156 : else
157 75 : Logging::LogIt(Logging::logGUI) << "feature option=\"" << it.key << " -" << widgetXboardNames[it.wtype] << " " << GetValue(it.key)
158 : << " " << it.vmin << " " << it.vmax << "\"";
159 1 : }
160 :
161 1 : void displayOptionsUCI() {
162 43 : for (const auto & it : _keys)
163 42 : if (it.type == k_string){
164 4 : if ( it.wtype == w_combo){
165 2 : Logging::LogIt(Logging::logGUI) << "option name " << it.key << " type " << widgetXboardNames[it.wtype] << " default "
166 3 : << GetValueString(it.key) << GetComboVar(it.key);
167 : }
168 : else {
169 6 : Logging::LogIt(Logging::logGUI) << "option name " << it.key << " type " << widgetXboardNames[it.wtype] << " default "
170 6 : << GetValueString(it.key);
171 : }
172 : }
173 38 : else if (it.type == k_bool)
174 26 : Logging::LogIt(Logging::logGUI) << "option name " << it.key << " type " << widgetXboardNames[it.wtype] << " default "
175 13 : << (GetValue(it.key) ? "true" : "false");
176 : else
177 50 : Logging::LogIt(Logging::logGUI) << "option name " << it.key << " type " << widgetXboardNames[it.wtype] << " default "
178 25 : << GetValue(it.key) << " min " << it.vmin << " max " << it.vmax;
179 1 : }
180 :
181 1 : void displayOptionsSPSA() {
182 43 : for (const auto & it : _keys)
183 42 : if (it.type == k_string){
184 4 : Logging::LogIt(Logging::logGUI) << "Skipping string option " << it.key;
185 : }
186 38 : else if (it.type == k_bool)
187 13 : Logging::LogIt(Logging::logGUI) << "Skipping bool option " << it.key;
188 : else{
189 25 : const KeyBase& k = GetKey(it.key);
190 25 : int curBest = GetValue(it.key);
191 25 : int spsaMin = std::max(it.vmin, static_cast<int>(curBest*0.5));
192 25 : int spsaMax = std::min(it.vmax, static_cast<int>(curBest*1.5));
193 25 : switch (k.type) {
194 0 : case k_depth: spsaMin = std::max(it.vmin, 0); spsaMax = std::min(it.vmax, 20); break;
195 24 : case k_int: if(curBest==0) {spsaMin = std::max(it.vmin, -500); spsaMax = std::min(it.vmax, 500);} break;
196 3 : case k_score: if(curBest==0) {spsaMin = std::max(it.vmin, -500); spsaMax = std::min(it.vmax, 500);} break;
197 0 : case k_ull: if(curBest==0) {spsaMin = std::max(it.vmin, -500); spsaMax = std::min(it.vmax, 500);} break;
198 : case k_string:
199 : case k_bool:
200 : case k_bad:
201 0 : default: Logging::LogIt(Logging::logError) << "Bad key type";
202 : }
203 25 : if (curBest < 0) std::swap(spsaMin, spsaMax);
204 25 : Logging::LogIt(Logging::logGUI) << it.key << ", int, " << curBest << ", "
205 : << spsaMin << ", "
206 : << spsaMax << ", "
207 67 : << std::min(16, std::max(1, int(spsaMax-spsaMin)/20)) << ", "
208 : << "0.002";
209 : }
210 1 : }
211 :
212 : #define SETVALUE(TYPEIN, TYPEOUT) \
213 : { \
214 : TYPEIN v; \
215 : str >> std::boolalpha >> v; \
216 : *static_cast<TYPEOUT*>(keyRef.value) = (TYPEOUT)v; \
217 : } \
218 : break;
219 : #define SETVALUESTR(TYPEIN, TYPEOUT) \
220 : { \
221 : TYPEIN v; \
222 : getline(str, v); \
223 : *static_cast<TYPEOUT*>(keyRef.value) = (TYPEOUT)v; \
224 : } \
225 : break;
226 :
227 11 : bool SetValue(const std::string& key, const std::string& val) {
228 11 : KeyBase& keyRef = GetKey(key);
229 11 : if (!keyRef.hotPlug && ThreadPool::instance().main().searching()) {
230 1 : Logging::LogIt(Logging::logError) << "Cannot change " << key << " during a search";
231 1 : return false;
232 : }
233 : std::string value = val;
234 10 : if (keyRef.type == k_bool) {
235 2 : if (value == "0") value = "false";
236 2 : else if (value == "1")
237 : value = "true";
238 : }
239 10 : std::stringstream str(value);
240 10 : switch (keyRef.type) {
241 2 : case k_bool: SETVALUE(bool, bool)
242 0 : case k_depth: SETVALUE(int, DepthType)
243 7 : case k_int: SETVALUE(int, int)
244 0 : case k_score: SETVALUE(int, ScoreType)
245 0 : case k_ull: SETVALUE(int, uint64_t)
246 3 : case k_string: SETVALUESTR(std::string, std::string)
247 : case k_bad:
248 0 : default: Logging::LogIt(Logging::logError) << "Bad key type"; return false;
249 : }
250 10 : Logging::LogIt(Logging::logInfo) << "Option set " << key << "=" << value;
251 10 : if (keyRef.callBack) {
252 10 : Logging::LogIt(Logging::logInfo) << "Calling callback for option " << key << "=" << value;
253 : keyRef.callBack();
254 : }
255 10 : displayOptionsDebug();
256 : return true;
257 10 : }
258 :
259 : template<typename C>
260 : void addOptions(C & coeff){
261 : for (size_t k = 0; k < coeff.N; ++k){
262 : _keys.emplace_back(k_depth, w_spin, coeff.getName(SearchConfig::CNT_minDepth,k), &coeff.minDepth[k] , DepthType(0) , DepthType(MAX_DEPTH) );
263 : _keys.emplace_back(k_depth, w_spin, coeff.getName(SearchConfig::CNT_maxdepth,k), &coeff.maxDepth[k] , DepthType(0) , DepthType(MAX_DEPTH) );
264 : _keys.emplace_back(k_score, w_spin, coeff.getName(SearchConfig::CNT_slopeD,k) , &coeff.slopeDepth[k] , ScoreType(-1500) , ScoreType(1500));
265 : _keys.emplace_back(k_score, w_spin, coeff.getName(SearchConfig::CNT_slopeGP,k) , &coeff.slopeGamePhase[k] , ScoreType(-1500) , ScoreType(1500));
266 : _keys.emplace_back(k_score, w_spin, coeff.getName(SearchConfig::CNT_init,k) , &coeff.init[k] , ScoreType(-1500) , ScoreType(1500));
267 : }
268 : for (size_t k = 0; k < coeff.M; ++k){
269 : _keys.emplace_back(k_score, w_spin, coeff.getName(SearchConfig::CNT_bonus,k) , &coeff.bonus[k] , ScoreType(-1500) , ScoreType(1500));
270 : }
271 : }
272 :
273 22 : void registerCOMOptions() { // options exposed to GUI
274 :
275 : #ifdef WITH_SEARCH_TUNING
276 : addOptions(SearchConfig::staticNullMoveCoeff);
277 : addOptions(SearchConfig::razoringCoeff);
278 : addOptions(SearchConfig::threatCoeff);
279 : addOptions(SearchConfig::historyPruningCoeff);
280 : addOptions(SearchConfig::captureHistoryPruningCoeff);
281 : addOptions(SearchConfig::futilityPruningCoeff);
282 : addOptions(SearchConfig::failHighReductionCoeff);
283 : #endif
284 :
285 22 : _keys.emplace_back(k_int, w_spin, "Level" , &DynamicConfig::level , (unsigned int)0 , (unsigned int)100);
286 22 : _keys.emplace_back(k_bool, w_check, "nodesBasedLevel" , &DynamicConfig::nodesBasedLevel , false , true);
287 22 : _keys.emplace_back(k_bool, w_check, "UCI_LimitStrength" , &DynamicConfig::limitStrength , false , true);
288 22 : _keys.emplace_back(k_int, w_spin, "UCI_Elo" , &DynamicConfig::strength , (int)500 , (int)2800);
289 22 : _keys.emplace_back(k_int, w_spin, "Hash" , &DynamicConfig::ttSizeMb , (unsigned int)1 , (unsigned int)256000 , &TT::initTable);
290 22 : _keys.emplace_back(k_int, w_spin, "PawnHash" , &DynamicConfig::ttPawnSizeMb , (unsigned int)1 , (unsigned int)4096 , &ThreadPool::initPawnTables);
291 22 : _keys.emplace_back(k_int, w_spin, "Threads" , &DynamicConfig::threads , (unsigned int)1 , (unsigned int)(MAX_THREADS-1) , std::bind(&ThreadPool::setup, &ThreadPool::instance()));
292 22 : _keys.emplace_back(k_bool, w_check, "UCI_Chess960" , &DynamicConfig::FRC , false , true);
293 22 : _keys.emplace_back(k_bool, w_check, "Ponder" , &DynamicConfig::UCIPonder , false , true);
294 22 : _keys.emplace_back(k_bool, w_check, "MateFinder" , &DynamicConfig::mateFinder , false , true);
295 22 : _keys.emplace_back(k_int, w_spin, "MultiPV" , &DynamicConfig::multiPV , (unsigned int)1 , (unsigned int)4);
296 22 : _keys.emplace_back(k_int, w_spin, "RandomOpen" , &DynamicConfig::randomOpen , (unsigned int)0 , (unsigned int)100);
297 22 : _keys.emplace_back(k_int, w_spin, "MinMoveOverHead" , &DynamicConfig::moveOverHead , (unsigned int)10 , (unsigned int)1000);
298 22 : _keys.emplace_back(k_score, w_spin, "Contempt" , &DynamicConfig::contempt , (ScoreType)-50 , (ScoreType)50);
299 22 : _keys.emplace_back(k_score, w_spin, "ContemptMG" , &DynamicConfig::contemptMG , (ScoreType)-50 , (ScoreType)50);
300 22 : _keys.emplace_back(k_bool, w_check, "Armageddon" , &DynamicConfig::armageddon , false , true);
301 22 : _keys.emplace_back(k_bool, w_check, "AntiChess" , &DynamicConfig::antichess , false , true);
302 22 : _keys.emplace_back(k_bool, w_check, "WDL_display" , &DynamicConfig::withWDL , false , true);
303 22 : _keys.emplace_back(k_bool, w_check, "bongCloud" , &DynamicConfig::bongCloud , false , true);
304 22 : _keys.emplace_back(k_bool, w_check, "anarchy" , &DynamicConfig::anarchy , false , true);
305 22 : _keys.emplace_back(k_score, w_spin, "badCapLimit" , &DynamicConfig::badCapLimit , (ScoreType)-1500 , (ScoreType)1500);
306 :
307 : #ifdef WITH_SYZYGY
308 22 : _keys.emplace_back(k_string,w_string,"SyzygyPath" , &DynamicConfig::syzygyPath , &SyzygyTb::initTB);
309 : #endif
310 :
311 : #ifdef WITH_NNUE
312 22 : _keys.emplace_back(k_string,w_string,"NNUEFile" , &DynamicConfig::NNUEFile , &NNUEWrapper::init);
313 22 : _keys.emplace_back(k_bool, w_check, "forceNNUE" , &DynamicConfig::forceNNUE , false , true);
314 22 : _keys.emplace_back(k_int, w_spin, "NNUEScaling" , &DynamicConfig::NNUEScaling , (int)32 , (int)256);
315 22 : _keys.emplace_back(k_int, w_spin, "NNUEThreshold" , &DynamicConfig::NNUEThreshold , (int)0 , (int)1500);
316 22 : _keys.emplace_back(k_int, w_spin, "NNUEThreshold2" , &DynamicConfig::NNUEThreshold2 , (int)0 , (int)1500);
317 : #endif
318 :
319 : #ifdef WITH_GENFILE
320 22 : _keys.emplace_back(k_bool, w_check, "GenFen" , &DynamicConfig::genFen , false , true);
321 22 : _keys.emplace_back(k_bool, w_check, "PgnOut" , &DynamicConfig::pgnOut , false , true);
322 22 : _keys.emplace_back(k_int, w_spin, "GenFenDepth" , &DynamicConfig::genFenDepth , (unsigned int)2 , (unsigned int)40);
323 22 : _keys.emplace_back(k_int, w_spin, "GenFenDepthEG" , &DynamicConfig::genFenDepthEG , (unsigned int)2 , (unsigned int)40);
324 22 : _keys.emplace_back(k_int, w_spin, "RandomPly" , &DynamicConfig::randomPly , (unsigned int)0 , (unsigned int)40);
325 : //_keys.emplace_back(k_ull, w_spin, "MaxNodes" , &TimeMan::maxNodes , (uint64_t)0 , (uint64_t)100000000);
326 : #endif
327 :
328 22 : _keys.emplace_back(k_int, w_spin, "StyleAttack" , &DynamicConfig::styleAttack , (int)0 , (int)100 , &EvalFeatures::callBack);
329 22 : _keys.emplace_back(k_int, w_spin, "StyleComplexity" , &DynamicConfig::styleComplexity , (int)0 , (int)100 , &EvalFeatures::callBack);
330 22 : _keys.emplace_back(k_int, w_spin, "StyleDevelopment" , &DynamicConfig::styleDevelopment , (int)0 , (int)100 , &EvalFeatures::callBack);
331 22 : _keys.emplace_back(k_int, w_spin, "StyleMaterial" , &DynamicConfig::styleMaterial , (int)0 , (int)100 , &EvalFeatures::callBack);
332 22 : _keys.emplace_back(k_int, w_spin, "StyleMobility" , &DynamicConfig::styleMobility , (int)0 , (int)100 , &EvalFeatures::callBack);
333 22 : _keys.emplace_back(k_int, w_spin, "StylePositional" , &DynamicConfig::stylePositional , (int)0 , (int)100 , &EvalFeatures::callBack);
334 22 : _keys.emplace_back(k_int, w_spin, "StyleForwardness" , &DynamicConfig::styleForwardness , (int)0 , (int)100 , &EvalFeatures::callBack);
335 :
336 22 : _keys.emplace_back(k_string, w_string,"UCI_Opponent" , &DynamicConfig::opponent /*, &Opponent::init*/);
337 22 : _keys.emplace_back(k_int, w_spin, "UCI_RatingAdv" , &DynamicConfig::ratingAdv , (int)-10000, (int)10000 , &Opponent::ratingReceived);
338 :
339 110 : _keys.emplace_back(k_string, w_combo, "UCI_Variant" , &DynamicConfig::chessvariant , std::vector<std::string>{ "chess", "antichess", "armageddon", "fischerandom"} , &UCI::handleVariant);
340 :
341 : #ifdef WITH_SEARCH_TUNING
342 :
343 : _keys.emplace_back(k_depth, w_spin, "aspirationMinDepth" , &SearchConfig::aspirationMinDepth , DepthType(0) , DepthType(30) );
344 : _keys.emplace_back(k_score, w_spin, "aspirationInit" , &SearchConfig::aspirationInit , ScoreType(0) , ScoreType(30) );
345 : _keys.emplace_back(k_score, w_spin, "aspirationDepthInit" , &SearchConfig::aspirationDepthInit , ScoreType(-150) , ScoreType(150) );
346 : _keys.emplace_back(k_score, w_spin, "aspirationDepthCoef" , &SearchConfig::aspirationDepthCoef , ScoreType(-10) , ScoreType(10) );
347 :
348 : _keys.emplace_back(k_score, w_spin, "qfutilityMargin0" , &SearchConfig::qfutilityMargin[0] , ScoreType(-200) , ScoreType(1500) );
349 : _keys.emplace_back(k_score, w_spin, "qfutilityMargin1" , &SearchConfig::qfutilityMargin[1] , ScoreType(-200) , ScoreType(1500) );
350 :
351 : _keys.emplace_back(k_depth, w_spin, "nullMoveMinDepth" , &SearchConfig::nullMoveMinDepth , DepthType(0) , DepthType(30) );
352 : _keys.emplace_back(k_depth, w_spin, "nullMoveVerifDepth" , &SearchConfig::nullMoveVerifDepth , DepthType(0) , DepthType(30) );
353 : _keys.emplace_back(k_score, w_spin, "nullMoveMargin" , &SearchConfig::nullMoveMargin , ScoreType(-500) , ScoreType(500) );
354 : _keys.emplace_back(k_score, w_spin, "nullMoveMargin2" , &SearchConfig::nullMoveMargin2 , ScoreType(-500) , ScoreType(500) );
355 : _keys.emplace_back(k_score, w_spin, "nullMoveReductionInit" , &SearchConfig::nullMoveReductionInit , ScoreType(1) , ScoreType(10) );
356 : _keys.emplace_back(k_score, w_spin, "nullMoveReductionDepthDivisor" , &SearchConfig::nullMoveReductionDepthDivisor , ScoreType(1) , ScoreType(10) );
357 : _keys.emplace_back(k_score, w_spin, "nullMoveDynamicDivisor" , &SearchConfig::nullMoveDynamicDivisor , ScoreType(1) , ScoreType(1500) );
358 :
359 : _keys.emplace_back(k_score, w_spin, "historyExtensionThreshold" , &SearchConfig::historyExtensionThreshold , ScoreType(1) , ScoreType(1500) );
360 :
361 :
362 : _keys.emplace_back(k_depth, w_spin, "CMHMaxDepth0" , &SearchConfig::CMHMaxDepth[0] , DepthType(0) , DepthType(30) );
363 : _keys.emplace_back(k_depth, w_spin, "CMHMaxDepth1" , &SearchConfig::CMHMaxDepth[1] , DepthType(0) , DepthType(30) );
364 : //_keys.emplace_back(k_score, w_spin, "randomAggressiveReductionFactor" , &SearchConfig::randomAggressiveReductionFactor , ScoreType(-10) , ScoreType(10) );
365 :
366 : _keys.emplace_back(k_depth, w_spin, "iidMinDepth" , &SearchConfig::iidMinDepth , DepthType(0) , DepthType(30) );
367 : _keys.emplace_back(k_depth, w_spin, "iidMinDepth2" , &SearchConfig::iidMinDepth2 , DepthType(0) , DepthType(30) );
368 : _keys.emplace_back(k_depth, w_spin, "iidMinDepth3" , &SearchConfig::iidMinDepth3 , DepthType(0) , DepthType(30) );
369 : _keys.emplace_back(k_depth, w_spin, "probCutMinDepth" , &SearchConfig::probCutMinDepth , DepthType(0) , DepthType(30) );
370 : _keys.emplace_back(k_depth, w_spin, "probCutSearchDepthFactor" , &SearchConfig::probCutSearchDepthFactor , DepthType(0) , DepthType(30) );
371 : _keys.emplace_back(k_int , w_spin, "probCutMaxMoves" , &SearchConfig::probCutMaxMoves , 0 , 30 );
372 : _keys.emplace_back(k_score, w_spin, "probCutMargin" , &SearchConfig::probCutMargin , ScoreType(-500) , ScoreType(1500) );
373 : _keys.emplace_back(k_score, w_spin, "probCutMarginSlope" , &SearchConfig::probCutMarginSlope , ScoreType(-500) , ScoreType(1500) );
374 :
375 : _keys.emplace_back(k_score, w_spin, "seeCaptureFactor" , &SearchConfig::seeCaptureFactor , ScoreType(0) , ScoreType(1500) );
376 : _keys.emplace_back(k_score, w_spin, "seeCaptureInit" , &SearchConfig::seeCaptureInit , ScoreType(-500) , ScoreType(500) );
377 : _keys.emplace_back(k_score, w_spin, "seeCapDangerDivisor" , &SearchConfig::seeCapDangerDivisor , ScoreType(1) , ScoreType(32) );
378 : _keys.emplace_back(k_score, w_spin, "seeQuietFactor" , &SearchConfig::seeQuietFactor , ScoreType(0) , ScoreType(1500) );
379 : _keys.emplace_back(k_score, w_spin, "seeQuietInit" , &SearchConfig::seeQuietInit , ScoreType(-500) , ScoreType(500) );
380 : _keys.emplace_back(k_score, w_spin, "seeQuietDangerDivisor" , &SearchConfig::seeQuietDangerDivisor , ScoreType(1) , ScoreType(32) );
381 : _keys.emplace_back(k_score, w_spin, "seeQThreshold" , &SearchConfig::seeQThreshold , ScoreType(-200) , ScoreType(200) );
382 : _keys.emplace_back(k_score, w_spin, "betaMarginDynamicHistory" , &SearchConfig::betaMarginDynamicHistory , ScoreType(0) , ScoreType(1500) );
383 :
384 : _keys.emplace_back(k_depth, w_spin, "lmrMinDepth" , &SearchConfig::lmrMinDepth , DepthType(0) , DepthType(30) );
385 : _keys.emplace_back(k_depth, w_spin, "singularExtensionDepth" , &SearchConfig::singularExtensionDepth , DepthType(0) , DepthType(30) );
386 : _keys.emplace_back(k_depth, w_spin, "singularExtensionDepthMinus" , &SearchConfig::singularExtensionDepthMinus , DepthType(1) , DepthType(30) );
387 :
388 : _keys.emplace_back(k_int , w_spin, "lmrCapHistoryFactor" , &SearchConfig::lmrCapHistoryFactor , 1 , 64 );
389 :
390 : _keys.emplace_back(k_score, w_spin, "dangerLimitPruning" , &SearchConfig::dangerLimitPruning , ScoreType(0) , ScoreType(65) );
391 : _keys.emplace_back(k_score, w_spin, "dangerLimitForwardPruning" , &SearchConfig::dangerLimitForwardPruning , ScoreType(0) , ScoreType(65) );
392 : _keys.emplace_back(k_score, w_spin, "dangerLimitReduction" , &SearchConfig::dangerLimitReduction , ScoreType(0) , ScoreType(65) );
393 : _keys.emplace_back(k_score, w_spin, "dangerDivisor" , &SearchConfig::dangerDivisor , ScoreType(-50) , ScoreType(256) );
394 :
395 : _keys.emplace_back(k_score, w_spin, "failLowRootMargin" , &SearchConfig::failLowRootMargin , ScoreType(-200) , ScoreType(1500) );
396 : _keys.emplace_back(k_score, w_spin, "CMHMargin" , &SearchConfig::CMHMargin , ScoreType(-2024), ScoreType(2048) );
397 : _keys.emplace_back(k_score, w_spin, "deltaBadMargin" , &SearchConfig::deltaBadMargin , ScoreType(0) , ScoreType(500) );
398 : _keys.emplace_back(k_score, w_spin, "deltaBadSEEThreshold" , &SearchConfig::deltaBadSEEThreshold , ScoreType(-200) , ScoreType(200) );
399 : _keys.emplace_back(k_score, w_spin, "deltaGoodMargin" , &SearchConfig::deltaGoodMargin , ScoreType(0) , ScoreType(500) );
400 : _keys.emplace_back(k_score, w_spin, "deltaGoodSEEThreshold" , &SearchConfig::deltaGoodSEEThreshold , ScoreType(0) , ScoreType(1000) );
401 :
402 : _keys.emplace_back(k_depth, w_spin, "iirMinDepth" , &SearchConfig::iirMinDepth , DepthType(1) , DepthType(32) );
403 : _keys.emplace_back(k_depth, w_spin, "iirReduction" , &SearchConfig::iirReduction , DepthType(0) , DepthType(5) );
404 :
405 : _keys.emplace_back(k_depth, w_spin, "ttAlphaCutDepth" , &SearchConfig::ttAlphaCutDepth , DepthType(1) , DepthType(8) );
406 : _keys.emplace_back(k_score, w_spin, "ttAlphaCutMargin" , &SearchConfig::ttAlphaCutMargin , ScoreType(0) , ScoreType(1000) );
407 : _keys.emplace_back(k_depth, w_spin, "ttBetaCutDepth" , &SearchConfig::ttBetaCutDepth , DepthType(1) , DepthType(8) );
408 : _keys.emplace_back(k_score, w_spin, "ttBetaCutMargin" , &SearchConfig::ttBetaCutMargin , ScoreType(0) , ScoreType(1000) );
409 :
410 : _keys.emplace_back(k_score, w_spin, "lazySortThreshold" , &SearchConfig::lazySortThreshold , ScoreType(-2048), ScoreType(2048) );
411 : _keys.emplace_back(k_score, w_spin, "lazySortThresholdQS" , &SearchConfig::lazySortThresholdQS , ScoreType(-2048), ScoreType(2048) );
412 :
413 : _keys.emplace_back(k_int , w_spin, "distributedTTBufSize" , &SearchConfig::distributedTTBufSize , 4 , 8192 );
414 :
415 : _keys.emplace_back(k_int , w_spin, "capPSTScoreDivisor" , &SearchConfig::capPSTScoreDivisor , 1 , 16 );
416 : _keys.emplace_back(k_int , w_spin, "capMMLVAMultiplicator" , &SearchConfig::capMMLVAMultiplicator , 1 , 16 );
417 : _keys.emplace_back(k_int , w_spin, "capHistoryDivisor" , &SearchConfig::capHistoryDivisor , 1 , 16 );
418 :
419 : _keys.emplace_back(k_int , w_spin, "quietHistoryDivisor1" , &SearchConfig::quietHistoryDivisor1 , 1 , 16 );
420 : _keys.emplace_back(k_int , w_spin, "quietHistoryDivisor2" , &SearchConfig::quietHistoryDivisor2 , 1 , 16 );
421 : _keys.emplace_back(k_int , w_spin, "quietHistoryDivisor3" , &SearchConfig::quietHistoryDivisor3 , 1 , 16 );
422 :
423 :
424 :
425 : ///@todo more ...
426 : #endif
427 :
428 : #ifdef WITH_PIECE_TUNING
429 : _keys.emplace_back(k_score, w_spin, "PawnValueMG" , &Values [P_wp+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
430 : _keys.emplace_back(k_score, w_spin, "PawnValueEG" , &ValuesEG[P_wp+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
431 : _keys.emplace_back(k_score, w_spin, "PawnValueGP" , &ValuesGP[P_wp+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
432 : _keys.emplace_back(k_score, w_spin, "PawnValueSEE" , &ValuesSEE[P_wp+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
433 :
434 : _keys.emplace_back(k_score, w_spin, "KnightValueMG" , &Values [P_wn+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
435 : _keys.emplace_back(k_score, w_spin, "KnightValueEG" , &ValuesEG[P_wn+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
436 : _keys.emplace_back(k_score, w_spin, "KnightValueGP" , &ValuesGP[P_wn+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
437 : _keys.emplace_back(k_score, w_spin, "KnightValueSEE", &ValuesSEE[P_wn+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
438 :
439 : _keys.emplace_back(k_score, w_spin, "BishopValueMG" , &Values [P_wb+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
440 : _keys.emplace_back(k_score, w_spin, "BishopValueEG" , &ValuesEG[P_wb+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
441 : _keys.emplace_back(k_score, w_spin, "BishopValueGP" , &ValuesGP[P_wb+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
442 : _keys.emplace_back(k_score, w_spin, "BishopValueSEE", &ValuesSEE[P_wb+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
443 :
444 : _keys.emplace_back(k_score, w_spin, "RookValueMG" , &Values [P_wr+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
445 : _keys.emplace_back(k_score, w_spin, "RookValueEG" , &ValuesEG[P_wr+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
446 : _keys.emplace_back(k_score, w_spin, "RookValueGP" , &ValuesGP[P_wr+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
447 : _keys.emplace_back(k_score, w_spin, "RookValueSEE" , &ValuesSEE[P_wr+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
448 :
449 : _keys.emplace_back(k_score, w_spin, "QueenValueMG" , &Values [P_wq+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
450 : _keys.emplace_back(k_score, w_spin, "QueenValueEG" , &ValuesEG[P_wq+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
451 : _keys.emplace_back(k_score, w_spin, "QueenValueGP" , &ValuesGP[P_wq+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
452 : _keys.emplace_back(k_score, w_spin, "QueenValueSEE" , &ValuesSEE[P_wq+PieceShift] , ScoreType(0) , ScoreType(2000) , [](){SymetrizeValue(); MaterialHash::InitMaterialScore(false);}));
453 : #endif
454 :
455 44 : }
456 :
457 : // load command line args in memory
458 22 : void readOptions(int argc, char** argv) {
459 114 : for (int i = 1; i < argc; ++i) args.push_back(argv[i]);
460 22 : }
461 :
462 : // get option from command line
463 22 : void initOptions(int argc, char** argv) {
464 : #define GETOPT(name, type) Options::getOption<type>(DynamicConfig::name, #name);
465 : #define GETOPTVAR(name, variable, type) Options::getOption<type>(DynamicConfig::variable, #name);
466 :
467 22 : registerCOMOptions();
468 22 : readOptions(argc, argv);
469 :
470 22 : GETOPT(minOutputLevel, int) // first to be read !
471 22 : GETOPT(debugMode, bool)
472 22 : GETOPT(disableTT, bool)
473 22 : GETOPT(debugFile, std::string)
474 22 : GETOPT(ttSizeMb, unsigned int)
475 22 : GETOPT(ttPawnSizeMb, unsigned int)
476 22 : GETOPT(contempt, ScoreType)
477 22 : GETOPT(FRC, bool)
478 22 : GETOPT(DFRC, bool)
479 22 : GETOPT(threads, unsigned int)
480 22 : GETOPT(mateFinder, bool)
481 22 : GETOPT(fullXboardOutput, bool)
482 22 : GETOPT(level, unsigned int)
483 22 : GETOPT(multiPV, unsigned int)
484 22 : GETOPT(randomOpen, unsigned int)
485 22 : GETOPT(limitStrength, bool)
486 22 : GETOPT(nodesBasedLevel, bool)
487 22 : GETOPT(strength, int)
488 22 : GETOPT(moveOverHead, unsigned int)
489 22 : GETOPT(armageddon, bool)
490 22 : GETOPT(antichess, bool)
491 22 : GETOPT(withWDL, bool)
492 22 : GETOPT(bongCloud, bool)
493 22 : GETOPT(anarchy, bool)
494 22 : Options::getOption<uint64_t>(TimeMan::maxNodes, "maxNodes");
495 :
496 : #ifdef WITH_SYZYGY
497 22 : GETOPT(syzygyPath, std::string)
498 : #endif
499 :
500 : #ifdef WITH_NNUE
501 22 : GETOPT(NNUEFile, std::string)
502 22 : GETOPT(forceNNUE, bool)
503 22 : GETOPT(NNUEScaling, int)
504 22 : GETOPT(NNUEThreshold, int)
505 22 : GETOPT(NNUEThreshold2, int)
506 : #endif
507 :
508 : #ifdef WITH_GENFILE
509 22 : GETOPT(genFen, bool)
510 22 : GETOPT(pgnOut, bool)
511 22 : GETOPT(genFenDepth, unsigned int)
512 22 : GETOPT(genFenDepthEG, unsigned int)
513 22 : GETOPT(randomPly, unsigned int)
514 : #endif
515 :
516 22 : if (DynamicConfig::DFRC) DynamicConfig::FRC = true;
517 22 : }
518 :
519 : } // namespace Options
|