Skip to content

Commit

Permalink
disable pawn check if no promotion available
Browse files Browse the repository at this point in the history
  • Loading branch information
Cab committed Feb 10, 2024
1 parent 93a252c commit 4361f34
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
38 changes: 36 additions & 2 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960,
chess960 = isChess960 || v->chess960;
tsumeMode = Options["TsumeMode"];
thisThread = th;
updatePawnCheckZone();
set_state(st);

assert(pos_is_ok());
Expand Down Expand Up @@ -936,7 +937,7 @@ Bitboard Position::attackers_to(Square s, Bitboard occupied, Color c, Bitboard j
// Use a faster version for variants with moderate rule variations
if (var->fastAttacks)
{
return (pawn_attacks_bb(~c, s) & pieces(c, PAWN))
return (pawn_attacks_bb(~c, s) & pieces(c, PAWN) & ~pawnCannotCheckZone[c])
| (attacks_bb<KNIGHT>(s) & pieces(c, KNIGHT, ARCHBISHOP, CHANCELLOR))
| (attacks_bb< ROOK>(s, occupied) & pieces(c, ROOK, QUEEN, CHANCELLOR))
| (attacks_bb<BISHOP>(s, occupied) & pieces(c, BISHOP, QUEEN, ARCHBISHOP))
Expand Down Expand Up @@ -2111,11 +2112,12 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
k ^= Zobrist::wall[gating_square(m)];
}

updatePawnCheckZone();
// Update the key with the final value
st->key = k;
// Calculate checkers bitboard (if move gives check)
st->checkersBB = givesCheck ? attackers_to(square<KING>(them), us) & pieces(us) : Bitboard(0);
assert(givesCheck == bool(st->checkersBB));
assert(givesCheck == bool(st->checkersBB) || givesCheck && var->prisonPawnPromotion);

sideToMove = ~sideToMove;

Expand Down Expand Up @@ -2954,6 +2956,13 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
return true;
}
}
if (var->prisonPawnPromotion &&
(pawn_attacks_bb(~sideToMove, square<KING>(~sideToMove))
& pieces(sideToMove, PAWN)
& ~pawnCannotCheckZone[sideToMove]) ){
result = mate_in(ply);
return true;
}

return false;
}
Expand Down Expand Up @@ -3252,6 +3261,31 @@ void Position::flip() {
assert(pos_is_ok());
}

void Position::updatePawnCheckZone() {
if (!var->prisonPawnPromotion) {
pawnCannotCheckZone[WHITE] = Bitboard(0);
pawnCannotCheckZone[BLACK] = Bitboard(0);
return;
}
for (Color color : { BLACK, WHITE }) {
if (count<KING>(~color) == 0) {
pawnCannotCheckZone[color] = Bitboard(0);
} else {
bool canPromotion = false;
for (PieceSet prom = promotion_piece_types(color) & rescueFor(PAWN); prom; ) {
PieceType pt = pop_lsb(prom);
if (count_in_prison(~color, pt) > 0) {
canPromotion = true;
break;
}
}
Bitboard pz = promotion_zone(color);
pawnCannotCheckZone[color] = canPromotion
? Bitboard(0)
: color == WHITE ? shift(SOUTH, pz) : shift(NORTH, pz);
}
}
}

/// Position::pos_is_ok() performs some consistency checks for the
/// position object and raises an asserts if something wrong is detected.
Expand Down
2 changes: 2 additions & 0 deletions src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,14 @@ class Position {
bool chess960;
int pieceCountInHand[COLOR_NB][PIECE_TYPE_NB];
int pieceCountInPrison[COLOR_NB][PIECE_TYPE_NB];
Bitboard pawnCannotCheckZone[COLOR_NB];
int virtualPieces;
Bitboard promotedPieces;
void add_to_hand(Piece pc);
int add_to_prison(Piece pc);
void remove_from_hand(Piece pc);
int remove_from_prison(Piece pc);
void updatePawnCheckZone();
void drop_piece(Piece pc_hand, Piece pc_drop, Square s, PieceType exchange);
void undrop_piece(Piece pc_hand, Square s, PieceType exchange);
Bitboard find_drop_region(Direction dir, Square s, Bitboard occupied) const;
Expand Down

0 comments on commit 4361f34

Please sign in to comment.