Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def status(self) -> chess.Status:
status = super().status()
if chess.popcount(self.pawns) + self.pockets[chess.WHITE].count(chess.PAWN) + self.pockets[chess.BLACK].count(chess.PAWN) <= 16:
status &= ~chess.STATUS_TOO_MANY_BLACK_PAWNS
status &= ~chess.STATUS_TOO_MANY_WHITE_PAWNS
if chess.popcount(self.occupied) + len(self.pockets[chess.WHITE]) + len(self.pockets[chess.BLACK]) <= 32:
status &= ~chess.STATUS_TOO_MANY_BLACK_PIECES
status &= ~chess.STATUS_TOO_MANY_WHITE_PIECES
return status
def calc_key(board: chess.BaseBoard, *, mirror: bool = False) -> str:
w = board.occupied_co[chess.WHITE ^ mirror]
b = board.occupied_co[chess.BLACK ^ mirror]
return "".join([
"K" * chess.popcount(board.kings & w),
"Q" * chess.popcount(board.queens & w),
"R" * chess.popcount(board.rooks & w),
"B" * chess.popcount(board.bishops & w),
"N" * chess.popcount(board.knights & w),
"P" * chess.popcount(board.pawns & w),
"v",
"K" * chess.popcount(board.kings & b),
"Q" * chess.popcount(board.queens & b),
"R" * chess.popcount(board.rooks & b),
"B" * chess.popcount(board.bishops & b),
"N" * chess.popcount(board.knights & b),
"P" * chess.popcount(board.pawns & b),
])
def legal_drop_squares_mask(self) -> chess.Bitboard:
king = self.king(self.turn)
if king is None:
return ~self.occupied
king_attackers = self.attackers_mask(not self.turn, king)
if not king_attackers:
return ~self.occupied
elif chess.popcount(king_attackers) == 1:
return chess.BB_BETWEEN[king][chess.msb(king_attackers)] & ~self.occupied
else:
return chess.BB_EMPTY
-2
:raises: :exc:`KeyError` (or specifically
:exc:`chess.syzygy.MissingTableError`) if the position could not
be found in the tablebase. Use
:func:`~chess.syzygy.Tablebase.get_wdl()` if you prefer to get
``None`` instead of an exception.
Note that probing corrupted table files is undefined behavior.
"""
# Positions with castling rights are not in the tablebase.
if board.castling_rights:
raise KeyError("syzygy tables do not contain positions with castling rights: {}".format(board.fen()))
# Validate piece count.
if chess.popcount(board.occupied) > 7:
raise KeyError("syzygy tables support up to 6 (and experimentally 7) pieces, not {}: {}".format(chess.popcount(board.occupied), board.fen()))
# Probe.
v, _ = self.probe_ab(board, -2, 2)
# If en passant is not possible, we are done.
if not board.ep_square or self.variant.captures_compulsory:
return v
# Now handle en passant.
v1 = -3
# Look at all legal en passant captures.
for move in board.generate_legal_ep():
board.push(move)
try:
def sprobe_ab(self, board: chess.Board, alpha: int, beta: int, threats: bool = False) -> Tuple[int, int]:
if chess.popcount(board.occupied_co[not board.turn]) > 1:
v, captures_found = self.sprobe_capts(board, alpha, beta)
if captures_found:
return v, 2
else:
if any(board.generate_legal_captures()):
return -2, 2
threats_found = False
if threats or chess.popcount(board.occupied) >= 6:
for threat in board.generate_legal_moves(~board.pawns):
board.push(threat)
try:
v_plus, captures_found = self.sprobe_capts(board, -beta, -alpha)
v = -v_plus
finally:
board.pop()
if captures_found and v > alpha:
threats_found = True
alpha = v
if alpha >= beta:
return v, 3
v = self.probe_wdl_table(board)
if v > alpha:
def _material_balance(self) -> int:
return (chess.popcount(self.occupied_co[self.turn]) -
chess.popcount(self.occupied_co[not self.turn]))
:raises: :exc:`KeyError` (or specifically
:exc:`chess.syzygy.MissingTableError`) if the position could not
be found in the tablebase. Use
:func:`~chess.syzygy.Tablebase.get_wdl()` if you prefer to get
``None`` instead of an exception.
Note that probing corrupted table files is undefined behavior.
"""
# Positions with castling rights are not in the tablebase.
if board.castling_rights:
raise KeyError("syzygy tables do not contain positions with castling rights: {}".format(board.fen()))
# Validate piece count.
if chess.popcount(board.occupied) > 7:
raise KeyError("syzygy tables support up to 6 (and experimentally 7) pieces, not {}: {}".format(chess.popcount(board.occupied), board.fen()))
# Probe.
v, _ = self.probe_ab(board, -2, 2)
# If en passant is not possible, we are done.
if not board.ep_square or self.variant.captures_compulsory:
return v
# Now handle en passant.
v1 = -3
# Look at all legal en passant captures.
for move in board.generate_legal_ep():
board.push(move)
try:
v0_plus, _ = self.probe_ab(board, -2, 2)
def calc_key(board: chess.BaseBoard, *, mirror: bool = False) -> str:
w = board.occupied_co[chess.WHITE ^ mirror]
b = board.occupied_co[chess.BLACK ^ mirror]
return "".join([
"K" * chess.popcount(board.kings & w),
"Q" * chess.popcount(board.queens & w),
"R" * chess.popcount(board.rooks & w),
"B" * chess.popcount(board.bishops & w),
"N" * chess.popcount(board.knights & w),
"P" * chess.popcount(board.pawns & w),
"v",
"K" * chess.popcount(board.kings & b),
"Q" * chess.popcount(board.queens & b),
"R" * chess.popcount(board.rooks & b),
"B" * chess.popcount(board.bishops & b),
"N" * chess.popcount(board.knights & b),
"P" * chess.popcount(board.pawns & b),
])
def _probe_hard(self, board: chess.Board, wdl_only: bool = False) -> int:
if board.is_insufficient_material():
return 0
if board.castling_rights:
raise KeyError("gaviota tables do not contain positions with castling rights: {}".format(board.fen()))
if chess.popcount(board.occupied) > 5:
raise KeyError("gaviota tables support up to 5 pieces, not {}: {}".format(chess.popcount(board.occupied), board.fen()))
stm = ctypes.c_uint(0 if board.turn == chess.WHITE else 1)
ep_square = ctypes.c_uint(board.ep_square if board.ep_square else 64)
castling = ctypes.c_uint(0)
c_ws = (ctypes.c_uint * 17)()
c_wp = (ctypes.c_ubyte * 17)()
i = -1
for i, square in enumerate(chess.SquareSet(board.occupied_co[chess.WHITE])):
c_ws[i] = square
c_wp[i] = typing.cast(chess.PieceType, board.piece_type_at(square))
c_ws[i + 1] = 64
c_wp[i + 1] = 0