add 'wall or move' rule (for Atlantis) (#728)
authorRainRat <rainrat78@yahoo.ca>
Fri, 1 Mar 2024 13:01:13 +0000 (05:01 -0800)
committerGitHub <noreply@github.com>
Fri, 1 Mar 2024 13:01:13 +0000 (14:01 +0100)
src/movegen.cpp
src/parser.cpp
src/position.cpp
src/variant.h
src/variants.ini

index 43807bb..f5a16eb 100644 (file)
@@ -29,7 +29,8 @@ namespace {
   ExtMove* make_move_and_gating(const Position& pos, ExtMove* moveList, Color us, Square from, Square to, PieceType pt = NO_PIECE_TYPE) {
 
     // Wall placing moves
-    if (pos.walling())
+    //if it's "wall or move", and they chose non-null move, skip even generating wall move
+    if (pos.walling() && !(pos.variant()->wallOrMove && (from!=to)))
     {
         Bitboard b = pos.board_bb() & ~((pos.pieces() ^ from) | to);
         if (T == CASTLING)
@@ -443,6 +444,12 @@ namespace {
         // Workaround for passing: Execute a non-move with any piece
         if (pos.pass(Us) && !pos.count<KING>(Us) && pos.pieces(Us))
             *moveList++ = make<SPECIAL>(lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));
+
+        //if "wall or move", generate walling action with null move
+        if (pos.variant()->wallOrMove)
+        {
+            moveList = make_move_and_gating<SPECIAL>(pos, moveList, Us, lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));
+        }
     }
 
     // King moves
index 2a4db2d..3ebf1b1 100644 (file)
@@ -472,6 +472,7 @@ Variant* VariantParser<DoCheck>::parse(Variant* v) {
     parse_attribute("wallingRegionBlack", v->wallingRegion[BLACK]);
     parse_attribute("wallingRegion", v->wallingRegion[WHITE]);
     parse_attribute("wallingRegion", v->wallingRegion[BLACK]);
+    parse_attribute("wallOrMove", v->wallOrMove);
     parse_attribute("seirawanGating", v->seirawanGating);
     parse_attribute("cambodianMoves", v->cambodianMoves);
     parse_attribute("diagonalLines", v->diagonalLines);
index c449b6a..023cdfa 100644 (file)
@@ -1303,7 +1303,8 @@ bool Position::pseudo_legal(const Move m) const {
       return checkers() ? MoveList<    EVASIONS>(*this).contains(m)
                         : MoveList<NON_EVASIONS>(*this).contains(m);
 
-  if (walling())
+  //if walling, and walling is not optional, or they didn't move, do the checks.
+  if (walling() && (!var->wallOrMove || (from==to)))
   {
       Bitboard wallsquares = st->wallSquares;
 
@@ -2045,7 +2046,8 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
   }
 
   // Add gated wall square
-  if (walling())
+  // if wallOrMove, only actually place the wall if they gave up their move
+  if (walling() && (!var->wallOrMove || (from==to)))
   {
       // Reset wall squares for duck walling
       if (walling_rule() == DUCK)
index a34b37d..aa27383 100644 (file)
@@ -108,6 +108,7 @@ struct Variant {
   bool gating = false;
   WallingRule wallingRule = NO_WALLING;
   Bitboard wallingRegion[COLOR_NB] = {AllSquares, AllSquares};
+  bool wallOrMove = false;
   bool seirawanGating = false;
   bool cambodianMoves = false;
   Bitboard diagonalLines = 0;
index 0b27fc2..fd5b504 100644 (file)
 # wallingRule: rule on where wall can be placed [WallingRule] (default: none)
 # wallingRegionWhite: mask where wall squares (including duck) can be placed by white [Bitboard] (default: all squares)
 # wallingRegionBlack: mask where wall squares (including duck) can be placed by black [Bitboard] (default: all squares)
+# wallOrMove: can wall or move, but not both [bool] (default: false)
 # seirawanGating: allow gating of pieces in hand like in S-Chess, requires "gating = true" [bool] (default: false)
 # cambodianMoves: enable special moves of cambodian chess, requires "gating = true" [bool] (default: false)
 # diagonalLines: enable special moves along diagonal for specific squares (Janggi) [Bitboard]
@@ -1811,9 +1812,7 @@ connectDiagonal = false
 #https://www.chessvariants.com/boardrules.dir/atlantis.html
 [atlantis:chess]
 wallingRule = edge
-#not ready yet. Other wall variants are "move and wall", this is "move or wall".
-#need to figure out way to do this ie. write code for:
-#wallOrMove = true
+wallOrMove = true
 
 #https://www.chessvariants.com/rules/ajax-orthodox-chess
 [ajax-orthodox:chess]