Simplify manual counting
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 2 May 2020 19:49:48 +0000 (21:49 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 2 May 2020 19:49:48 +0000 (21:49 +0200)
No functional change.

src/position.cpp
src/position.h
src/pyffish.cpp

index cb8f442..05e89b1 100644 (file)
@@ -581,7 +581,7 @@ Position& Position::set(const string& code, Color c, StateInfo* si) {
 /// Position::fen() returns a FEN representation of the position. In case of
 /// Chess960 the Shredder-FEN notation is used. This is mainly a debugging function.
 
-const string Position::fen(bool sfen, bool showPromoted, unsigned int countStarted, std::string holdings) const {
+const string Position::fen(bool sfen, bool showPromoted, int countStarted, std::string holdings) const {
 
   int emptyCnt;
   std::ostringstream ss;
@@ -686,10 +686,7 @@ const string Position::fen(bool sfen, bool showPromoted, unsigned int countStart
 
   // Counting ply or 50-move rule counter
   if (st->countingLimit)
-      if (countStarted == 0)
-          ss << st->countingPly;
-      else
-          ss << std::min(st->countingPly, countStarted > (unsigned int)gamePly ? 0 : (int)(1 + gamePly - countStarted));
+      ss << counting_ply(countStarted);
   else
       ss << st->rule50;
 
@@ -1809,7 +1806,7 @@ bool Position::see_ge(Move m, Value threshold) const {
 /// Position::is_optinal_game_end() tests whether the position may end the game by
 /// 50-move rule, by repetition, or a variant rule that allows a player to claim a game result.
 
-bool Position::is_optional_game_end(Value& result, int ply, unsigned int countStarted) const {
+bool Position::is_optional_game_end(Value& result, int ply, int countStarted) const {
 
   // n-move rule
   if (n_move_rule() && st->rule50 > (2 * n_move_rule() - 1) && (!checkers() || MoveList<LEGAL>(*this).size()))
@@ -1856,7 +1853,7 @@ bool Position::is_optional_game_end(Value& result, int ply, unsigned int countSt
   // counting rules
   if (   counting_rule()
       && st->countingLimit
-      && std::min(st->countingPly, countStarted > (unsigned int)gamePly ? 0 : countStarted == 0 ? st->countingPly : (int)(1 + gamePly - countStarted)) > st->countingLimit
+      && counting_ply(countStarted) > st->countingLimit
       && (!checkers() || MoveList<LEGAL>(*this).size()))
   {
       result = VALUE_DRAW;
index 813f054..28d4aaa 100644 (file)
@@ -91,7 +91,7 @@ public:
   // FEN string input/output
   Position& set(const Variant* v, const std::string& fenStr, bool isChess960, StateInfo* si, Thread* th, bool sfen = false);
   Position& set(const std::string& code, Color c, StateInfo* si);
-  const std::string fen(bool sfen = false, bool showPromoted = false, unsigned int countStarted = 0, std::string holdings = "-") const;
+  const std::string fen(bool sfen = false, bool showPromoted = false, int countStarted = 0, std::string holdings = "-") const;
 
   // Variant rule properties
   const Variant* variant() const;
@@ -254,11 +254,12 @@ public:
   Thread* this_thread() const;
   bool is_immediate_game_end() const;
   bool is_game_end(Value& result, int ply = 0) const;
-  bool is_optional_game_end(Value& result, int ply = 0, unsigned int countStarted = 0) const;
+  bool is_optional_game_end(Value& result, int ply = 0, int countStarted = 0) const;
   bool is_immediate_game_end(Value& result, int ply = 0) const;
   bool has_game_cycle(int ply) const;
   bool has_repeated() const;
   int counting_limit() const;
+  int counting_ply(int countStarted) const;
   int rule50_count() const;
   Score psq_score() const;
   Value non_pawn_material(Color c) const;
@@ -969,6 +970,10 @@ inline int Position::game_ply() const {
   return gamePly;
 }
 
+inline int Position::counting_ply(int countStarted) const {
+  return countStarted == 0 ? st->countingPly : std::min(st->countingPly, std::max(1 + gamePly - countStarted, 0));
+}
+
 inline int Position::rule50_count() const {
   return st->rule50;
 }
index 609da4d..5afd653 100644 (file)
@@ -483,10 +483,11 @@ extern "C" PyObject* pyffish_getFEN(PyObject* self, PyObject *args) {
     if (!PyArg_ParseTuple(args, "ssO!|pppi", &variant, &fen, &PyList_Type, &moveList, &chess960, &sfen, &showPromoted, &countStarted)) {
         return NULL;
     }
+    countStarted = std::min<unsigned int>(countStarted, INT_MAX); // pseudo-unsigned
 
     StateListPtr states(new std::deque<StateInfo>(1));
     buildPosition(pos, states, variant, fen, moveList, chess960);
-    return Py_BuildValue("s", pos.fen(sfen, showPromoted, (unsigned int)countStarted).c_str());
+    return Py_BuildValue("s", pos.fen(sfen, showPromoted, countStarted).c_str());
 }
 
 // INPUT variant, fen, move list
@@ -556,10 +557,11 @@ extern "C" PyObject* pyffish_isOptionalGameEnd(PyObject* self, PyObject *args) {
     if (!PyArg_ParseTuple(args, "ssO!|pi", &variant, &fen, &PyList_Type, &moveList, &chess960, &countStarted)) {
         return NULL;
     }
+    countStarted = std::min<unsigned int>(countStarted, INT_MAX); // pseudo-unsigned
 
     StateListPtr states(new std::deque<StateInfo>(1));
     buildPosition(pos, states, variant, fen, moveList, chess960);
-    gameEnd = pos.is_optional_game_end(result, 0, (unsigned int)countStarted);
+    gameEnd = pos.is_optional_game_end(result, 0, countStarted);
     return Py_BuildValue("(Oi)", gameEnd ? Py_True : Py_False, result);
 }