- [Chess Variants on Chess.com](https://www.chess.com/variants)
### Development Best Practices
-* Make sure to only stage and commit changes that are intended to be part of the task.
+* Make sure to only stage and commit changes that were changed as part of the task, do not simply add all changes.
* Keep changes minimal and focused on the task at hand.
* After applying changes make sure that all places related to the task have been identified.
* Stay consistent with the existing code style and conventions.
parse_attribute("doubleStepRegionBlack", v->doubleStepRegion[BLACK]);
parse_attribute("tripleStepRegionWhite", v->tripleStepRegion[WHITE]);
parse_attribute("tripleStepRegionBlack", v->tripleStepRegion[BLACK]);
- parse_attribute("enPassantRegion", v->enPassantRegion);
+ parse_attribute("enPassantRegion", v->enPassantRegion[WHITE]);
+ parse_attribute("enPassantRegion", v->enPassantRegion[BLACK]);
+ parse_attribute("enPassantRegionWhite", v->enPassantRegion[WHITE]);
+ parse_attribute("enPassantRegionBlack", v->enPassantRegion[BLACK]);
parse_attribute("enPassantTypes", v->enPassantTypes[WHITE], v->pieceToChar);
parse_attribute("enPassantTypes", v->enPassantTypes[BLACK], v->pieceToChar);
parse_attribute("enPassantTypesWhite", v->enPassantTypes[WHITE], v->pieceToChar);
// a) side to move have a pawn threatening epSquare
// b) there is an enemy pawn one or two (for triple steps) squares in front of epSquare
// c) there is no (non-wall) piece on epSquare or behind epSquare
- if ( (var->enPassantRegion & epSquare)
+ if ( (var->enPassantRegion[sideToMove] & epSquare)
&& ( !var->fastAttacks
|| (var->enPassantTypes[sideToMove] & ~piece_set(PAWN))
|| ( pawn_attacks_bb(~sideToMove, epSquare) & pieces(sideToMove, PAWN)
st->captureSquare = capsq;
assert(st->epSquares & to);
- assert(var->enPassantRegion & to);
+ assert(var->enPassantRegion[us] & to);
assert(piece_on(to) == NO_PIECE);
}
&& ( std::abs(int(to) - int(from)) == 2 * NORTH
|| std::abs(int(to) - int(from)) == 3 * NORTH))
{
- if ( (var->enPassantRegion & (to - pawn_push(us)))
+ if ( (var->enPassantRegion[them] & (to - pawn_push(us)))
&& ((pawn_attacks_bb(us, to - pawn_push(us)) & pieces(them, PAWN)) || var->enPassantTypes[them] & ~piece_set(PAWN))
&& !(walling() && gating_square(m) == to - pawn_push(us)))
{
k ^= Zobrist::enpassant[file_of(to)];
}
if ( std::abs(int(to) - int(from)) == 3 * NORTH
- && (var->enPassantRegion & (to - 2 * pawn_push(us)))
+ && (var->enPassantRegion[them] & (to - 2 * pawn_push(us)))
&& ((pawn_attacks_bb(us, to - 2 * pawn_push(us)) & pieces(them, PAWN)) || var->enPassantTypes[them] & ~piece_set(PAWN))
&& !(walling() && gating_square(m) == to - 2 * pawn_push(us)))
{
&& ((PseudoMoves[1][us][type_of(pc)][from] & ~PseudoMoves[0][us][type_of(pc)][from]) & to))
{
assert(type_of(pc) != PAWN);
- st->epSquares = between_bb(from, to) & var->enPassantRegion;
+ st->epSquares = between_bb(from, to) & var->enPassantRegion[them];
for (Bitboard b = st->epSquares; b; )
k ^= Zobrist::enpassant[file_of(pop_lsb(b))];
}
capsq = st->captureSquare;
assert(st->previous->epSquares & to);
- assert(var->enPassantRegion & to);
+ assert(var->enPassantRegion[sideToMove] & to);
assert(piece_on(capsq) == NO_PIECE);
}
if ( (sideToMove != WHITE && sideToMove != BLACK)
|| (count<KING>(WHITE) && piece_on(square<KING>(WHITE)) != make_piece(WHITE, KING))
|| (count<KING>(BLACK) && piece_on(square<KING>(BLACK)) != make_piece(BLACK, KING))
- || (ep_squares() & ~var->enPassantRegion))
+ || (ep_squares() & ~(var->enPassantRegion[WHITE] | var->enPassantRegion[BLACK])))
assert(0 && "pos_is_ok: Default");
if (Fast)
Variant* v = chess_variant_base()->init();
v->startFen = "rnbqkbnr/pppppppp/8/1PP2PP1/PPPPPPPP/PPPPPPPP/PPPPPPPP/PPPPPPPP w kq - 0 1";
v->doubleStepRegion[WHITE] |= Rank1BB;
- v->enPassantRegion = Rank3BB | Rank6BB; // exclude en passant on second rank
+ v->enPassantRegion[WHITE] = Rank6BB; // exclude en passant on second rank
+ v->enPassantRegion[BLACK] = Rank3BB; // exclude en passant on second rank
v->extinctionValue = -VALUE_MATE;
v->extinctionPieceTypes = piece_set(ALL_PIECES);
return v;
v->nMoveRuleTypes[BLACK] = piece_set(CUSTOM_PIECE_1);
v->promotionPieceTypes[BLACK] = piece_set(COMMONER) | DRAGON | ARCHBISHOP | CUSTOM_PIECE_2 | CUSTOM_PIECE_3;
v->promotionLimit[COMMONER] = 2;
- v->enPassantRegion = 0;
+ v->enPassantRegion[WHITE] = 0;
+ v->enPassantRegion[BLACK] = 0;
v->extinctionPieceCount = 0;
v->extinctionPseudoRoyal = true;
v->dupleCheck = true;
bool doubleStep = true;
Bitboard doubleStepRegion[COLOR_NB] = {Rank2BB, Rank7BB};
Bitboard tripleStepRegion[COLOR_NB] = {};
- Bitboard enPassantRegion = AllSquares;
+ Bitboard enPassantRegion[COLOR_NB] = {AllSquares, AllSquares};
PieceSet enPassantTypes[COLOR_NB] = {piece_set(PAWN), piece_set(PAWN)};
bool castling = true;
bool castlingDroppedPiece = false;
# tripleStepRegionWhite: region where pawn triple steps are allowed for white [Bitboard] (default: -)
# tripleStepRegionBlack: region where pawn triple steps are allowed for black [Bitboard] (default: -)
# enPassantRegion: define region (target squares) where en passant is allowed after double steps [Bitboard] (default: AllSquares)
+# enPassantRegionWhite: define region (target squares) where en passant is allowed for white [Bitboard] (default: AllSquares)
+# enPassantRegionBlack: define region (target squares) where en passant is allowed for black [Bitboard] (default: AllSquares)
# enPassantTypes: define pieces able to capture en passant [PieceSet] (default: p)
# enPassantTypesWhite: define white pieces able to capture en passant [PieceSet] (default: p)
# enPassantTypesBlack: define black pieces able to capture en passant [PieceSet] (default: p)