def test_distance(self): h8 = Position(Rank.EIGHT, File.H) h7 = Position(Rank.SEVEN, File.H) h1 = Position(Rank.ONE, File.H) a8 = Position(Rank.EIGHT, File.A) a1 = Position(Rank.ONE, File.A) self.assertEqual(h8.dist(h7), 1) self.assertEqual(h8.dist(h1), 7) self.assertEqual(h8.dist(a8), 7) self.assertEqual(a8.dist(h8), 7) self.assertEqual(a1.dist(h8), 7)
def en_passant_handler(board, *, from_pos: Position, to_pos: Position): board_move_func(board, from_pos=from_pos, to_pos=to_pos) square = board[to_pos.rank][to_pos.file] if to_pos == board.en_passant_pos: # capture(delete) the pawn assert isinstance(square, Pawn) board[from_pos.rank][to_pos.file] = None board.en_passant_pos = None if hasattr(square, 'figure_type') and square.figure_type is Type.PAWN and from_pos.dist(to_pos) == 2: direction = square.color.forward_direction board.en_passant_pos = Position(to_pos.rank - direction, to_pos.file)
def maybe_castle_wrapper(board, *, from_pos: Position, to_pos: Position): board_move_func(board, from_pos=from_pos, to_pos=to_pos) square = board[to_pos.rank][to_pos.file] if getattr(square, 'figure_type', None) is Type.KING: board.castling_perms[square.color] = CastlingPerm.NONE if from_pos.dist(to_pos) == 2: # Castling -> Move rook direction = from_pos.relative_direction_towards_position(to_pos) old_file, new_file = ('a', 'd') if direction is Direction.LEFT else ('h', 'f') rank = '1' if square.color is Color.WHITE else '8' board.move(from_pos=P(f'{old_file}{rank}'), to_pos=P(f'{new_file}{rank}'))
def get_attackers( self, start_pos: Position, color: Color ) -> Generator[Position, None, None]: all_directions = list(Diagonal) + list(Direction) positions_by_dir = self.get_positions_in_direction(start_pos, *all_directions) positions_by_dir['Knight'] = filter(self.is_in_bounds, Knight.possible_positions(start_pos)) diagonals = [d.name for d in Diagonal] # TODO(yavor): cleanup from bug fix directions = [d.name for d in Direction] for direction, positions in positions_by_dir.items(): direction = getattr(direction, 'name', direction) # TODO(yavor): cleanup bug fix for position in positions: if not self.is_empty(position) and self.are_enemies(color, position): enemy = self[position.rank][position.file] enemy_type = enemy.figure_type if direction == 'Knight' and enemy_type is Type.KNIGHT: yield position if direction in diagonals and enemy_type in [Type.BISHOP, Type.QUEEN]: yield position elif direction in directions and enemy_type in [Type.ROOK, Type.QUEEN]: yield position elif enemy_type is Type.KING and start_pos.dist(position) == 1: yield position elif enemy_type is Type.PAWN: direction = Direction.DOWN if enemy.color == Color.WHITE else Direction.UP pawn_positions = { Position(rank=start_pos.rank + direction, file=start_pos.file + Direction.RIGHT), Position(rank=start_pos.rank + direction, file=start_pos.file + Direction.LEFT) } if position in pawn_positions: yield position elif not self.is_empty(position) and direction != 'Knight': # every other piece is blockable so we can stop going further break