Untitled
unknown
python
5 months ago
3.2 kB
8
Indexable
import chess def a_star_search(board: chess.Board, goal_position: chess.Square): """ Implements the A* search algorithm to find the final path for the Knight's quest. Parameters: - board: The chess board that the knight is moving upon. - goal_position: The target square where the knight needs to move (H8). Returns: A list containing the final path from start to goal, represented by square IDs. """ # Priority queue: stores (f(n), g(n), current_square, path_to_current_square) priority_queue = [] # g_score: cost to reach a square from the start g_score = {i: float('inf') for i in range(64)} # Initialize with infinity g_score[0] = 0 # The knight starts at A1 (square 0) # Start position and push it to the list with initial f(n) = g(n) + h(n) start_position = 0 priority_queue.append((0 + chess.square_knight_distance(start_position, goal_position), 0, start_position, [start_position])) # Set to track visited nodes visited = set() while priority_queue: # Sort the queue manually by f(n) to always pick the best option priority_queue.sort(key=lambda x: x[0]) # Sort by f(n) f_current, g_current, current_square, path_to_current = priority_queue.pop(0) # If the current square is the goal, return the path if current_square == goal_position: return path_to_current # If we've already visited this node, skip it if current_square in visited: continue # Mark this node as visited visited.add(current_square) # Place the knight at the current square board.clear() # Clear the board board.set_piece_at(current_square, chess.Piece(chess.KNIGHT, chess.WHITE)) # Place the knight # Get all legal moves for the knight from the current square legal_moves = list(board.legal_moves) # Prepare the list of possible moves sorted by f(n) for move in legal_moves: next_square = move.to_square # Skip already visited squares if next_square in visited: continue # Calculate g(n): the cost to reach next_square tentative_g_score = g_current + 1 # Only proceed if this new g(n) is better (shorter path) than what we have for the next square if tentative_g_score < g_score[next_square]: # Update g(n) for next_square g_score[next_square] = tentative_g_score # Calculate h(n): heuristic cost to the goal h_score = chess.square_knight_distance(next_square, goal_position) # Calculate f(n) = g(n) + h(n) f_score = tentative_g_score + h_score # Add the move to the priority queue priority_queue.append((f_score, tentative_g_score, next_square, path_to_current + [next_square])) # If we exhaust the priority queue without finding the goal, return an empty list (shouldn't happen) return []
Editor is loading...
Leave a Comment