flagPieceSafe, Squatter (#719)
authorRainRat <rainrat78@yahoo.ca>
Tue, 26 Sep 2023 09:44:24 +0000 (02:44 -0700)
committerGitHub <noreply@github.com>
Tue, 26 Sep 2023 09:44:24 +0000 (11:44 +0200)
src/parser.cpp
src/position.h
src/variant.h
src/variants.ini

index 3d822eb..48b8cc9 100644 (file)
@@ -496,6 +496,7 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
     parse_attribute("flagPieceCount", v->flagPieceCount);
     parse_attribute("flagPieceBlockedWin", v->flagPieceBlockedWin);
     parse_attribute("flagMove", v->flagMove);
+    parse_attribute("flagPieceSafe", v->flagPieceSafe);
     parse_attribute("checkCounting", v->checkCounting);
     parse_attribute("connectN", v->connectN);
     parse_attribute("connectHorizontal", v->connectHorizontal);
@@ -598,6 +599,8 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
             if (v->mutuallyImmuneTypes)
                 std::cerr << "Can not use kings or pseudo-royal with mutuallyImmuneTypes." << std::endl;
         }
+        if (v->flagPieceSafe && v->blastOnCapture)
+            std::cerr << "Can not use flagPieceSafe with blastOnCapture (flagPieceSafe uses simple assessment that does not see blast)." << std::endl;
     }
     return v;
 }
index 2311776..7b9b4cd 100644 (file)
@@ -962,9 +962,40 @@ inline bool Position::flag_move() const {
 
 inline bool Position::flag_reached(Color c) const {
   assert(var != nullptr);
-  return   (flag_region(c) & pieces(c, flag_piece(c)))
+  bool simpleResult = 
+        (flag_region(c) & pieces(c, flag_piece(c)))
         && (   popcount(flag_region(c) & pieces(c, flag_piece(c))) >= var->flagPieceCount
             || (var->flagPieceBlockedWin && !(flag_region(c) & ~pieces())));
+      
+  if (simpleResult&&var->flagPieceSafe)
+  {
+      Bitboard piecesInFlagZone = flag_region(c) & pieces(c, flag_piece(c));
+      int potentialPieces = (popcount(piecesInFlagZone));
+      /*
+      There isn't a variant that uses it, but in the hypothetical game where the rules say I need 3
+      pieces in the flag zone and they need to be safe: If I have 3 pieces there, but one is under
+      threat, I don't think I can declare victory. If I have 4 there, but one is under threat, I
+      think that's victory.
+      */      
+      while (piecesInFlagZone)
+      {
+          Square sr = pop_lsb(piecesInFlagZone);
+          Bitboard flagAttackers = attackers_to(sr, ~c);
+
+          if ((potentialPieces < var->flagPieceCount) || (potentialPieces >= var->flagPieceCount + 1)) break;
+          while (flagAttackers)
+          {
+              Square currentAttack = pop_lsb(flagAttackers);
+              if (legal(make_move(currentAttack, sr)))
+              {
+                  potentialPieces--;
+                  break;
+              }
+          }
+      }
+      return potentialPieces >= var->flagPieceCount;
+  }
+  return simpleResult;
 }
 
 inline bool Position::check_counting() const {
index cb2fe05..e8899f3 100644 (file)
@@ -147,6 +147,7 @@ struct Variant {
   int flagPieceCount = 1;
   bool flagPieceBlockedWin = false;
   bool flagMove = false;
+  bool flagPieceSafe = false;
   bool checkCounting = false;
   int connectN = 0;
   bool connectHorizontal = true;
index e3bdf0d..73bf9e9 100644 (file)
 # flagPieceCount: number of flag pieces that have to be in the flag zone [int] (default: 1)
 # flagPieceBlockedWin: for flagPieceCount > 1, win if at least one flag piece in flag zone and all others occupied by pieces [bool] (default: false)
 # flagMove: the other side gets one more move after one reaches the flag zone [bool] (default: false)
+# flagPieceSafe: the flag piece must be safe to win [bool] (default: false)
 # checkCounting: enable check count win rule (check count is communicated via FEN, see 3check) [bool] (default: false)
 # connectN: number of aligned pieces for win [int] (default: 0)
 # connectVertical: connectN looks at Vertical rows [bool] (default: true)
@@ -1558,26 +1559,18 @@ nFoldRule = 2
 
 [alapo:chess]
 #https://www.chessvariants.org/small.dir/alapo.html
-#Reaching the opponent's back row such that the piece isn't immediately
-#captured is a win. Let's promote to a victory piece (Amazon), then, moving
-#that piece to anywhere not on the back row is a victory. There's nothing about
-#the Amazon in the rules, just a powerful piece.
-pieceToCharTable = ..BRQ........AFW.....K..brq........afw.....k
+pieceToCharTable = ..BRQ.........FW.....K..brq.........fw.....k
 maxRank = 6
 maxFile = f
 wazir = w
 fers = f
-amazon = a
 king = -
 commoner = k
 startFen = rbqqbr/wfkkfw/6/6/WFKKFW/RBQQBR
-promotionRegionWhite = *6
-promotionRegionBlack = *1
-promotedPieceType = w:a r:a f:a b:a k:a q:a
-mandatoryPiecePromotion = true
-flagPiece = a
-flagRegionWhite = *5 *4 *3 *2 *1
-flagRegionBlack = *6 *5 *4 *3 *2
+flagRegionWhite = *6
+flagRegionBlack = *1
+flagPieceSafe = true
+flagMove = true
 stalemateValue = loss
 nMoveRule = 0
 nFoldRule = 0
@@ -1740,6 +1733,12 @@ castlingRank = 2
 [castle:chess]
 castlingWins = q
 
+#https://github.com/yagu0/vchess/blob/master/client/src/translations/rules/Squatter1/en.pug
+[squatter:chess]
+flagRegionWhite = *8
+flagRegionBlack = *1
+flagPieceSafe = true
+
 [opposite-castling:chess]
 oppositeCastling = true