Skip to content

Commit

Permalink
Implement Antichess insufficient material with knights
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasf committed Jul 22, 2022
1 parent 835c520 commit aa0a04f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
27 changes: 18 additions & 9 deletions chess/variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,25 @@ def is_variant_draw(self) -> bool:
return self.is_stalemate() and self._material_balance() == 0

def has_insufficient_material(self, color: chess.Color) -> bool:
if self.occupied != self.bishops:
if not self.occupied_co[color]:
return False
elif not self.occupied_co[not color]:
return True
elif self.occupied == self.bishops:
# In a position with only bishops, check if all our bishops can be
# captured.
we_some_on_light = bool(self.occupied_co[color] & chess.BB_LIGHT_SQUARES)
we_some_on_dark = bool(self.occupied_co[color] & chess.BB_DARK_SQUARES)
they_all_on_dark = not (self.occupied_co[not color] & chess.BB_LIGHT_SQUARES)
they_all_on_light = not (self.occupied_co[not color] & chess.BB_DARK_SQUARES)
return (we_some_on_light and they_all_on_dark) or (we_some_on_dark and they_all_on_light)
elif self.occupied == self.knights and chess.popcount(self.knights) == 2:
return (
self.turn == color ^
bool(self.occupied_co[chess.WHITE] & chess.BB_LIGHT_SQUARES) ^
bool(self.occupied_co[chess.BLACK] & chess.BB_DARK_SQUARES))
else:
return False

# In a position with only bishops, check if all our bishops can be
# captured.
we_some_on_light = bool(self.occupied_co[color] & chess.BB_LIGHT_SQUARES)
we_some_on_dark = bool(self.occupied_co[color] & chess.BB_DARK_SQUARES)
they_all_on_dark = not (self.occupied_co[not color] & chess.BB_LIGHT_SQUARES)
they_all_on_light = not (self.occupied_co[not color] & chess.BB_DARK_SQUARES)
return (we_some_on_light and they_all_on_dark) or (we_some_on_dark and they_all_on_light)

def generate_pseudo_legal_moves(self, from_mask: chess.Bitboard = chess.BB_ALL, to_mask: chess.Bitboard = chess.BB_ALL) -> Iterator[chess.Move]:
for move in super().generate_pseudo_legal_moves(from_mask, to_mask):
Expand Down
5 changes: 5 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,11 @@ def _check(board, white, black):
_check(chess.variant.GiveawayBoard("8/8/8/6b1/8/3B4/4B3/5B2 w - - 0 1"), True, True)
_check(chess.variant.GiveawayBoard("8/8/5b2/8/8/3B4/3B4/8 w - - 0 1"), True, False)
_check(chess.variant.SuicideBoard("8/5p2/5P2/8/3B4/1bB5/8/8 b - - 0 1"), false_negative, false_negative)
_check(chess.variant.AntichessBoard("8/8/8/1n2N3/8/8/8/8 w - - 0 32"), True, False)
_check(chess.variant.AntichessBoard("8/3N4/8/1n6/8/8/8/8 b - - 1 32"), True, False)
_check(chess.variant.AntichessBoard("6n1/8/8/4N3/8/8/8/8 b - - 0 27"), False, True)
_check(chess.variant.AntichessBoard("8/8/5n2/4N3/8/8/8/8 w - - 1 28"), False, True)
_check(chess.variant.AntichessBoard("8/3n4/8/8/8/8/8/8 w - - 0 29"), False, True)

_check(chess.variant.KingOfTheHillBoard("8/5k2/8/8/8/8/3K4/8 w - - 0 1"), False, False)

Expand Down

0 comments on commit aa0a04f

Please sign in to comment.