Use material counting for Janggi adjudication
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 23 May 2020 11:58:57 +0000 (13:58 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 23 May 2020 11:58:57 +0000 (13:58 +0200)
When material counting is enabled, use it also for repetition
and 50-move rule adjudication.

Closes #108, #117, and #131.

src/position.cpp
src/position.h
src/variant.cpp

index 80307e7..7d25a94 100644 (file)
@@ -1818,7 +1818,7 @@ bool Position::is_optional_game_end(Value& result, int ply, int countStarted) co
   // n-move rule
   if (n_move_rule() && st->rule50 > (2 * n_move_rule() - 1) && (!checkers() || MoveList<LEGAL>(*this).size()))
   {
-      result = VALUE_DRAW;
+      result = var->materialCounting ? convert_mate_value(material_counting_result(), ply) : VALUE_DRAW;
       return true;
   }
 
@@ -1848,6 +1848,8 @@ bool Position::is_optional_game_end(Value& result, int ply, int countStarted) co
                                               : var->perpetualCheckIllegal && perpetualUs ? -VALUE_MATE
                                               : var->nFoldValueAbsolute && sideToMove == BLACK ? -var->nFoldValue
                                               : var->nFoldValue, ply);
+                  if (result == VALUE_DRAW && var->materialCounting)
+                      result = convert_mate_value(material_counting_result(), ply);
                   return true;
               }
 
@@ -1949,9 +1951,7 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
   // Check for bikjang rule (Janggi) and double passing
   if (st->pliesFromNull > 0 && ((st->bikjang && st->previous->bikjang) || (st->pass && st->previous->pass)))
   {
-      result = var->materialCounting ? convert_mate_value(sideToMove == WHITE ?  material_counting_result()
-                                                                              : -material_counting_result(), ply)
-                                     : VALUE_DRAW;
+      result = var->materialCounting ? convert_mate_value(material_counting_result(), ply) : VALUE_DRAW;
       return true;
   }
   // Tsume mode: Assume that side with king wins when not in check
@@ -1992,7 +1992,7 @@ bool Position::has_game_cycle(int ply) const {
 
   int end = captures_to_hand() ? st->pliesFromNull : std::min(st->rule50, st->pliesFromNull);
 
-  if (end < 3 || var->nFoldValue != VALUE_DRAW || var->perpetualCheckIllegal)
+  if (end < 3 || var->nFoldValue != VALUE_DRAW || var->perpetualCheckIllegal || var->materialCounting)
     return false;
 
   Key originalKey = st->key;
index b563843..47302ef 100644 (file)
@@ -1085,6 +1085,7 @@ inline bool Position::bikjang() const {
 inline Value Position::material_counting_result() const {
   auto weigth_count = [this](PieceType pt, int v){ return v * (count(WHITE, pt) - count(BLACK, pt)); };
   int materialCount;
+  Value result;
   switch (var->materialCounting)
   {
   case JANGGI_MATERIAL:
@@ -1095,15 +1096,18 @@ inline Value Position::material_counting_result() const {
                      + weigth_count(WAZIR, 3)
                      + weigth_count(SOLDIER, 2)
                      - 1;
-      return materialCount > 0 ? VALUE_MATE : -VALUE_MATE;
+      result = materialCount > 0 ? VALUE_MATE : -VALUE_MATE;
+      break;
   case UNWEIGHTED_MATERIAL:
-      return  count(WHITE, ALL_PIECES) > count(BLACK, ALL_PIECES) ?  VALUE_MATE
-            : count(WHITE, ALL_PIECES) < count(BLACK, ALL_PIECES) ? -VALUE_MATE
-                                                                  :  VALUE_DRAW;
+      result =  count(WHITE, ALL_PIECES) > count(BLACK, ALL_PIECES) ?  VALUE_MATE
+              : count(WHITE, ALL_PIECES) < count(BLACK, ALL_PIECES) ? -VALUE_MATE
+                                                                    :  VALUE_DRAW;
+      break;
   default:
       assert(false);
-      return VALUE_DRAW;
+      result = VALUE_DRAW;
   }
+  return sideToMove == WHITE ? result : -result;
 }
 
 inline void Position::add_to_hand(Piece pc) {
index 3ebe1b5..a72be75 100644 (file)
@@ -887,7 +887,7 @@ namespace {
         v->diagonalLines = make_bitboard(SQ_D1, SQ_F1, SQ_E2, SQ_D3, SQ_F3,
                                          SQ_D8, SQ_F8, SQ_E9, SQ_D10, SQ_F10);
         v->kingPass = true;
-        v->nFoldValue = -VALUE_MATE;
+        v->nFoldValue = VALUE_DRAW;
         v->perpetualCheckIllegal = true;
         return v;
     }