Module pacai.core.search.position
Expand source code
from pacai.core.actions import Actions
from pacai.core.directions import Directions
from pacai.core.search.problem import SearchProblem
DEFAULT_COST_FUNCTION = lambda x: 1
DEFAULT_GOAL_POSITION = (1, 1)
class PositionSearchProblem(SearchProblem):
"""
A `pacai.core.search.problem.SearchProblem` for finding a specific location on the board.
The state space consists of (x, y) positions.
Note that this search problem is fully specified and should be used as an example.
"""
def __init__(self, gameState, costFn = DEFAULT_COST_FUNCTION,
goal = DEFAULT_GOAL_POSITION, start = None):
"""
Args:
gameState: A `pacai.core.gamestate.AbstractGameState`.
costFn: A function from a search state (x, y) to a non-negative number.
goal: The target position.
"""
super().__init__()
self.walls = gameState.getWalls()
self.goal = goal
self.costFn = costFn
self.startState = start
if (self.startState is None):
self.startState = gameState.getAgentPosition(0)
if (self.startState is None):
raise ValueError("Could not find starting location.")
def startingState(self):
return self.startState
def isGoal(self, state):
if (state != self.goal):
return False
# Register the locations we have visited.
# This allows the GUI to highlight them.
self._visitedLocations.add(state)
# Note: visit history requires coordinates not states. In this situation
# they are equivalent.
coordinates = state
self._visitHistory.append(coordinates)
return True
def successorStates(self, state):
"""
Returns successor states, the actions they require, and a constant cost of 1.
"""
successors = []
for action in Directions.CARDINAL:
x, y = state
dx, dy = Actions.directionToVector(action)
nextx, nexty = int(x + dx), int(y + dy)
if (not self.walls[nextx][nexty]):
nextState = (nextx, nexty)
cost = self.costFn(nextState)
successors.append((nextState, action, cost))
# Bookkeeping for display purposes (the highlight in the GUI).
self._numExpanded += 1
if (state not in self._visitedLocations):
self._visitedLocations.add(state)
# Note: visit history requires coordinates not states. In this situation
# they are equivalent.
coordinates = state
self._visitHistory.append(coordinates)
return successors
def actionsCost(self, actions):
"""
Returns the cost of a particular sequence of actions.
If those actions include an illegal move, return 999999.
"""
if (actions is None):
return 999999
x, y = self.startingState()
cost = 0
for action in actions:
# Check figure out the next state and see whether its' legal
dx, dy = Actions.directionToVector(action)
x, y = int(x + dx), int(y + dy)
if (self.walls[x][y]):
return 999999
cost += self.costFn((x, y))
return cost
Functions
def DEFAULT_COST_FUNCTION(x)
-
Expand source code
DEFAULT_COST_FUNCTION = lambda x: 1
Classes
class PositionSearchProblem (gameState, costFn=
>, goal=(1, 1), start=None) -
A
SearchProblem
for finding a specific location on the board. The state space consists of (x, y) positions.Note that this search problem is fully specified and should be used as an example.
Args
gameState
- A
AbstractGameState
. costFn
- A function from a search state (x, y) to a non-negative number.
goal
- The target position.
Expand source code
class PositionSearchProblem(SearchProblem): """ A `pacai.core.search.problem.SearchProblem` for finding a specific location on the board. The state space consists of (x, y) positions. Note that this search problem is fully specified and should be used as an example. """ def __init__(self, gameState, costFn = DEFAULT_COST_FUNCTION, goal = DEFAULT_GOAL_POSITION, start = None): """ Args: gameState: A `pacai.core.gamestate.AbstractGameState`. costFn: A function from a search state (x, y) to a non-negative number. goal: The target position. """ super().__init__() self.walls = gameState.getWalls() self.goal = goal self.costFn = costFn self.startState = start if (self.startState is None): self.startState = gameState.getAgentPosition(0) if (self.startState is None): raise ValueError("Could not find starting location.") def startingState(self): return self.startState def isGoal(self, state): if (state != self.goal): return False # Register the locations we have visited. # This allows the GUI to highlight them. self._visitedLocations.add(state) # Note: visit history requires coordinates not states. In this situation # they are equivalent. coordinates = state self._visitHistory.append(coordinates) return True def successorStates(self, state): """ Returns successor states, the actions they require, and a constant cost of 1. """ successors = [] for action in Directions.CARDINAL: x, y = state dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) if (not self.walls[nextx][nexty]): nextState = (nextx, nexty) cost = self.costFn(nextState) successors.append((nextState, action, cost)) # Bookkeeping for display purposes (the highlight in the GUI). self._numExpanded += 1 if (state not in self._visitedLocations): self._visitedLocations.add(state) # Note: visit history requires coordinates not states. In this situation # they are equivalent. coordinates = state self._visitHistory.append(coordinates) return successors def actionsCost(self, actions): """ Returns the cost of a particular sequence of actions. If those actions include an illegal move, return 999999. """ if (actions is None): return 999999 x, y = self.startingState() cost = 0 for action in actions: # Check figure out the next state and see whether its' legal dx, dy = Actions.directionToVector(action) x, y = int(x + dx), int(y + dy) if (self.walls[x][y]): return 999999 cost += self.costFn((x, y)) return cost
Ancestors
- SearchProblem
- abc.ABC
Subclasses
Methods
def actionsCost(self, actions)
-
Returns the cost of a particular sequence of actions. If those actions include an illegal move, return 999999.
Expand source code
def actionsCost(self, actions): """ Returns the cost of a particular sequence of actions. If those actions include an illegal move, return 999999. """ if (actions is None): return 999999 x, y = self.startingState() cost = 0 for action in actions: # Check figure out the next state and see whether its' legal dx, dy = Actions.directionToVector(action) x, y = int(x + dx), int(y + dy) if (self.walls[x][y]): return 999999 cost += self.costFn((x, y)) return cost
def isGoal(self, state)
-
Inherited from:
SearchProblem
.isGoal
Answers the question: Is this state a goal? …
Expand source code
def isGoal(self, state): if (state != self.goal): return False # Register the locations we have visited. # This allows the GUI to highlight them. self._visitedLocations.add(state) # Note: visit history requires coordinates not states. In this situation # they are equivalent. coordinates = state self._visitHistory.append(coordinates) return True
def startingState(self)
-
Inherited from:
SearchProblem
.startingState
Answers the question: Where should the search start? …
Expand source code
def startingState(self): return self.startState
def successorStates(self, state)
-
Returns successor states, the actions they require, and a constant cost of 1.
Expand source code
def successorStates(self, state): """ Returns successor states, the actions they require, and a constant cost of 1. """ successors = [] for action in Directions.CARDINAL: x, y = state dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) if (not self.walls[nextx][nexty]): nextState = (nextx, nexty) cost = self.costFn(nextState) successors.append((nextState, action, cost)) # Bookkeeping for display purposes (the highlight in the GUI). self._numExpanded += 1 if (state not in self._visitedLocations): self._visitedLocations.add(state) # Note: visit history requires coordinates not states. In this situation # they are equivalent. coordinates = state self._visitHistory.append(coordinates) return successors