occupied &= ~square_bb(capture_square(kto));
if (capture(m) && blast_on_capture())
occupied &= ~((attacks_bb<KING>(kto) & ((pieces(WHITE) | pieces(BLACK)) ^ pieces(PAWN))) | kto);
+ // Petrifying a pseudo-royal piece is illegal
+ if (capture(m) && (var->petrifyOnCaptureTypes & type_of(moved_piece(m))) && (st->pseudoRoyals & from))
+ return false;
Bitboard pseudoRoyals = st->pseudoRoyals & pieces(sideToMove);
Bitboard pseudoRoyalsTheirs = st->pseudoRoyals & pieces(~sideToMove);
if (is_ok(from) && (pseudoRoyals & from))
// Self-explosions are illegal
if (pseudoRoyals & ~occupied)
return false;
+ // Petrifiable pseudo-royals can't capture
+ Bitboard attackerCandidatesTheirs = occupied & ~square_bb(kto);
+ for (PieceSet ps = var->petrifyOnCaptureTypes & extinction_piece_types(); ps;)
+ attackerCandidatesTheirs &= ~pieces(~us, pop_lsb(ps));
// Check for legality unless we capture a pseudo-royal piece
if (!(pseudoRoyalsTheirs & ~occupied))
while (pseudoRoyals)
Square sr = pop_lsb(pseudoRoyals);
// Touching pseudo-royal pieces are immune
if ( !(blast_on_capture() && (pseudoRoyalsTheirs & attacks_bb<KING>(sr)))
- && (attackers_to(sr, occupied, ~us) & (occupied & ~square_bb(kto))))
+ && (attackers_to(sr, occupied, ~us) & attackerCandidatesTheirs))
return false;
}
// Look for duple check
Square sr = pop_lsb(pseudoRoyalCandidates);
// Touching pseudo-royal pieces are immune
if (!( !(blast_on_capture() && (pseudoRoyalsTheirs & attacks_bb<KING>(sr)))
- && (attackers_to(sr, occupied, ~us) & (occupied & ~square_bb(kto)))))
+ && (attackers_to(sr, occupied, ~us) & attackerCandidatesTheirs)))
allCheck = false;
}
if (allCheck)
}
}
- // Petrifying the king is illegal
- if (var->petrifyOnCapture && capture(m) && type_of(moved_piece(m)) == KING)
- return false;
-
// mutuallyImmuneTypes (diplomacy in Atomar)-- In no-check Atomic, kings can be beside each other, but in Atomar, this prevents them from actually taking.
// Generalized to allow a custom set of pieces that can't capture a piece of the same type.
if (capture(m) &&
// Is there a direct check?
if (type_of(m) != PROMOTION && type_of(m) != PIECE_PROMOTION && type_of(m) != PIECE_DEMOTION && type_of(m) != CASTLING
- && !(var->petrifyOnCapture && capture(m) && type_of(moved_piece(m)) != PAWN))
+ && !((var->petrifyOnCaptureTypes & type_of(moved_piece(m))) && capture(m)))
{
PieceType pt = type_of(moved_piece(m));
if (pt == JANGGI_CANNON)
return true;
// Petrified piece can't give check
- if (var->petrifyOnCapture && capture(m) && type_of(moved_piece(m)) != PAWN)
+ if ((var->petrifyOnCaptureTypes & type_of(moved_piece(m))) && capture(m))
return false;
// Is there a check by special diagonal moves?
// Remove the blast pieces
- if (captured && (blast_on_capture() || var->petrifyOnCapture))
+ if (captured && (blast_on_capture() || var->petrifyOnCaptureTypes))
{
std::memset(st->unpromotedBycatch, 0, sizeof(st->unpromotedBycatch));
st->demotedBycatch = st->promotedBycatch = 0;
blastImmune |= pieces(pt);
};
Bitboard blast = blast_on_capture() ? ((attacks_bb<KING>(to) & ((pieces(WHITE) | pieces(BLACK)) ^ pieces(PAWN))) | to)
- & (pieces() ^ blastImmune) : type_of(pc) != PAWN ? square_bb(to) : Bitboard(0);
+ & (pieces() ^ blastImmune) : var->petrifyOnCaptureTypes & type_of(pc) ? square_bb(to) : Bitboard(0);
while (blast)
{
Square bsq = pop_lsb(blast);
}
// Make a wall square where the piece was
- if (bsq == to ? var->petrifyOnCapture : var->petrifyBlastPieces)
+ if (bsq == to ? bool(var->petrifyOnCaptureTypes & type_of(bpc)) : var->petrifyBlastPieces)
{
st->wallSquares |= bsq;
byTypeBB[ALL_PIECES] |= bsq;
byTypeBB[ALL_PIECES] ^= st->wallSquares ^ st->previous->wallSquares;
// Add the blast pieces
- if (st->capturedPiece && (blast_on_capture() || var->petrifyOnCapture))
+ if (st->capturedPiece && (blast_on_capture() || var->petrifyOnCaptureTypes))
{
Bitboard blast = attacks_bb<KING>(to) | to;
while (blast)
if (swap <= 0)
return true;
+ // Petrification ends SEE
+ if (var->petrifyOnCaptureTypes & type_of(moved_piece(m)) && capture(m))
+ return false;
+
Bitboard occupied = (type_of(m) != DROP ? pieces() ^ from : pieces()) ^ to;
Color stm = color_of(moved_piece(m));
Bitboard attackers = attackers_to(to, occupied);
v->extinctionPieceTypes = piece_set(ALL_PIECES);
return v;
}
+ // Petrified
+ // Sideways pawns + petrification on capture
+ // https://www.chess.com/variants/petrified
+ Variant* petrified_variant() {
+ Variant* v = pawnsideways_variant()->init();
+ v->remove_piece(KING);
+ v->add_piece(COMMONER, 'k');
+ v->castlingKingPiece[WHITE] = v->castlingKingPiece[BLACK] = COMMONER;
+ v->extinctionValue = -VALUE_MATE;
+ v->extinctionPieceTypes = piece_set(COMMONER);
+ v->extinctionPseudoRoyal = true;
+ v->petrifyOnCaptureTypes = piece_set(COMMONER) | QUEEN | ROOK | BISHOP | KNIGHT;
+ return v;
+ }
// Atomic chess without checks (ICC rules)
// https://www.chessclub.com/help/atomic
Variant* nocheckatomic_variant() {
#ifdef ALLVARS
// Duck chess
+ // https://duckchess.com/
Variant* duck_variant() {
Variant* v = chess_variant_base()->init();
v->remove_piece(KING);
add("kinglet", kinglet_variant());
add("threekings", threekings_variant());
add("horde", horde_variant());
+ add("petrified", petrified_variant());
add("nocheckatomic", nocheckatomic_variant());
add("atomic", atomic_variant());
add("atomar", atomar_variant());
&& !makpongRule
&& !connectN
&& !blastOnCapture
+ && !petrifyOnCaptureTypes
&& !capturesToHand
&& !twoBoards
&& !restrictedMobility
# blastOnCapture: captures explode all adjacent non-pawn pieces (e.g., atomic chess) [bool] (default: false)
# blastImmuneTypes: pieces completely immune to explosions (even at ground zero) [PieceSet] (default: none)
# mutuallyImmuneTypes: pieces that can't capture another piece of same types (e.g., kings (commoners) in atomar) [PieceSet] (default: none)
-# petrifyOnCapture: non-pawn pieces are turned into wall squares when capturing [bool] (default: false)
+# petrifyOnCaptureTypes: defined pieces are turned into wall squares when capturing [PieceSet] (default: -)
# petrifyBlastPieces: if petrify and blast combined, should pieces destroyed in the blast be petrified? [bool] (default: false)
# doubleStep: enable pawn double step [bool] (default: true)
# doubleStepRegionWhite: region where pawn double steps are allowed for white [Bitboard] (default: *2)
pawn = -
customPiece1 = p:fmWfceFifmnD
pawnTypes = p
-petrifyOnCapture = true
+petrifyOnCaptureTypes = pnbrq
enPassantRegion = -
#https://en.wikipedia.org/wiki/Nim