Skip to content

Commit 63aac2e

Browse files
committed
Expose optional occupied parameter for attackers_mask (#1090)
1 parent ec8ecec commit 63aac2e

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

chess/__init__.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,9 @@ def attacks(self, square: Square) -> SquareSet:
902902
"""
903903
return SquareSet(self.attacks_mask(square))
904904

905-
def _attackers_mask(self, color: Color, square: Square, occupied: Bitboard) -> Bitboard:
905+
def attackers_mask(self, color: Color, square: Square, occupied: Optional[Bitboard] = None) -> Bitboard:
906+
occupied = self.occupied if occupied is None else occupied
907+
906908
rank_pieces = BB_RANK_MASKS[square] & occupied
907909
file_pieces = BB_FILE_MASKS[square] & occupied
908910
diag_pieces = BB_DIAG_MASKS[square] & occupied
@@ -920,27 +922,38 @@ def _attackers_mask(self, color: Color, square: Square, occupied: Bitboard) -> B
920922

921923
return attackers & self.occupied_co[color]
922924

923-
def attackers_mask(self, color: Color, square: Square) -> Bitboard:
924-
return self._attackers_mask(color, square, self.occupied)
925-
926-
def is_attacked_by(self, color: Color, square: Square) -> bool:
925+
def is_attacked_by(self, color: Color, square: Square, occupied: Optional[IntoSquareSet] = None) -> bool:
927926
"""
928927
Checks if the given side attacks the given square.
929928
930929
Pinned pieces still count as attackers. Pawns that can be captured
931930
en passant are **not** considered attacked.
931+
932+
*occupied* determines which squares are considered to block attacks.
933+
For example,
934+
``board.occupied ^ board.pieces_mask(chess.KING, board.turn)`` can be
935+
used to consider X-ray attacks through the king.
936+
Defaults to ``board.occupied`` (all pieces including the king,
937+
no X-ray attacks).
932938
"""
933-
return bool(self.attackers_mask(color, square))
939+
return bool(self.attackers_mask(color, square, None if occupied is None else SquareSet(occupied).mask))
934940

935-
def attackers(self, color: Color, square: Square) -> SquareSet:
941+
def attackers(self, color: Color, square: Square, occupied: Optional[IntoSquareSet] = None) -> SquareSet:
936942
"""
937943
Gets the set of attackers of the given color for the given square.
938944
939945
Pinned pieces still count as attackers.
940946
947+
*occupied* determines which squares are considered to block attacks.
948+
For example,
949+
``board.occupied ^ board.pieces_mask(chess.KING, board.turn)`` can be
950+
used to consider X-ray attacks through the king.
951+
Defaults to ``board.occupied`` (all pieces including the king,
952+
no X-ray attacks).
953+
941954
Returns a :class:`set of squares <chess.SquareSet>`.
942955
"""
943-
return SquareSet(self.attackers_mask(color, square))
956+
return SquareSet(self.attackers_mask(color, square, None if occupied is None else SquareSet(occupied).mask))
944957

945958
def pin_mask(self, color: Color, square: Square) -> Bitboard:
946959
king = self.king(color)
@@ -3723,7 +3736,7 @@ def generate_legal_captures(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboar
37233736
self.generate_legal_ep(from_mask, to_mask))
37243737

37253738
def _attacked_for_king(self, path: Bitboard, occupied: Bitboard) -> bool:
3726-
return any(self._attackers_mask(not self.turn, sq, occupied) for sq in scan_reversed(path))
3739+
return any(self.attackers_mask(not self.turn, sq, occupied) for sq in scan_reversed(path))
37273740

37283741
def generate_castling_moves(self, from_mask: Bitboard = BB_ALL, to_mask: Bitboard = BB_ALL) -> Iterator[Move]:
37293742
if self.is_variant_end():

0 commit comments

Comments
 (0)