pacai.search.food
1import typing 2 3import pacai.core.board 4import pacai.core.gamestate 5import pacai.core.search 6import pacai.pacman.board 7 8class FoodSearchNode(pacai.core.search.SearchNode): 9 """ 10 A search node for the food search problem. 11 The state for this search problem will be 12 the current position and the remaining food positions. 13 """ 14 15 def __init__(self, 16 position: pacai.core.board.Position, 17 remaining_food: typing.Iterable[pacai.core.board.Position]) -> None: 18 self.position: pacai.core.board.Position = position 19 """ The current position being searched. """ 20 21 self.remaining_food: tuple[pacai.core.board.Position, ...] = tuple(sorted(list(remaining_food))) 22 """ 23 The food left to eat. 24 This is kept sorted to ensure that underlying comparison checks run cleanly. 25 """ 26 27 def __lt__(self, other: object) -> bool: 28 if (not isinstance(other, FoodSearchNode)): 29 return False 30 31 return ((self.position, self.remaining_food) < (other.position, other.remaining_food)) 32 33 def __eq__(self, other: object) -> bool: 34 if (not isinstance(other, FoodSearchNode)): 35 return False 36 37 return ((self.position == other.position) and (self.remaining_food == other.remaining_food)) 38 39 def __hash__(self) -> int: 40 return hash((self.position, self.remaining_food)) 41 42class FoodSearchProblem(pacai.core.search.SearchProblem[FoodSearchNode]): 43 """ 44 A search problem associated with finding the a path that collects all of the "food" in a game. 45 """ 46 47 def __init__(self, 48 game_state: pacai.core.gamestate.GameState, 49 start_position: pacai.core.board.Position | None = None, 50 **kwargs: typing.Any) -> None: 51 """ 52 Create a food search problem. 53 54 If no start position is provided, the current agent's position will be used. 55 """ 56 57 super().__init__() 58 59 self.state: pacai.core.gamestate.GameState = game_state 60 """ Keep track of the enire game state. """ 61 62 if (start_position is None): 63 start_position = game_state.get_agent_position() 64 65 if (start_position is None): 66 raise ValueError("Could not find starting position.") 67 68 self.start_position = start_position 69 """ The position to start from. """ 70 71 def get_starting_node(self) -> FoodSearchNode: 72 return FoodSearchNode(self.start_position, self.state.board.get_marker_positions(pacai.pacman.board.MARKER_PELLET)) 73 74 def is_goal_node(self, node: FoodSearchNode) -> bool: 75 return (len(node.remaining_food) == 0) 76 77 def complete(self, goal_node: FoodSearchNode) -> None: 78 # Mark the final node in the history. 79 self.position_history.append(goal_node.position) 80 81 def get_successor_nodes(self, node: FoodSearchNode) -> list[pacai.core.search.SuccessorInfo]: 82 successors = [] 83 84 # Check all the non-wall neighbors. 85 for (action, position) in self.state.board.get_neighbors(node.position): 86 new_remaining_food = list(node.remaining_food).copy() 87 if (position in new_remaining_food): 88 new_remaining_food.remove(position) 89 90 next_node = FoodSearchNode(position, new_remaining_food) 91 successors.append(pacai.core.search.SuccessorInfo(next_node, action, 1.0)) 92 93 # Do bookkeeping on the states/positions we visited. 94 self.expanded_node_count += 1 95 if (node not in self.visited_nodes): 96 self.position_history.append(node.position) 97 98 return successors
9class FoodSearchNode(pacai.core.search.SearchNode): 10 """ 11 A search node for the food search problem. 12 The state for this search problem will be 13 the current position and the remaining food positions. 14 """ 15 16 def __init__(self, 17 position: pacai.core.board.Position, 18 remaining_food: typing.Iterable[pacai.core.board.Position]) -> None: 19 self.position: pacai.core.board.Position = position 20 """ The current position being searched. """ 21 22 self.remaining_food: tuple[pacai.core.board.Position, ...] = tuple(sorted(list(remaining_food))) 23 """ 24 The food left to eat. 25 This is kept sorted to ensure that underlying comparison checks run cleanly. 26 """ 27 28 def __lt__(self, other: object) -> bool: 29 if (not isinstance(other, FoodSearchNode)): 30 return False 31 32 return ((self.position, self.remaining_food) < (other.position, other.remaining_food)) 33 34 def __eq__(self, other: object) -> bool: 35 if (not isinstance(other, FoodSearchNode)): 36 return False 37 38 return ((self.position == other.position) and (self.remaining_food == other.remaining_food)) 39 40 def __hash__(self) -> int: 41 return hash((self.position, self.remaining_food))
A search node for the food search problem. The state for this search problem will be the current position and the remaining food positions.
FoodSearchNode( position: pacai.core.board.Position, remaining_food: Iterable[pacai.core.board.Position])
16 def __init__(self, 17 position: pacai.core.board.Position, 18 remaining_food: typing.Iterable[pacai.core.board.Position]) -> None: 19 self.position: pacai.core.board.Position = position 20 """ The current position being searched. """ 21 22 self.remaining_food: tuple[pacai.core.board.Position, ...] = tuple(sorted(list(remaining_food))) 23 """ 24 The food left to eat. 25 This is kept sorted to ensure that underlying comparison checks run cleanly. 26 """
remaining_food: tuple[pacai.core.board.Position, ...]
The food left to eat. This is kept sorted to ensure that underlying comparison checks run cleanly.
43class FoodSearchProblem(pacai.core.search.SearchProblem[FoodSearchNode]): 44 """ 45 A search problem associated with finding the a path that collects all of the "food" in a game. 46 """ 47 48 def __init__(self, 49 game_state: pacai.core.gamestate.GameState, 50 start_position: pacai.core.board.Position | None = None, 51 **kwargs: typing.Any) -> None: 52 """ 53 Create a food search problem. 54 55 If no start position is provided, the current agent's position will be used. 56 """ 57 58 super().__init__() 59 60 self.state: pacai.core.gamestate.GameState = game_state 61 """ Keep track of the enire game state. """ 62 63 if (start_position is None): 64 start_position = game_state.get_agent_position() 65 66 if (start_position is None): 67 raise ValueError("Could not find starting position.") 68 69 self.start_position = start_position 70 """ The position to start from. """ 71 72 def get_starting_node(self) -> FoodSearchNode: 73 return FoodSearchNode(self.start_position, self.state.board.get_marker_positions(pacai.pacman.board.MARKER_PELLET)) 74 75 def is_goal_node(self, node: FoodSearchNode) -> bool: 76 return (len(node.remaining_food) == 0) 77 78 def complete(self, goal_node: FoodSearchNode) -> None: 79 # Mark the final node in the history. 80 self.position_history.append(goal_node.position) 81 82 def get_successor_nodes(self, node: FoodSearchNode) -> list[pacai.core.search.SuccessorInfo]: 83 successors = [] 84 85 # Check all the non-wall neighbors. 86 for (action, position) in self.state.board.get_neighbors(node.position): 87 new_remaining_food = list(node.remaining_food).copy() 88 if (position in new_remaining_food): 89 new_remaining_food.remove(position) 90 91 next_node = FoodSearchNode(position, new_remaining_food) 92 successors.append(pacai.core.search.SuccessorInfo(next_node, action, 1.0)) 93 94 # Do bookkeeping on the states/positions we visited. 95 self.expanded_node_count += 1 96 if (node not in self.visited_nodes): 97 self.position_history.append(node.position) 98 99 return successors
A search problem associated with finding the a path that collects all of the "food" in a game.
FoodSearchProblem( game_state: pacai.core.gamestate.GameState, start_position: pacai.core.board.Position | None = None, **kwargs: Any)
48 def __init__(self, 49 game_state: pacai.core.gamestate.GameState, 50 start_position: pacai.core.board.Position | None = None, 51 **kwargs: typing.Any) -> None: 52 """ 53 Create a food search problem. 54 55 If no start position is provided, the current agent's position will be used. 56 """ 57 58 super().__init__() 59 60 self.state: pacai.core.gamestate.GameState = game_state 61 """ Keep track of the enire game state. """ 62 63 if (start_position is None): 64 start_position = game_state.get_agent_position() 65 66 if (start_position is None): 67 raise ValueError("Could not find starting position.") 68 69 self.start_position = start_position 70 """ The position to start from. """
Create a food search problem.
If no start position is provided, the current agent's position will be used.
72 def get_starting_node(self) -> FoodSearchNode: 73 return FoodSearchNode(self.start_position, self.state.board.get_marker_positions(pacai.pacman.board.MARKER_PELLET))
Get the starting node for the search problem.
78 def complete(self, goal_node: FoodSearchNode) -> None: 79 # Mark the final node in the history. 80 self.position_history.append(goal_node.position)
Notify this search problem that the solver choose this goal node.
82 def get_successor_nodes(self, node: FoodSearchNode) -> list[pacai.core.search.SuccessorInfo]: 83 successors = [] 84 85 # Check all the non-wall neighbors. 86 for (action, position) in self.state.board.get_neighbors(node.position): 87 new_remaining_food = list(node.remaining_food).copy() 88 if (position in new_remaining_food): 89 new_remaining_food.remove(position) 90 91 next_node = FoodSearchNode(position, new_remaining_food) 92 successors.append(pacai.core.search.SuccessorInfo(next_node, action, 1.0)) 93 94 # Do bookkeeping on the states/positions we visited. 95 self.expanded_node_count += 1 96 if (node not in self.visited_nodes): 97 self.position_history.append(node.position) 98 99 return successors
Get all the possible successors (successor nodes) to the current node. This action can be though of expanding a search node, or getting the children of a node in the search tree.