pacai.student.singlesearch
In this file, you will implement code relating to simple single-agent searches.
1""" 2In this file, you will implement code relating to simple single-agent searches. 3""" 4 5import random 6import typing 7 8import pacai.agents.searchproblem 9import pacai.core.agent 10import pacai.core.agentaction 11import pacai.core.board 12import pacai.core.gamestate 13import pacai.core.search 14import pacai.pacman.board 15import pacai.search.common 16import pacai.search.food 17import pacai.search.position 18 19def depth_first_search( 20 problem: pacai.core.search.SearchProblem, 21 heuristic: pacai.core.search.SearchHeuristic, 22 rng: random.Random, 23 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 24 """ 25 A pacai.core.search.SearchProblemSolver that implements depth first search (DFS). 26 This means that it will search the deepest nodes in the search tree first. 27 See: https://en.wikipedia.org/wiki/Depth-first_search . 28 """ 29 30 # *** Your Code Here *** 31 raise NotImplementedError('depth_first_search') 32 33def breadth_first_search( 34 problem: pacai.core.search.SearchProblem, 35 heuristic: pacai.core.search.SearchHeuristic, 36 rng: random.Random, 37 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 38 """ 39 A pacai.core.search.SearchProblemSolver that implements breadth first search (BFS). 40 This means that it will search nodes based on what level in search tree they appear. 41 See: https://en.wikipedia.org/wiki/Breadth-first_search . 42 """ 43 44 # *** Your Code Here *** 45 raise NotImplementedError('breadth_first_search') 46 47def uniform_cost_search( 48 problem: pacai.core.search.SearchProblem, 49 heuristic: pacai.core.search.SearchHeuristic, 50 rng: random.Random, 51 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 52 """ 53 A pacai.core.search.SearchProblemSolver that implements uniform cost search (UCS). 54 This means that it will search nodes with a lower total cost first. 55 See: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Practical_optimizations_and_infinite_graphs . 56 """ 57 58 # *** Your Code Here *** 59 raise NotImplementedError('uniform_cost_search') 60 61def astar_search( 62 problem: pacai.core.search.SearchProblem, 63 heuristic: pacai.core.search.SearchHeuristic, 64 rng: random.Random, 65 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 66 """ 67 A pacai.core.search.SearchProblemSolver that implements A* search (pronounced "A Star search"). 68 This means that it will search nodes with a lower combined cost and heuristic first. 69 See: https://en.wikipedia.org/wiki/A*_search_algorithm . 70 """ 71 72 # *** Your Code Here *** 73 raise NotImplementedError('astar_search') 74 75class CornersSearchNode(pacai.core.search.SearchNode): 76 """ 77 A search node the can be used to represent the corners search problem. 78 79 You get to implement this search node however you want. 80 """ 81 82 def __init__(self) -> None: 83 """ Construct a search node to help search for corners. """ 84 85 # *** Your Code Here *** 86 # Remember that you can also add argument to your constructor. 87 88class CornersSearchProblem(pacai.core.search.SearchProblem[CornersSearchNode]): 89 """ 90 A search problem for touching the four different corners in a board. 91 92 You may assume that very board is surrounded by walls (e.g., (0, 0) is a wall), 93 and that the position diagonally inside from the walled corner is the location we are looking for. 94 For example, if we had a square board that was 10x10, then we would be looking for the following corners: 95 - (1, 1) -- North-West / Upper Left 96 - (1, 8) -- North-East / Upper Right 97 - (8, 1) -- South-West / Lower Left 98 - (8, 8) -- South-East / Lower Right 99 """ 100 101 def __init__(self, 102 game_state: pacai.core.gamestate.GameState, 103 **kwargs: typing.Any) -> None: 104 super().__init__(**kwargs) 105 106 # *** Your Code Here *** 107 108 def get_starting_node(self) -> CornersSearchNode: 109 # *** Your Code Here *** 110 raise NotImplementedError('CornersSearchProblem.get_starting_node') 111 112 def is_goal_node(self, node: CornersSearchNode) -> bool: 113 # *** Your Code Here *** 114 raise NotImplementedError('CornersSearchProblem.is_goal_node') 115 116 def get_successor_nodes(self, node: CornersSearchNode) -> list[pacai.core.search.SuccessorInfo]: 117 # *** Your Code Here *** 118 raise NotImplementedError('CornersSearchProblem.get_successor_nodes') 119 120def corners_heuristic(node: CornersSearchNode, problem: CornersSearchProblem, **kwargs: typing.Any) -> float: 121 """ 122 A heuristic for CornersSearchProblem. 123 124 This function should always return a number that is a lower bound 125 on the shortest path from the state to a goal of the problem; 126 i.e. it should be admissible. 127 (You need not worry about consistency for this heuristic to receive full credit.) 128 """ 129 130 # *** Your Code Here *** 131 return pacai.search.common.null_heuristic(node, problem) # Default to a trivial solution. 132 133def food_heuristic(node: pacai.search.food.FoodSearchNode, problem: pacai.search.food.FoodSearchProblem, **kwargs: typing.Any) -> float: 134 """ 135 A heuristic for the FoodSearchProblem. 136 """ 137 138 # *** Your Code Here *** 139 return pacai.search.common.null_heuristic(node, problem) # Default to a trivial solution. 140 141class ClosestDotSearchAgent(pacai.agents.searchproblem.GreedySubproblemSearchAgent): 142 """ 143 Search for a path to all the food by greedily searching for the next closest food again and again 144 (util we have reached all the food). 145 146 This agent is left to you to fill out. 147 But make sure to take your time and think. 148 The final solution is quite simple if you take your time to understand everything up until this point and leverage 149 pacai.agents.searchproblem.GreedySubproblemSearchAgent and pacai.student.problem.AnyMarkerSearchProblem. 150 pacai.agents.searchproblem.GreedySubproblemSearchAgent is already implemented, 151 but you should take some time to understand it. 152 pacai.student.problem.AnyMarkerSearchProblem (below in this file) has not yet been implemented, 153 but is the quickest and easiest way to implement this class. 154 155 Hint: 156 Remember that you can call a parent class' `__init__()` method from a child class' `__init__()` method. 157 (See pacai.student.problem.AnyMarkerSearchProblem for an example.) 158 Child classes will generally always call their parent's `__init__()` method 159 (if a child class does not implement `__init__()`, then the parent's `__init__()` is automatically called). 160 This call does not need to be the first line in the method, 161 and you can pass whatever you want to the parent's `__init__()`. 162 """ 163 164 # *** Your Code Here *** 165 166class AnyMarkerSearchProblem(pacai.search.position.PositionSearchProblem): 167 """ 168 A search problem for finding a path to any instance of the specified board marker (e.g., food, wall, power capsule). 169 170 This search problem is just like the pacai.search.position.PositionSearchProblem, 171 but has a different goal test, which you need to fill in below. 172 You may modify the `__init__()` if you want, the other methods should be fine as-is. 173 """ 174 175 def __init__(self, 176 game_state: pacai.core.gamestate.GameState, 177 target_marker: pacai.core.board.Marker = pacai.pacman.board.MARKER_PELLET, 178 **kwargs: typing.Any) -> None: 179 super().__init__(game_state, **kwargs) 180 181 # *** Your Code Here *** 182 183 def is_goal_node(self, node: pacai.search.position.PositionSearchNode) -> bool: 184 # *** Your Code Here *** 185 raise NotImplementedError('CornersSearchProblem.is_goal_node') 186 187class ApproximateSearchAgent(pacai.core.agent.Agent): 188 """ 189 A search agent that tries to perform an approximate search instead of an exact one. 190 In other words, this agent is okay with a solution that is "good enough" and not necessarily optimal. 191 """
20def depth_first_search( 21 problem: pacai.core.search.SearchProblem, 22 heuristic: pacai.core.search.SearchHeuristic, 23 rng: random.Random, 24 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 25 """ 26 A pacai.core.search.SearchProblemSolver that implements depth first search (DFS). 27 This means that it will search the deepest nodes in the search tree first. 28 See: https://en.wikipedia.org/wiki/Depth-first_search . 29 """ 30 31 # *** Your Code Here *** 32 raise NotImplementedError('depth_first_search')
A pacai.core.search.SearchProblemSolver that implements depth first search (DFS). This means that it will search the deepest nodes in the search tree first. See: https://en.wikipedia.org/wiki/Depth-first_search .
34def breadth_first_search( 35 problem: pacai.core.search.SearchProblem, 36 heuristic: pacai.core.search.SearchHeuristic, 37 rng: random.Random, 38 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 39 """ 40 A pacai.core.search.SearchProblemSolver that implements breadth first search (BFS). 41 This means that it will search nodes based on what level in search tree they appear. 42 See: https://en.wikipedia.org/wiki/Breadth-first_search . 43 """ 44 45 # *** Your Code Here *** 46 raise NotImplementedError('breadth_first_search')
A pacai.core.search.SearchProblemSolver that implements breadth first search (BFS). This means that it will search nodes based on what level in search tree they appear. See: https://en.wikipedia.org/wiki/Breadth-first_search .
48def uniform_cost_search( 49 problem: pacai.core.search.SearchProblem, 50 heuristic: pacai.core.search.SearchHeuristic, 51 rng: random.Random, 52 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 53 """ 54 A pacai.core.search.SearchProblemSolver that implements uniform cost search (UCS). 55 This means that it will search nodes with a lower total cost first. 56 See: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Practical_optimizations_and_infinite_graphs . 57 """ 58 59 # *** Your Code Here *** 60 raise NotImplementedError('uniform_cost_search')
A pacai.core.search.SearchProblemSolver that implements uniform cost search (UCS). This means that it will search nodes with a lower total cost first. See: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Practical_optimizations_and_infinite_graphs .
62def astar_search( 63 problem: pacai.core.search.SearchProblem, 64 heuristic: pacai.core.search.SearchHeuristic, 65 rng: random.Random, 66 **kwargs: typing.Any) -> pacai.core.search.SearchSolution: 67 """ 68 A pacai.core.search.SearchProblemSolver that implements A* search (pronounced "A Star search"). 69 This means that it will search nodes with a lower combined cost and heuristic first. 70 See: https://en.wikipedia.org/wiki/A*_search_algorithm . 71 """ 72 73 # *** Your Code Here *** 74 raise NotImplementedError('astar_search')
A pacai.core.search.SearchProblemSolver that implements A* search (pronounced "A Star search"). This means that it will search nodes with a lower combined cost and heuristic first. See: https://en.wikipedia.org/wiki/A*_search_algorithm .
76class CornersSearchNode(pacai.core.search.SearchNode): 77 """ 78 A search node the can be used to represent the corners search problem. 79 80 You get to implement this search node however you want. 81 """ 82 83 def __init__(self) -> None: 84 """ Construct a search node to help search for corners. """ 85 86 # *** Your Code Here *** 87 # Remember that you can also add argument to your constructor.
A search node the can be used to represent the corners search problem.
You get to implement this search node however you want.
89class CornersSearchProblem(pacai.core.search.SearchProblem[CornersSearchNode]): 90 """ 91 A search problem for touching the four different corners in a board. 92 93 You may assume that very board is surrounded by walls (e.g., (0, 0) is a wall), 94 and that the position diagonally inside from the walled corner is the location we are looking for. 95 For example, if we had a square board that was 10x10, then we would be looking for the following corners: 96 - (1, 1) -- North-West / Upper Left 97 - (1, 8) -- North-East / Upper Right 98 - (8, 1) -- South-West / Lower Left 99 - (8, 8) -- South-East / Lower Right 100 """ 101 102 def __init__(self, 103 game_state: pacai.core.gamestate.GameState, 104 **kwargs: typing.Any) -> None: 105 super().__init__(**kwargs) 106 107 # *** Your Code Here *** 108 109 def get_starting_node(self) -> CornersSearchNode: 110 # *** Your Code Here *** 111 raise NotImplementedError('CornersSearchProblem.get_starting_node') 112 113 def is_goal_node(self, node: CornersSearchNode) -> bool: 114 # *** Your Code Here *** 115 raise NotImplementedError('CornersSearchProblem.is_goal_node') 116 117 def get_successor_nodes(self, node: CornersSearchNode) -> list[pacai.core.search.SuccessorInfo]: 118 # *** Your Code Here *** 119 raise NotImplementedError('CornersSearchProblem.get_successor_nodes')
A search problem for touching the four different corners in a board.
You may assume that very board is surrounded by walls (e.g., (0, 0) is a wall), and that the position diagonally inside from the walled corner is the location we are looking for. For example, if we had a square board that was 10x10, then we would be looking for the following corners:
- (1, 1) -- North-West / Upper Left
- (1, 8) -- North-East / Upper Right
- (8, 1) -- South-West / Lower Left
- (8, 8) -- South-East / Lower Right
109 def get_starting_node(self) -> CornersSearchNode: 110 # *** Your Code Here *** 111 raise NotImplementedError('CornersSearchProblem.get_starting_node')
Get the starting node for the search problem.
113 def is_goal_node(self, node: CornersSearchNode) -> bool: 114 # *** Your Code Here *** 115 raise NotImplementedError('CornersSearchProblem.is_goal_node')
Check if this node is a valid goal node.
117 def get_successor_nodes(self, node: CornersSearchNode) -> list[pacai.core.search.SuccessorInfo]: 118 # *** Your Code Here *** 119 raise NotImplementedError('CornersSearchProblem.get_successor_nodes')
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.
Inherited Members
121def corners_heuristic(node: CornersSearchNode, problem: CornersSearchProblem, **kwargs: typing.Any) -> float: 122 """ 123 A heuristic for CornersSearchProblem. 124 125 This function should always return a number that is a lower bound 126 on the shortest path from the state to a goal of the problem; 127 i.e. it should be admissible. 128 (You need not worry about consistency for this heuristic to receive full credit.) 129 """ 130 131 # *** Your Code Here *** 132 return pacai.search.common.null_heuristic(node, problem) # Default to a trivial solution.
A heuristic for CornersSearchProblem.
This function should always return a number that is a lower bound on the shortest path from the state to a goal of the problem; i.e. it should be admissible. (You need not worry about consistency for this heuristic to receive full credit.)
134def food_heuristic(node: pacai.search.food.FoodSearchNode, problem: pacai.search.food.FoodSearchProblem, **kwargs: typing.Any) -> float: 135 """ 136 A heuristic for the FoodSearchProblem. 137 """ 138 139 # *** Your Code Here *** 140 return pacai.search.common.null_heuristic(node, problem) # Default to a trivial solution.
A heuristic for the FoodSearchProblem.
142class ClosestDotSearchAgent(pacai.agents.searchproblem.GreedySubproblemSearchAgent): 143 """ 144 Search for a path to all the food by greedily searching for the next closest food again and again 145 (util we have reached all the food). 146 147 This agent is left to you to fill out. 148 But make sure to take your time and think. 149 The final solution is quite simple if you take your time to understand everything up until this point and leverage 150 pacai.agents.searchproblem.GreedySubproblemSearchAgent and pacai.student.problem.AnyMarkerSearchProblem. 151 pacai.agents.searchproblem.GreedySubproblemSearchAgent is already implemented, 152 but you should take some time to understand it. 153 pacai.student.problem.AnyMarkerSearchProblem (below in this file) has not yet been implemented, 154 but is the quickest and easiest way to implement this class. 155 156 Hint: 157 Remember that you can call a parent class' `__init__()` method from a child class' `__init__()` method. 158 (See pacai.student.problem.AnyMarkerSearchProblem for an example.) 159 Child classes will generally always call their parent's `__init__()` method 160 (if a child class does not implement `__init__()`, then the parent's `__init__()` is automatically called). 161 This call does not need to be the first line in the method, 162 and you can pass whatever you want to the parent's `__init__()`. 163 """ 164 165 # *** Your Code Here ***
Search for a path to all the food by greedily searching for the next closest food again and again (util we have reached all the food).
This agent is left to you to fill out. But make sure to take your time and think. The final solution is quite simple if you take your time to understand everything up until this point and leverage pacai.agents.searchproblem.GreedySubproblemSearchAgent and pacai.student.problem.AnyMarkerSearchProblem. pacai.agents.searchproblem.GreedySubproblemSearchAgent is already implemented, but you should take some time to understand it. pacai.student.problem.AnyMarkerSearchProblem (below in this file) has not yet been implemented, but is the quickest and easiest way to implement this class.
Hint:
Remember that you can call a parent class' __init__() method from a child class' __init__() method.
(See pacai.student.problem.AnyMarkerSearchProblem for an example.)
Child classes will generally always call their parent's __init__() method
(if a child class does not implement __init__(), then the parent's __init__() is automatically called).
This call does not need to be the first line in the method,
and you can pass whatever you want to the parent's __init__().
Inherited Members
167class AnyMarkerSearchProblem(pacai.search.position.PositionSearchProblem): 168 """ 169 A search problem for finding a path to any instance of the specified board marker (e.g., food, wall, power capsule). 170 171 This search problem is just like the pacai.search.position.PositionSearchProblem, 172 but has a different goal test, which you need to fill in below. 173 You may modify the `__init__()` if you want, the other methods should be fine as-is. 174 """ 175 176 def __init__(self, 177 game_state: pacai.core.gamestate.GameState, 178 target_marker: pacai.core.board.Marker = pacai.pacman.board.MARKER_PELLET, 179 **kwargs: typing.Any) -> None: 180 super().__init__(game_state, **kwargs) 181 182 # *** Your Code Here *** 183 184 def is_goal_node(self, node: pacai.search.position.PositionSearchNode) -> bool: 185 # *** Your Code Here *** 186 raise NotImplementedError('CornersSearchProblem.is_goal_node')
A search problem for finding a path to any instance of the specified board marker (e.g., food, wall, power capsule).
This search problem is just like the pacai.search.position.PositionSearchProblem,
but has a different goal test, which you need to fill in below.
You may modify the __init__() if you want, the other methods should be fine as-is.
176 def __init__(self, 177 game_state: pacai.core.gamestate.GameState, 178 target_marker: pacai.core.board.Marker = pacai.pacman.board.MARKER_PELLET, 179 **kwargs: typing.Any) -> None: 180 super().__init__(game_state, **kwargs) 181 182 # *** Your Code Here ***
Create a positional search problem.
If no goal position is provided, the board's search target will be used, if that does not exist, then DEFAULT_GOAL_POSITION will be used. If no start position is provided, the current agent's position will be used. If no cost function is provided, pacai.util.alias.COST_FUNC_UNIT will be used.
188class ApproximateSearchAgent(pacai.core.agent.Agent): 189 """ 190 A search agent that tries to perform an approximate search instead of an exact one. 191 In other words, this agent is okay with a solution that is "good enough" and not necessarily optimal. 192 """
A search agent that tries to perform an approximate search instead of an exact one. In other words, this agent is okay with a solution that is "good enough" and not necessarily optimal.