Module pacai.agents.search.base

Classes

class SearchAgent (index,
fn: str | Callable[[SearchProblem], ] = <function depthFirstSearch>,
prob: str | Callable[[AbstractGameState], SearchProblem] = pacai.core.search.position.PositionSearchProblem,
heuristic: str | Callable = <function null>,
**kwargs)
Expand source code
class SearchAgent(BaseAgent):
    """
    A general search agent that finds a path using a supplied search algorithm for a
    supplied search problem,
    then returns actions to follow that path.

    As a default, this agent runs `pacai.student.search.depthFirstSearch` on a
    `pacai.core.search.position.PositionSearchProblem` to find location (1, 1).
    """

    def __init__(self, index,
            fn: Union[str, Callable[[SearchProblem], any]] = depthFirstSearch,
            prob: Union[str, Callable[[AbstractGameState], SearchProblem]] = PositionSearchProblem,
            heuristic: Union[str, Callable] = nullHeuristic,
            **kwargs):
        super().__init__(index, **kwargs)

        if isinstance(prob, str):
            # Get the search problem type from the name.
            self.searchType = reflection.qualifiedImport(prob)
        else:
            # Use provided problem or problem factory.
            self.searchType = prob
        logging.info('[SearchAgent] using problem type %s.' % (self.searchType))

        if isinstance(fn, str):
            # Get the search function from the name and heuristic.
            self.searchFunction = self._fetchSearchFunction(fn, heuristic)
        else:
            # Use provided search function and ignore heuristic.
            self.searchFunction = fn
        logging.info('[SearchAgent] using function %s.' % (self.searchFunction))

        # The actions the search produced.
        self._actions = []

        # The currentl action (from self._actions) that the agent is performing.
        self._actionIndex = 0

    def registerInitialState(self, state):
        """
        This is the first time that the agent sees the layout of the game board.
        Here, we choose a path to the goal.
        In this phase, the agent should compute the path to the goal
        and store it in a local variable.
        All of the work is done in this method!
        """

        if (self.searchFunction is None):
            raise Exception('No search function provided for SearchAgent.')

        starttime = time.time()
        problem = self.searchType(state)  # Makes a new search problem.

        self._actions = self.searchFunction(problem)  # Find a path.
        self._actionIndex = 0

        totalCost = problem.actionsCost(self._actions)

        state.setHighlightLocations(problem.getVisitHistory())

        logging.info('Path found with total cost of %d in %.1f seconds' %
                (totalCost, time.time() - starttime))

        logging.info('Search nodes expanded: %d' % problem.getExpandedCount())

    def getAction(self, state):
        """
        Returns the next action in the path chosen earlier (in registerInitialState).
        Return Directions.STOP if there is no further action to take.
        """

        if (self._actionIndex >= (len(self._actions))):
            return Directions.STOP

        action = self._actions[self._actionIndex]
        self._actionIndex += 1

        return action

    def _fetchSearchFunction(self, functionName: str, heuristic: Union[str, Callable]):
        """
        Get the specified search function by name.
        If that function also takes a heurisitc (i.e. has a parameter called "heuristic"),
        then return a lambda that binds the heuristic to the function.
        """

        # Locate the function.
        function = reflection.qualifiedImport(functionName)

        # Check if the function has a heuristic.
        if 'heuristic' not in function.__code__.co_varnames:
            logging.info('[SearchAgent] using function %s.' % (functionName))
            return function

        if isinstance(heuristic, str):
            # Fetch the heuristic.
            heuristic = reflection.qualifiedImport(heuristic)
        logging.info('[SearchAgent] using function %s and heuristic %s.' %
                (functionName, heuristic))

        # Bind the heuristic.
        return lambda x: function(x, heuristic = heuristic)

A general search agent that finds a path using a supplied search algorithm for a supplied search problem, then returns actions to follow that path.

As a default, this agent runs depthFirstSearch() on a PositionSearchProblem to find location (1, 1).

Ancestors

Subclasses

Static methods

def loadAgent(name, index, args={})

Inherited from: BaseAgent.loadAgent

Load an agent with the given class name. The name can be fully qualified or just the bare class name. If the bare name is given, the class should …

Methods

def final(self, state)

Inherited from: BaseAgent.final

Inform the agent about the result of a game.

def getAction(self, state)
Expand source code
def getAction(self, state):
    """
    Returns the next action in the path chosen earlier (in registerInitialState).
    Return Directions.STOP if there is no further action to take.
    """

    if (self._actionIndex >= (len(self._actions))):
        return Directions.STOP

    action = self._actions[self._actionIndex]
    self._actionIndex += 1

    return action

Returns the next action in the path chosen earlier (in registerInitialState). Return Directions.STOP if there is no further action to take.

def observationFunction(self, state)

Inherited from: BaseAgent.observationFunction

Make an observation on the state of the game. Called once for each round of the game.

def registerInitialState(self, state)
Expand source code
def registerInitialState(self, state):
    """
    This is the first time that the agent sees the layout of the game board.
    Here, we choose a path to the goal.
    In this phase, the agent should compute the path to the goal
    and store it in a local variable.
    All of the work is done in this method!
    """

    if (self.searchFunction is None):
        raise Exception('No search function provided for SearchAgent.')

    starttime = time.time()
    problem = self.searchType(state)  # Makes a new search problem.

    self._actions = self.searchFunction(problem)  # Find a path.
    self._actionIndex = 0

    totalCost = problem.actionsCost(self._actions)

    state.setHighlightLocations(problem.getVisitHistory())

    logging.info('Path found with total cost of %d in %.1f seconds' %
            (totalCost, time.time() - starttime))

    logging.info('Search nodes expanded: %d' % problem.getExpandedCount())

This is the first time that the agent sees the layout of the game board. Here, we choose a path to the goal. In this phase, the agent should compute the path to the goal and store it in a local variable. All of the work is done in this method!