fixed bug where rook would also be able to initialize castling

This commit is contained in:
simoncreates
2026-02-26 21:19:47 +01:00
parent c29573f5cb
commit 701f9a188a
+7 -11
View File
@@ -201,6 +201,7 @@ class ChessBoard:
self.num_moves = max(0, self.num_moves - 1) self.num_moves = max(0, self.num_moves - 1)
return True return True
# creates all theoretically possible moves which can be performed by the piece at a position
def moves_unchecked(self, piece: Piece, pos: BoardPos) -> List[List[Tuple[int, int]]]: def moves_unchecked(self, piece: Piece, pos: BoardPos) -> List[List[Tuple[int, int]]]:
row, column = pos.p row, column = pos.p
rays: List[List[Tuple[int, int]]] = [] rays: List[List[Tuple[int, int]]] = []
@@ -310,19 +311,12 @@ class ChessBoard:
row_height = 7 if color == Color.WHITE else 0 row_height = 7 if color == Color.WHITE else 0
expected_king_pos = BoardPos((row_height, 4)) expected_king_pos = BoardPos((row_height, 4))
king_lhs_dest = BoardPos((row_height, 2))
king_rhs_dest = BoardPos((row_height, 6))
# if king moved
if self.has_piece_moved(expected_king_pos): if self.has_piece_moved(expected_king_pos):
return moves return moves
expected_lhs_rook_pos = BoardPos((row_height, 0)) expected_lhs_rook_pos = BoardPos((row_height, 0))
expected_rhs_rook_pos = BoardPos((row_height, 7)) expected_rhs_rook_pos = BoardPos((row_height, 7))
lhs_rook_dest = BoardPos((row_height, 3))
rhs_rook_dest = BoardPos((row_height, 6))
# squares that must be empty between rook and king # squares that must be empty between rook and king
lhs_pieces_inbetween = [BoardPos((row_height, i)) for i in range(1, 4)] # cols 1,2,3 lhs_pieces_inbetween = [BoardPos((row_height, i)) for i in range(1, 4)] # cols 1,2,3
rhs_pieces_inbetween = [BoardPos((row_height, i)) for i in range(5, 7)] # cols 5,6 rhs_pieces_inbetween = [BoardPos((row_height, i)) for i in range(5, 7)] # cols 5,6
@@ -331,17 +325,19 @@ class ChessBoard:
lhs_fields_attacked = [BoardPos((row_height, i)) for i in (4, 3, 2)] lhs_fields_attacked = [BoardPos((row_height, i)) for i in (4, 3, 2)]
rhs_fields_attacked = [BoardPos((row_height, i)) for i in (4, 5, 6)] rhs_fields_attacked = [BoardPos((row_height, i)) for i in (4, 5, 6)]
# queenside
if (not self.has_piece_moved(expected_lhs_rook_pos) if (not self.has_piece_moved(expected_lhs_rook_pos)
and self.are_pieces_none(lhs_pieces_inbetween) and self.are_pieces_none(lhs_pieces_inbetween)
and not self.are_fields_attacked(lhs_fields_attacked, color.opposite)): and not self.are_fields_attacked(lhs_fields_attacked, color.opposite)):
king_lhs_dest = BoardPos((row_height, 2))
moves.append(BoardMove(expected_king_pos, king_lhs_dest, MoveType.CASTLING_QUEENSIDE)) moves.append(BoardMove(expected_king_pos, king_lhs_dest, MoveType.CASTLING_QUEENSIDE))
moves.append(BoardMove(expected_lhs_rook_pos, lhs_rook_dest, MoveType.CASTLING_QUEENSIDE))
# kingside
if (not self.has_piece_moved(expected_rhs_rook_pos) if (not self.has_piece_moved(expected_rhs_rook_pos)
and self.are_pieces_none(rhs_pieces_inbetween) and self.are_pieces_none(rhs_pieces_inbetween)
and not self.are_fields_attacked(rhs_fields_attacked, color.opposite)): and not self.are_fields_attacked(rhs_fields_attacked, color.opposite)):
king_rhs_dest = BoardPos((row_height, 6))
moves.append(BoardMove(expected_king_pos, king_rhs_dest, MoveType.CASTLING_KINGSIDE)) moves.append(BoardMove(expected_king_pos, king_rhs_dest, MoveType.CASTLING_KINGSIDE))
moves.append(BoardMove(expected_rhs_rook_pos, rhs_rook_dest, MoveType.CASTLING_QUEENSIDE))
return moves return moves
def has_piece_moved(self, pos: BoardPos) -> bool: def has_piece_moved(self, pos: BoardPos) -> bool:
@@ -447,7 +443,7 @@ class ChessBoard:
# do a move and then check, if the king is still in check # do a move and then check, if the king is still in check
# if it isnt, add the move to the possibles ones # if it isnt, add the move to the possibles ones
if not self.make_move(move, color): if not self.make_move(move, color):
raise ValueError("self moves basic created a move, which cannot be done (hopefully unreachable)") raise ValueError(f"self.moves_basic created a move, which cannot be done (hopefully unreachable). move: {move}")
all_basic_enemy_moves = self.moves_basic(color.opposite) all_basic_enemy_moves = self.moves_basic(color.opposite)
king_pos = self.pos_of_king(color) king_pos = self.pos_of_king(color)
@@ -544,7 +540,7 @@ def play_random_game(board: Optional[ChessBoard] = None, max_moves: int = 400, v
return board, moves_played return board, moves_played
def run_random_games(n: int = 100, max_moves: int = 400, verbose: bool = False): def run_random_games(n: int = 20, max_moves: int = 200, verbose: bool = False):
for i in range(n): for i in range(n):
final_board, moves = play_random_game(None, max_moves=max_moves, verbose=verbose) final_board, moves = play_random_game(None, max_moves=max_moves, verbose=verbose)
if verbose: if verbose: