Skip to content

Commit aa0a04f

Browse files
committed
Implement Antichess insufficient material with knights
1 parent 835c520 commit aa0a04f

2 files changed

Lines changed: 23 additions & 9 deletions

File tree

chess/variant.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,25 @@ def is_variant_draw(self) -> bool:
8585
return self.is_stalemate() and self._material_balance() == 0
8686

8787
def has_insufficient_material(self, color: chess.Color) -> bool:
88-
if self.occupied != self.bishops:
88+
if not self.occupied_co[color]:
89+
return False
90+
elif not self.occupied_co[not color]:
91+
return True
92+
elif self.occupied == self.bishops:
93+
# In a position with only bishops, check if all our bishops can be
94+
# captured.
95+
we_some_on_light = bool(self.occupied_co[color] & chess.BB_LIGHT_SQUARES)
96+
we_some_on_dark = bool(self.occupied_co[color] & chess.BB_DARK_SQUARES)
97+
they_all_on_dark = not (self.occupied_co[not color] & chess.BB_LIGHT_SQUARES)
98+
they_all_on_light = not (self.occupied_co[not color] & chess.BB_DARK_SQUARES)
99+
return (we_some_on_light and they_all_on_dark) or (we_some_on_dark and they_all_on_light)
100+
elif self.occupied == self.knights and chess.popcount(self.knights) == 2:
101+
return (
102+
self.turn == color ^
103+
bool(self.occupied_co[chess.WHITE] & chess.BB_LIGHT_SQUARES) ^
104+
bool(self.occupied_co[chess.BLACK] & chess.BB_DARK_SQUARES))
105+
else:
89106
return False
90-
91-
# In a position with only bishops, check if all our bishops can be
92-
# captured.
93-
we_some_on_light = bool(self.occupied_co[color] & chess.BB_LIGHT_SQUARES)
94-
we_some_on_dark = bool(self.occupied_co[color] & chess.BB_DARK_SQUARES)
95-
they_all_on_dark = not (self.occupied_co[not color] & chess.BB_LIGHT_SQUARES)
96-
they_all_on_light = not (self.occupied_co[not color] & chess.BB_DARK_SQUARES)
97-
return (we_some_on_light and they_all_on_dark) or (we_some_on_dark and they_all_on_light)
98107

99108
def generate_pseudo_legal_moves(self, from_mask: chess.Bitboard = chess.BB_ALL, to_mask: chess.Bitboard = chess.BB_ALL) -> Iterator[chess.Move]:
100109
for move in super().generate_pseudo_legal_moves(from_mask, to_mask):

test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,11 @@ def _check(board, white, black):
561561
_check(chess.variant.GiveawayBoard("8/8/8/6b1/8/3B4/4B3/5B2 w - - 0 1"), True, True)
562562
_check(chess.variant.GiveawayBoard("8/8/5b2/8/8/3B4/3B4/8 w - - 0 1"), True, False)
563563
_check(chess.variant.SuicideBoard("8/5p2/5P2/8/3B4/1bB5/8/8 b - - 0 1"), false_negative, false_negative)
564+
_check(chess.variant.AntichessBoard("8/8/8/1n2N3/8/8/8/8 w - - 0 32"), True, False)
565+
_check(chess.variant.AntichessBoard("8/3N4/8/1n6/8/8/8/8 b - - 1 32"), True, False)
566+
_check(chess.variant.AntichessBoard("6n1/8/8/4N3/8/8/8/8 b - - 0 27"), False, True)
567+
_check(chess.variant.AntichessBoard("8/8/5n2/4N3/8/8/8/8 w - - 1 28"), False, True)
568+
_check(chess.variant.AntichessBoard("8/3n4/8/8/8/8/8/8 w - - 0 29"), False, True)
564569

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

0 commit comments

Comments
 (0)