Add user-defined conversions to UCIOption
authorMarco Costalba <mcostalba@gmail.com>
Wed, 28 Dec 2011 17:27:18 +0000 (18:27 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Wed, 28 Dec 2011 18:42:50 +0000 (19:42 +0100)
Greatly improves the usage. User defined conversions
are a novelity for SF, another amazing C++ facility
at work !

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/evaluate.cpp
src/search.cpp
src/thread.cpp
src/timeman.cpp
src/uci.cpp
src/ucioption.h

index ab10597b6fe69c70241bdada24fdd4596404498c..5e278242b742ddd2457d0a7f2312b63e47f5b081 100644 (file)
@@ -412,7 +412,7 @@ void read_evaluation_uci_options(Color us) {
 
   // If running in analysis mode, make sure we use symmetrical king safety. We do this
   // by replacing both Weights[kingDangerUs] and Weights[kingDangerThem] by their average.
-  if (Options["UCI_AnalyseMode"].value<bool>())
+  if (Options["UCI_AnalyseMode"])
       Weights[kingDangerUs] = Weights[kingDangerThem] = (Weights[kingDangerUs] + Weights[kingDangerThem]) / 2;
 
   init_safety();
@@ -1101,8 +1101,8 @@ namespace {
   Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight) {
 
     // Scale option value from 100 to 256
-    int mg = Options[mgOpt].value<int>() * 256 / 100;
-    int eg = Options[egOpt].value<int>() * 256 / 100;
+    int mg = Options[mgOpt] * 256 / 100;
+    int eg = Options[egOpt] * 256 / 100;
 
     return apply_weight(make_score(mg, eg), internalWeight);
   }
index 636ebd8ef6654b4a31f325b752ca5e1d0dceab53..c7bc8d1752f8c15e18ecf43baf1d3e0ae8f329d5 100644 (file)
@@ -296,12 +296,12 @@ void Search::think() {
           || count(SearchMoves.begin(), SearchMoves.end(), ml.move()))
           RootMoves.push_back(RootMove(ml.move()));
 
-  if (Options["OwnBook"].value<bool>())
+  if (Options["OwnBook"])
   {
-      if (Options["Book File"].value<string>() != book.name())
-          book.open(Options["Book File"].value<string>());
+      if (book.name() != (string)Options["Book File"])
+          book.open(Options["Book File"]);
 
-      Move bookMove = book.probe(pos, Options["Best Book Move"].value<bool>());
+      Move bookMove = book.probe(pos, Options["Best Book Move"]);
 
       if (   bookMove != MOVE_NONE
           && count(RootMoves.begin(), RootMoves.end(), bookMove))
@@ -315,24 +315,24 @@ void Search::think() {
   read_evaluation_uci_options(pos.side_to_move());
   Threads.read_uci_options();
 
-  TT.set_size(Options["Hash"].value<int>());
-  if (Options["Clear Hash"].value<bool>())
+  TT.set_size(Options["Hash"]);
+  if (Options["Clear Hash"])
   {
       Options["Clear Hash"] = false;
       TT.clear();
   }
 
-  UCIMultiPV = Options["MultiPV"].value<size_t>();
-  SkillLevel = Options["Skill Level"].value<int>();
+  UCIMultiPV = Options["MultiPV"];
+  SkillLevel = Options["Skill Level"];
 
   // Do we have to play with skill handicap? In this case enable MultiPV that
   // we will use behind the scenes to retrieve a set of possible moves.
   SkillLevelEnabled = (SkillLevel < 20);
   MultiPV = (SkillLevelEnabled ? std::max(UCIMultiPV, (size_t)4) : UCIMultiPV);
 
-  if (Options["Use Search Log"].value<bool>())
+  if (Options["Use Search Log"])
   {
-      Log log(Options["Search Log Filename"].value<string>());
+      Log log(Options["Search Log Filename"]);
       log << "\nSearching: "  << pos.to_fen()
           << "\ninfinite: "   << Limits.infinite
           << " ponder: "      << Limits.ponder
@@ -362,11 +362,11 @@ void Search::think() {
   Threads.set_timer(0);
   Threads.set_size(1);
 
-  if (Options["Use Search Log"].value<bool>())
+  if (Options["Use Search Log"])
   {
       int e = elapsed_time();
 
-      Log log(Options["Search Log Filename"].value<string>());
+      Log log(Options["Search Log Filename"]);
       log << "Nodes: "          << pos.nodes_searched()
           << "\nNodes/second: " << (e > 0 ? pos.nodes_searched() * 1000 / e : 0)
           << "\nBest move: "    << move_to_san(pos, RootMoves[0].pv[0]);
@@ -512,7 +512,7 @@ namespace {
         if (SkillLevelEnabled && depth == 1 + SkillLevel)
             skillBest = do_skill_level();
 
-        if (Options["Use Search Log"].value<bool>())
+        if (Options["Use Search Log"])
              pv_info_to_log(pos, depth, bestValue, elapsed_time(), &RootMoves[0].pv[0]);
 
         // Filter out startup noise when monitoring best move stability
@@ -1758,7 +1758,7 @@ split_point_start: // At split points actual search starts from here
     while (m != pv)
         pos.undo_move(*--m);
 
-    Log l(Options["Search Log Filename"].value<string>());
+    Log l(Options["Search Log Filename"]);
     l << s.str() << endl;
   }
 
index 18e35fb062ca9e11919cd6bab60148d2c13a3e7a..5c0ac84bae6f44c2de0f33f319ef568a5104f539 100644 (file)
@@ -112,11 +112,11 @@ bool Thread::is_available_to(int master) const {
 
 void ThreadsManager::read_uci_options() {
 
-  maxThreadsPerSplitPoint = Options["Max Threads per Split Point"].value<int>();
-  minimumSplitDepth       = Options["Min Split Depth"].value<int>() * ONE_PLY;
-  useSleepingThreads      = Options["Use Sleeping Threads"].value<bool>();
+  maxThreadsPerSplitPoint = Options["Max Threads per Split Point"];
+  minimumSplitDepth       = Options["Min Split Depth"] * ONE_PLY;
+  useSleepingThreads      = Options["Use Sleeping Threads"];
 
-  set_size(Options["Threads"].value<int>());
+  set_size(Options["Threads"]);
 }
 
 
index 8282f2c629a384f1cbfd9fe21f937ad05605fc16..aece49d5772d6892aea8b3a64d506c87a2c572cb 100644 (file)
@@ -104,10 +104,10 @@ void TimeManager::init(const Search::LimitsType& limits, int currentPly)
   int hypMTG, hypMyTime, t1, t2;
 
   // Read uci parameters
-  int emergencyMoveHorizon = Options["Emergency Move Horizon"].value<int>();
-  int emergencyBaseTime    = Options["Emergency Base Time"].value<int>();
-  int emergencyMoveTime    = Options["Emergency Move Time"].value<int>();
-  int minThinkingTime      = Options["Minimum Thinking Time"].value<int>();
+  int emergencyMoveHorizon = Options["Emergency Move Horizon"];
+  int emergencyBaseTime    = Options["Emergency Base Time"];
+  int emergencyMoveTime    = Options["Emergency Move Time"];
+  int minThinkingTime      = Options["Minimum Thinking Time"];
 
   // Initialize to maximum values but unstablePVExtraTime that is reset
   unstablePVExtraTime = 0;
@@ -132,7 +132,7 @@ void TimeManager::init(const Search::LimitsType& limits, int currentPly)
       maximumSearchTime = std::min(maximumSearchTime, t2);
   }
 
-  if (Options["Ponder"].value<bool>())
+  if (Options["Ponder"])
       optimumSearchTime += optimumSearchTime / 4;
 
   // Make sure that maxSearchTime is not over absoluteMaxSearchTime
index c4d01fa10dbda9b6af3f531acd04af52c2865438..02a3c30c79f5ea338d611f0b399ef796b57b9b53 100644 (file)
@@ -157,7 +157,7 @@ namespace {
     else
         return;
 
-    pos.from_fen(fen, Options["UCI_Chess960"].value<bool>());
+    pos.from_fen(fen, Options["UCI_Chess960"]);
 
     // Parse move list (if any)
     while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)
@@ -188,10 +188,14 @@ namespace {
     while (is >> token)
         value += string(" ", !value.empty()) + token;
 
-    if (Options.count(name))
-        Options[name] = (value.empty() ? "true" : value); // UCI buttons don't have "value"
-    else
+    if (!Options.count(name))
         cout << "No such option: " << name << endl;
+
+    else if (value.empty()) // UCI buttons don't have a value
+        Options[name] = true;
+
+    else
+        Options[name] = value;
   }
 
 
index b8622e51d124baee07a75040ffe82d258476e4bc..f0787132a7f68104d3804987ef638accd821788e 100644 (file)
@@ -35,10 +35,19 @@ public:
   UCIOption(bool v, std::string type = "check");
   UCIOption(int v, int min, int max);
 
-  template<typename T> T value() const;
   void operator=(const std::string& v);
   void operator=(bool v) { *this = std::string(v ? "true" : "false"); }
 
+  operator int() const {
+    assert(type == "check" || type == "button" || type == "spin");
+    return (type == "spin" ? atoi(currentValue.c_str()) : currentValue == "true");
+  }
+
+  operator std::string() const {
+    assert(type == "string");
+    return currentValue;
+  }
+
 private:
   friend std::ostream& operator<<(std::ostream&, const OptionsMap&);
 
@@ -48,29 +57,6 @@ private:
 };
 
 
-/// UCIOption::value() definition and specializations
-template<typename T>
-T UCIOption::value() const {
-
-  assert(type == "spin");
-  return T(atoi(currentValue.c_str()));
-}
-
-template<>
-inline std::string UCIOption::value<std::string>() const {
-
-  assert(type == "string");
-  return currentValue;
-}
-
-template<>
-inline bool UCIOption::value<bool>() const {
-
-  assert(type == "check" || type == "button");
-  return currentValue == "true";
-}
-
-
 /// Custom comparator because UCI options should be case insensitive
 struct CaseInsensitiveLess {
   bool operator() (const std::string&, const std::string&) const;