Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.     Texel - A UCI chess engine.
  3.     Copyright (C) 2012-2014  Peter Ă–sterlund, peterosterlund2@gmail.com
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. /*
  20.  * parameters.hpp
  21.  *
  22.  *  Created on: Feb 25, 2012
  23.  *      Author: petero
  24.  */
  25.  
  26. #ifndef PARAMETERS_HPP_
  27. #define PARAMETERS_HPP_
  28.  
  29. #include "util/util.hpp"
  30. #include "piece.hpp"
  31. #include "position.hpp"
  32.  
  33. #include <memory>
  34. #include <functional>
  35. #include <map>
  36. #include <string>
  37. #include <cassert>
  38.  
  39.  
  40. /** Handles all UCI parameters. */
  41. class Parameters {
  42. public:
  43.     enum Type {
  44.         CHECK,
  45.         SPIN,
  46.         COMBO,
  47.         BUTTON,
  48.         STRING
  49.     };
  50.  
  51.     /** Observer pattern. */
  52.     class Listener {
  53.         using Func = std::function<void()>;
  54.     public:
  55.         int addListener(Func f, bool callNow = true);
  56.  
  57.         void removeListener(int id);
  58.  
  59.     protected:
  60.         void notify();
  61.  
  62.     private:
  63.         int nextId = 0;
  64.         std::map<int, Func> listeners;
  65.     };
  66.  
  67.     /** Base class for UCI parameters. */
  68.     struct ParamBase : public Listener {
  69.         std::string name;
  70.         Type type;
  71.  
  72.         ParamBase(const std::string& n, Type t) : name(n), type(t) { }
  73.         ParamBase(const ParamBase& other) = delete;
  74.         ParamBase& operator=(const ParamBase& other) = delete;
  75.  
  76.         virtual bool getBoolPar() const { assert(false); return false; }
  77.         virtual int getIntPar() const { assert(false); return 0; }
  78.         virtual std::string getStringPar() const { assert(false); return ""; }
  79.         virtual void set(const std::string& value) { assert(false); }
  80.     };
  81.  
  82.     /** A boolean parameter. */
  83.     struct CheckParam : public ParamBase {
  84.         bool value;
  85.         bool defaultValue;
  86.  
  87.         CheckParam(const std::string& name, bool def)
  88.             : ParamBase(name, CHECK) {
  89.             this->value = def;
  90.             this->defaultValue = def;
  91.         }
  92.  
  93.         bool getBoolPar() const override { return value; }
  94.  
  95.         void set(const std::string& value) override {
  96.             if (toLowerCase(value) == "true")
  97.                 this->value = true;
  98.             else if (toLowerCase(value) == "false")
  99.                 this->value = false;
  100.             notify();
  101.         }
  102.     };
  103.  
  104.     /** An integer parameter. */
  105.     struct SpinParam : public ParamBase {
  106.         int minValue;
  107.         int maxValue;
  108.         int value;
  109.         int defaultValue;
  110.  
  111.         SpinParam(const std::string& name, int minV, int maxV, int def)
  112.             : ParamBase(name, SPIN) {
  113.             minValue = minV;
  114.             maxValue = maxV;
  115.             value = def;
  116.             defaultValue = def;
  117.         }
  118.  
  119.         int getIntPar() const override { return value; }
  120.  
  121.         void set(const std::string& value) override {
  122.             int val;
  123.             if (str2Num(value, val) && (val >= minValue) && (val <= maxValue)) {
  124.                 this->value = val;
  125.                 notify();
  126.             }
  127.         }
  128.  
  129.         int getDefaultValue() const { return defaultValue; }
  130.         int getMinValue() const { return minValue; }
  131.         int getMaxValue() const { return maxValue; }
  132.     };
  133.  
  134.     /** A multi-choice parameter. */
  135.     struct ComboParam : public ParamBase {
  136.         std::vector<std::string> allowedValues;
  137.         std::string value;
  138.         std::string defaultValue;
  139.  
  140.         ComboParam(const std::string& name, const std::vector<std::string>& allowed,
  141.                    const std::string& def)
  142.             : ParamBase(name, COMBO) {
  143.             this->allowedValues = allowed;
  144.             this->value = def;
  145.             this->defaultValue = def;
  146.         }
  147.  
  148.         std::string getStringPar() const override { return value; }
  149.  
  150.         void set(const std::string& value) override {
  151.             for (size_t i = 0; i < allowedValues.size(); i++) {
  152.                 const std::string& allowed = allowedValues[i];
  153.                 if (toLowerCase(allowed) == toLowerCase(value)) {
  154.                     this->value = allowed;
  155.                     notify();
  156.                     break;
  157.                 }
  158.             }
  159.         }
  160.     };
  161.  
  162.     /** An action parameter. */
  163.     struct ButtonParam : public ParamBase {
  164.         ButtonParam(const std::string& name)
  165.             : ParamBase(name, BUTTON) { }
  166.  
  167.         void set(const std::string& value) override {
  168.             notify();
  169.         }
  170.     };
  171.  
  172.     /** A string parameter. */
  173.     struct StringParam : public ParamBase {
  174.         std::string value;
  175.         std::string defaultValue;
  176.  
  177.         StringParam(const std::string& name, const std::string& def)
  178.             : ParamBase(name, STRING) {
  179.             this->value = def;
  180.             this->defaultValue = def;
  181.         }
  182.  
  183.         std::string getStringPar() const override { return value; }
  184.  
  185.         void set(const std::string& value) override {
  186.             this->value = value;
  187.             notify();
  188.         }
  189.     };
  190.  
  191.     /** Get singleton instance. */
  192.     static Parameters& instance();
  193.  
  194.     /** Retrieve list of all parameters. */
  195.     void getParamNames(std::vector<std::string>& parNames);
  196.  
  197.     std::shared_ptr<ParamBase> getParam(const std::string& name) const;
  198.  
  199.     bool getBoolPar(const std::string& name) const;
  200.     int getIntPar(const std::string& name) const;
  201.     std::string getStringPar(const std::string& name) const;
  202.  
  203.     void set(const std::string& name, const std::string& value);
  204.  
  205.     /** Register a parameter. */
  206.     void addPar(const std::shared_ptr<ParamBase>& p);
  207.  
  208. private:
  209.     Parameters();
  210.  
  211.     std::map<std::string, std::shared_ptr<ParamBase>> params;
  212.     std::vector<std::string> paramNames;
  213. };
  214.  
  215. // ----------------------------------------------------------------------------
  216.  
  217. /** Param can be either a UCI parameter or a compile time constant. */
  218. template <int defaultValue, int minValue, int maxValue, bool uci> class Param;
  219.  
  220. template <int defaultValue, int minValue, int maxValue>
  221. class Param<defaultValue, minValue, maxValue, false> {
  222. public:
  223.     Param() {}
  224.     operator int() const { return defaultValue; }
  225.     void registerParam(const std::string& name, Parameters& pars) {}
  226.     template <typename Func> void addListener(Func f) { f(); }
  227. };
  228.  
  229. template <int defaultValue, int minValue, int maxValue>
  230. class Param<defaultValue, minValue, maxValue, true> {
  231. public:
  232.     Param() : value(0) {}
  233.     operator int() const { return value; }
  234.     void registerParam(const std::string& name, Parameters& pars) {
  235.         par = std::make_shared<Parameters::SpinParam>(name, minValue, maxValue, defaultValue);
  236.         pars.addPar(par);
  237.         par->addListener([this](){ value = par->getIntPar(); });
  238.     }
  239.     template <typename Func> void addListener(Func f) {
  240.         if (par)
  241.             par->addListener(f, false);
  242.         f();
  243.     }
  244. private:
  245.     int value;
  246.     std::shared_ptr<Parameters::SpinParam> par;
  247. };
  248.  
  249. #define DECLARE_PARAM(name, defV, minV, maxV, uci) \
  250.     using name##ParamType = Param<defV,minV,maxV,uci>; \
  251.     extern name##ParamType name;
  252.  
  253. #define DEFINE_PARAM(name) \
  254.     name##ParamType name;
  255.  
  256. #define REGISTER_PARAM(varName, uciName) \
  257.     varName.registerParam(uciName, *this);
  258.  
  259. // ----------------------------------------------------------------------------
  260.  
  261. /** Non-template base class to reduce executable code size. */
  262. class ParamTableBase : public Parameters::Listener {
  263. public:
  264.     int getMinValue() const { return minValue; }
  265.     int getMaxValue() const { return maxValue; }
  266.  
  267. protected:
  268.     ParamTableBase(bool uci0, int minVal0, int maxVal0) :
  269.         uci(uci0), minValue(minVal0), maxValue(maxVal0) {}
  270.     void registerParamsN(const std::string& name, Parameters& pars,
  271.                          int* table, int* parNo, int N);
  272.     void modifiedN(int* table, int* parNo, int N);
  273.  
  274.     const bool uci;
  275.     const int minValue;
  276.     const int maxValue;
  277.  
  278.     std::vector<std::shared_ptr<Parameters::SpinParam>> params;
  279. };
  280.  
  281. template <int N>
  282. class ParamTable : public ParamTableBase {
  283. public:
  284.     ParamTable(int minVal, int maxVal, bool uci,
  285.                std::initializer_list<int> data,
  286.                std::initializer_list<int> parNo);
  287.  
  288.     int operator[](int i) const { return table[i]; }
  289.     const int* getTable() const { return table; }
  290.  
  291.     void registerParams(const std::string& name, Parameters& pars) {
  292.         registerParamsN(name, pars, table, parNo, N);
  293.     }
  294. private:
  295.     int table[N];
  296.     int parNo[N];
  297. };
  298.  
  299. template <int N>
  300. class ParamTableMirrored {
  301. public:
  302.     ParamTableMirrored(ParamTable<N>& orig0) : orig(orig0) {
  303.         orig.addListener([this]() {
  304.             if (N == 64) {
  305.                 for (int sq = 0; sq < N; sq++)
  306.                     table[sq] = orig[Position::mirrorY(sq)];
  307.             } else {
  308.                 for (int i = 0; i < N; i++)
  309.                     table[i] = orig[N-1-i];
  310.             }
  311.         });
  312.     }
  313.     int operator[](int i) const { return table[i]; }
  314.     const int* getTable() const { return table; }
  315. private:
  316.     int table[N];
  317.     ParamTable<N>& orig;
  318. };
  319.  
  320. template <int N>
  321. ParamTable<N>::ParamTable(int minVal0, int maxVal0, bool uci0,
  322.                           std::initializer_list<int> table0,
  323.                           std::initializer_list<int> parNo0)
  324.     : ParamTableBase(uci0, minVal0, maxVal0) {
  325.     assert(table0.size() == N);
  326.     assert(parNo0.size() == N);
  327.     for (int i = 0; i < N; i++) {
  328.         table[i] = table0.begin()[i];
  329.         parNo[i] = parNo0.begin()[i];
  330.     }
  331. }
  332.  
  333. inline bool
  334. Parameters::getBoolPar(const std::string& name) const {
  335.     return getParam(name)->getBoolPar();
  336. }
  337.  
  338. inline int
  339. Parameters::getIntPar(const std::string& name) const {
  340.     return getParam(name)->getIntPar();
  341. }
  342.  
  343. inline std::string
  344. Parameters::getStringPar(const std::string& name) const {
  345.     return getParam(name)->getStringPar();
  346. }
  347.  
  348. inline void
  349. Parameters::set(const std::string& name, const std::string& value) {
  350.     auto it = params.find(toLowerCase(name));
  351.     if (it == params.end())
  352.         return;
  353.     it->second->set(value);
  354. }
  355.  
  356. // ----------------------------------------------------------------------------
  357. // UCI parameters
  358.  
  359. namespace UciParams {
  360.     extern std::shared_ptr<Parameters::SpinParam> hash;
  361.     extern std::shared_ptr<Parameters::CheckParam> ownBook;
  362.     extern std::shared_ptr<Parameters::CheckParam> ponder;
  363.     extern std::shared_ptr<Parameters::CheckParam> analyseMode;
  364.     extern std::shared_ptr<Parameters::SpinParam> strength;
  365.     extern std::shared_ptr<Parameters::SpinParam> threads;
  366.     extern std::shared_ptr<Parameters::SpinParam> multiPV;
  367.  
  368.     extern std::shared_ptr<Parameters::StringParam> gtbPath;
  369.     extern std::shared_ptr<Parameters::SpinParam> gtbCache;
  370.     extern std::shared_ptr<Parameters::StringParam> rtbPath;
  371.     extern std::shared_ptr<Parameters::SpinParam> minProbeDepth;
  372.  
  373.     extern std::shared_ptr<Parameters::ButtonParam> clearHash;
  374. }
  375.  
  376. // ----------------------------------------------------------------------------
  377. // Tuning parameters
  378.  
  379. const bool useUciParam = false;
  380.  
  381. extern int pieceValue[Piece::nPieceTypes];
  382.  
  383. // Evaluation parameters
  384.  
  385. DECLARE_PARAM(pV, 100, 1, 200, useUciParam);
  386. DECLARE_PARAM(nV, 385, 1, 800, useUciParam);
  387. DECLARE_PARAM(bV, 385, 1, 800, useUciParam);
  388. DECLARE_PARAM(rV, 597, 1, 1200, useUciParam);
  389. DECLARE_PARAM(qV, 1215, 1, 2400, useUciParam);
  390. DECLARE_PARAM(kV, 9900, 9900, 9900, false); // Used by SEE algorithm but not included in board material sums
  391.  
  392. DECLARE_PARAM(pawnIslandPenalty,        8, 0, 50, useUciParam);
  393. DECLARE_PARAM(pawnBackwardPenalty,      15, 0, 50, useUciParam);
  394. DECLARE_PARAM(pawnSemiBackwardPenalty1, 6, -50, 50, useUciParam);
  395. DECLARE_PARAM(pawnSemiBackwardPenalty2, 2, -50, 50, useUciParam);
  396. DECLARE_PARAM(pawnRaceBonus,            181, 0, 1000, useUciParam);
  397. DECLARE_PARAM(passedPawnEGFactor,       63, 1, 128, useUciParam);
  398. DECLARE_PARAM(RBehindPP1,               10, -100, 100, useUciParam);
  399. DECLARE_PARAM(RBehindPP2,               24, -100, 100, useUciParam);
  400.  
  401. DECLARE_PARAM(QvsRMBonus1,         30, -100, 100, useUciParam);
  402. DECLARE_PARAM(QvsRMBonus2,         -8, -100, 100, useUciParam);
  403. DECLARE_PARAM(knightVsQueenBonus1, 125, 0, 200, useUciParam);
  404. DECLARE_PARAM(knightVsQueenBonus2, 251, 0, 600, useUciParam);
  405. DECLARE_PARAM(knightVsQueenBonus3, 357, 0, 800, useUciParam);
  406. DECLARE_PARAM(krkpBonus,           135, 0, 400, useUciParam);
  407. DECLARE_PARAM(krpkbBonus,          140, -200, 200, useUciParam);
  408. DECLARE_PARAM(krpkbPenalty,        70,  0, 128, useUciParam);
  409. DECLARE_PARAM(krpknBonus,          259, 0, 400, useUciParam);
  410. DECLARE_PARAM(RvsBPBonus,          -38, -200, 200, useUciParam);
  411.  
  412. DECLARE_PARAM(pawnTradePenalty,    54, 0, 100, useUciParam);
  413. DECLARE_PARAM(pieceTradeBonus,     10, 0, 100, useUciParam);
  414. DECLARE_PARAM(pawnTradeThreshold,  361, 100, 1000, useUciParam);
  415. DECLARE_PARAM(pieceTradeThreshold, 717, 10, 1000, useUciParam);
  416.  
  417. DECLARE_PARAM(threatBonus1,     63, 5, 500, useUciParam);
  418. DECLARE_PARAM(threatBonus2,     1191, 100, 10000, useUciParam);
  419.  
  420. DECLARE_PARAM(rookHalfOpenBonus,     14, 0, 100, useUciParam);
  421. DECLARE_PARAM(rookOpenBonus,         21, 0, 100, useUciParam);
  422. DECLARE_PARAM(rookDouble7thRowBonus, 78, 0, 100, useUciParam);
  423. DECLARE_PARAM(trappedRookPenalty1,   59, 0, 200, useUciParam);
  424. DECLARE_PARAM(trappedRookPenalty2,   31, 0, 200, useUciParam);
  425.  
  426. DECLARE_PARAM(bishopPairPawnPenalty, 5, 0, 10, useUciParam);
  427. DECLARE_PARAM(trappedBishopPenalty,  128, 0, 300, useUciParam);
  428. DECLARE_PARAM(oppoBishopPenalty,     80, 0, 128, useUciParam);
  429.  
  430. DECLARE_PARAM(kingSafetyHalfOpenBCDEFG1, 18, 0, 100, useUciParam);
  431. DECLARE_PARAM(kingSafetyHalfOpenBCDEFG2, -2, -50, 100, useUciParam);
  432. DECLARE_PARAM(kingSafetyHalfOpenAH1,     21, 0, 100, useUciParam);
  433. DECLARE_PARAM(kingSafetyHalfOpenAH2,     14, 0, 100, useUciParam);
  434. DECLARE_PARAM(kingSafetyWeight1,         26, -50, 200, useUciParam);
  435. DECLARE_PARAM(kingSafetyWeight2,         -50, -50, 200, useUciParam);
  436. DECLARE_PARAM(kingSafetyWeight3,         7, -50, 200, useUciParam);
  437. DECLARE_PARAM(kingSafetyWeight4,         1, -50, 200, useUciParam);
  438. DECLARE_PARAM(kingSafetyThreshold,       46, 0, 200, useUciParam);
  439. DECLARE_PARAM(knightKingProtectBonus,    12, -50, 50, useUciParam);
  440. DECLARE_PARAM(bishopKingProtectBonus,    15, -50, 50, useUciParam);
  441. DECLARE_PARAM(pawnStormBonus,            12, 0, 20, useUciParam);
  442.  
  443. DECLARE_PARAM(pawnLoMtrl,          503, 0, 10000, useUciParam);
  444. DECLARE_PARAM(pawnHiMtrl,          3205, 0, 10000, useUciParam);
  445. DECLARE_PARAM(minorLoMtrl,         1114, 0, 10000, useUciParam);
  446. DECLARE_PARAM(minorHiMtrl,         3743, 0, 10000, useUciParam);
  447. DECLARE_PARAM(castleLoMtrl,        712, 0, 10000, useUciParam);
  448. DECLARE_PARAM(castleHiMtrl,        7884, 0, 10000, useUciParam);
  449. DECLARE_PARAM(queenLoMtrl,         4504, 0, 10000, useUciParam);
  450. DECLARE_PARAM(queenHiMtrl,         6544, 0, 10000, useUciParam);
  451. DECLARE_PARAM(passedPawnLoMtrl,    768, 0, 10000, useUciParam);
  452. DECLARE_PARAM(passedPawnHiMtrl,    2511, 0, 10000, useUciParam);
  453. DECLARE_PARAM(kingSafetyLoMtrl,    919, 0, 10000, useUciParam);
  454. DECLARE_PARAM(kingSafetyHiMtrl,    3567, 0, 10000, useUciParam);
  455. DECLARE_PARAM(oppoBishopLoMtrl,    752, 0, 10000, useUciParam);
  456. DECLARE_PARAM(oppoBishopHiMtrl,    3386, 0, 10000, useUciParam);
  457. DECLARE_PARAM(knightOutpostLoMtrl, 157, 0, 10000, useUciParam);
  458. DECLARE_PARAM(knightOutpostHiMtrl, 539, 0, 10000, useUciParam);
  459.  
  460. extern ParamTable<64>         kt1b, kt2b, pt1b, pt2b, nt1b, nt2b, bt1b, bt2b, qt1b, qt2b, rt1b;
  461. extern ParamTableMirrored<64> kt1w, kt2w, pt1w, pt2w, nt1w, nt2w, bt1w, bt2w, qt1w, qt2w, rt1w;
  462.  
  463. extern ParamTable<64> knightOutpostBonus;
  464. extern ParamTable<64> protectedPawnBonus, attackedPawnBonus;
  465. extern ParamTable<4> protectBonus;
  466.  
  467. extern ParamTable<15> rookMobScore;
  468. extern ParamTable<14> bishMobScore;
  469. extern ParamTable<28> knightMobScore;
  470. extern ParamTable<28> queenMobScore;
  471.  
  472. extern ParamTable<36> connectedPPBonus;
  473. extern ParamTable<8> passedPawnBonusX, passedPawnBonusY;
  474. extern ParamTable<10> ppBlockerBonus;
  475. extern ParamTable<8> candidatePassedBonus;
  476.  
  477. extern ParamTable<16> majorPieceRedundancy;
  478. extern ParamTable<5> QvsRRBonus;
  479. extern ParamTable<7> RvsMBonus, RvsMMBonus;
  480. extern ParamTable<4> bishopPairValue;
  481. extern ParamTable<7> rookEGDrawFactor, RvsBPDrawFactor;
  482.  
  483. extern ParamTable<4> castleFactor;
  484. extern ParamTable<9> pawnShelterTable, pawnStormTable;
  485. extern ParamTable<14> kingAttackWeight;
  486. extern ParamTable<5> kingPPSupportK;
  487. extern ParamTable<8> kingPPSupportP;
  488.  
  489. extern ParamTable<8> pawnDoubledPenalty;
  490. extern ParamTable<8> pawnIsolatedPenalty;
  491. extern ParamTable<10> halfMoveFactor;
  492. extern ParamTable<9> stalePawnFactor;
  493.  
  494.  
  495. // Search parameters
  496.  
  497. DECLARE_PARAM(aspirationWindow, 15, 1, 100, useUciParam);
  498. DECLARE_PARAM(rootLMRMoveCount, 2, 0, 100, useUciParam);
  499.  
  500. DECLARE_PARAM(razorMargin1, 86, 1, 500, useUciParam);
  501. DECLARE_PARAM(razorMargin2, 353, 1, 1000, useUciParam);
  502.  
  503. DECLARE_PARAM(reverseFutilityMargin1, 204, 1, 1000, useUciParam);
  504. DECLARE_PARAM(reverseFutilityMargin2, 420, 1, 1000, useUciParam);
  505. DECLARE_PARAM(reverseFutilityMargin3, 533, 1, 2000, useUciParam);
  506. DECLARE_PARAM(reverseFutilityMargin4, 788, 1, 3000, useUciParam);
  507.  
  508. DECLARE_PARAM(futilityMargin1,  61, 1,  500, useUciParam);
  509. DECLARE_PARAM(futilityMargin2, 144, 1,  500, useUciParam);
  510. DECLARE_PARAM(futilityMargin3, 268, 1, 1000, useUciParam);
  511. DECLARE_PARAM(futilityMargin4, 334, 1, 1000, useUciParam);
  512.  
  513. DECLARE_PARAM(lmpMoveCountLimit1,  3, 1, 256, useUciParam);
  514. DECLARE_PARAM(lmpMoveCountLimit2,  6, 1, 256, useUciParam);
  515. DECLARE_PARAM(lmpMoveCountLimit3, 12, 1, 256, useUciParam);
  516. DECLARE_PARAM(lmpMoveCountLimit4, 24, 1, 256, useUciParam);
  517.  
  518. DECLARE_PARAM(lmrMoveCountLimit1,  3, 1, 256, useUciParam);
  519. DECLARE_PARAM(lmrMoveCountLimit2, 12, 1, 256, useUciParam);
  520.  
  521. DECLARE_PARAM(quiesceMaxSortMoves, 8, 0, 256, useUciParam);
  522. DECLARE_PARAM(deltaPruningMargin, 152, 0, 1000, useUciParam);
  523.  
  524.  
  525. // Time management parameters
  526.  
  527. DECLARE_PARAM(timeMaxRemainingMoves, 35, 2, 200, useUciParam);
  528. DECLARE_PARAM(bufferTime, 1000, 1, 10000, useUciParam);
  529. DECLARE_PARAM(minTimeUsage, 85, 1, 100, useUciParam);
  530. DECLARE_PARAM(maxTimeUsage, 400, 100, 1000, useUciParam);
  531. DECLARE_PARAM(timePonderHitRate, 35, 1, 100, useUciParam);
  532.  
  533.  
  534. #endif /* PARAMETERS_HPP_ */
  535.