LCOV - code coverage report
Current view: top level - Source - option.cpp (source / functions) Coverage Total Hit
Test: coverage Lines: 95.1 % 204 194
Test Date: 2026-03-02 16:42:41 Functions: 100.0 % 19 19

            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
        

Generated by: LCOV version 2.0-1