b ^= to - pawn_push(us);
if (pos.variant()->arrowGating)
b &= moves_bb(us, type_of(pos.piece_on(from)), to, pos.pieces() ^ from);
+ if (pos.variant()->staticGating)
+ b &= pos.variant()->staticGatingRegion;
+ if (pos.variant()->pastGating)
+ b &= square_bb(from);
+
while (b)
*moveList++ = make_gating<T>(from, to, pt, pop_lsb(b));
return moveList;
parse_attribute("gating", v->gating);
parse_attribute("arrowGating", v->arrowGating);
parse_attribute("duckGating", v->duckGating);
+ parse_attribute("staticGating", v->staticGating);
+ parse_attribute("pastGating", v->pastGating);
+ parse_attribute("staticGatingRegion", v->staticGatingRegion);
parse_attribute("seirawanGating", v->seirawanGating);
parse_attribute("cambodianMoves", v->cambodianMoves);
parse_attribute("diagonalLines", v->diagonalLines);
std::cerr << "Inconsistent settings: castlingQueensideFile > castlingKingsideFile." << std::endl;
// Check for limitations
- if (v->pieceDrops && (v->arrowGating || v->duckGating))
+ if (v->pieceDrops && (v->arrowGating || v->duckGating || v->staticGating || v->pastGating))
std::cerr << "pieceDrops and arrowGating/duckGating are incompatible." << std::endl;
// Options incompatible with royal kings
if (v->pieceTypes.find(KING) != v->pieceTypes.end())
return false;
if (var->arrowGating && !(moves_bb(us, type_of(pc), to, pieces() ^ from) & gating_square(m)))
return false;
-
+ if (var->pastGating && (from != gating_square(m)))
+ return false;
+ if (var->staticGating && !(var->staticGatingRegion & gating_square(m)))
+ return false;
+
// Handle the case where a mandatory piece promotion/demotion is not taken
if ( mandatory_piece_promotion()
&& (is_promoted(from) ? piece_demotion() : promoted_piece_type(type_of(pc)) != NO_PIECE_TYPE)
inline bool Position::wall_gating() const {
assert(var != nullptr);
- return var->arrowGating || var->duckGating;
+ return var->arrowGating || var->duckGating || var->staticGating || var->pastGating;
}
inline bool Position::seirawan_gating() const {
v->stalemateValue = VALUE_MATE;
return v;
}
+
+ Variant* isolation_variant() { //https://boardgamegeek.com/boardgame/1875/isolation
+ Variant* v = chess_variant_base()->init();
+ v->maxRank = RANK_8;
+ v->maxFile = FILE_F;
+ v->reset_pieces();
+ v->add_piece(CUSTOM_PIECES, 'p', "mK"); //move as a King, but can't capture
+ v->startFen = "2p3/6/6/6/6/6/6/3P2 w - - 0 1";
+ v->stalemateValue = -VALUE_MATE;
+ v->staticGating = true;
+ v->staticGatingRegion = AllSquares ^ make_bitboard(SQ_C1, SQ_D8);
+ return v;
+ }
+
+ Variant* isolation7x7_variant() {
+ Variant* v = isolation_variant()->init();
+ v->maxRank = RANK_7;
+ v->maxFile = FILE_G;
+ v->startFen = "3p3/7/7/7/7/7/3P3 w - - 0 1";
+ v->staticGatingRegion = AllSquares ^ make_bitboard(SQ_D1, SQ_D7);
+ return v;
+ }
+
+ Variant* snailtrail_variant() { //https://boardgamegeek.com/boardgame/37135/snailtrail
+ Variant* v = chess_variant_base()->init();
+ v->maxRank = RANK_7;
+ v->maxFile = FILE_G;
+ v->reset_pieces();
+ v->add_piece(CUSTOM_PIECES, 'p', "mK"); //move as a King, but can't capture
+ v->startFen = "6p/7/7/7/7/7/P6 w - - 0 1";
+ v->stalemateValue = -VALUE_MATE;
+ v->pastGating = true;
+ return v;
+ }
+
+ Variant* joust_variant() { //https://www.chessvariants.com/programs.dir/joust.html
+ //This page mainly describes a variant where position on home row is randomized, but also a variant where they start in the centre(implemented here)
+ Variant* v = chess_variant_base()->init();
+ v->reset_pieces();
+ v->add_piece(CUSTOM_PIECES, 'n', "mN"); //move as a Knight, but can't capture
+ v->startFen = "8/8/8/4n3/3N4/8/8/8 w - - 0 1";
+ v->stalemateValue = -VALUE_MATE;
+ v->pastGating = true;
+ return v;
+ }
+
+
#endif
// Three-check chess
// Check the king three times to win
add("nocheckatomic", nocheckatomic_variant());
add("atomic", atomic_variant());
#ifdef ALLVARS
+ add("isolation", isolation_variant());
+ add("isolation7x7", isolation7x7_variant());
+ add("snailtrail", snailtrail_variant());
add("duck", duck_variant());
+ add("joust", joust_variant());
+
#endif
+
add("3check", threecheck_variant());
add("5check", fivecheck_variant());
add("crazyhouse", crazyhouse_variant());
bool gating = false;
bool arrowGating = false;
bool duckGating = false;
+ bool staticGating = false;
+ bool pastGating = false;
+ Bitboard staticGatingRegion = AllSquares;
bool seirawanGating = false;
bool cambodianMoves = false;
Bitboard diagonalLines = 0;
# gating: maintain squares on backrank with extra rights in castling field of FEN [bool] (default: false)
# arrowGating: gating of wall squares in Game of the Amazons style [bool] (default: false)
# duckGating: gating of a wall square in Duck chess style [bool] (default: false)
+# staticGating: gating of wall squares in Isolation style [bool] (default: false)
+# staticGatingRegion: mask where wall squares can be placed [Bitboard] (default: all squares)
+# pastGating: gating of previous square [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]
whiteFlag = *9
blackFlag = *1
immobilityIllegal = true
+