diff --git a/src/movegen.cpp b/src/movegen.cpp index b658619d3..0c99cb322 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -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() && !pos.count(Us) && pos.pieces(Us)) *moveList++ = make(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(pos, moveList, Us, SQ_A1, SQ_A1); + } } // King moves diff --git a/src/parser.cpp b/src/parser.cpp index 3d822ebb4..8e1a5d5bd 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -450,6 +450,7 @@ Variant* VariantParser::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); diff --git a/src/position.cpp b/src/position.cpp index 39f4888e2..7d50ad079 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -1303,7 +1303,8 @@ bool Position::pseudo_legal(const Move m) const { return checkers() ? MoveList< EVASIONS>(*this).contains(m) : MoveList(*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) diff --git a/src/variant.h b/src/variant.h index cb2fe0514..0e86f5921 100644 --- a/src/variant.h +++ b/src/variant.h @@ -109,6 +109,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; diff --git a/src/variants.ini b/src/variants.ini index e3bdf0dad..6f1acfab8 100644 --- a/src/variants.ini +++ b/src/variants.ini @@ -222,6 +222,7 @@ # 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] @@ -1776,6 +1777,4 @@ stalemateValue = loss #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 \ No newline at end of file +wallOrMove = true