pacai.agents.greedy

 1import typing
 2
 3import pacai.core.action
 4import pacai.core.agent
 5import pacai.core.gamestate
 6import pacai.core.features
 7import pacai.util.alias
 8import pacai.util.reflection
 9
10class GreedyAgent(pacai.core.agent.Agent):
11    """
12    An agent that greedily takes the available move with the best score at the time.
13    If multiple moves have the same score, this agent will just randomly choose between them.
14    """
15
16    def get_action(self, state: pacai.core.gamestate.GameState) -> pacai.core.action.Action:
17        legal_actions = state.get_legal_actions()
18        if (len(legal_actions) == 1):
19            return legal_actions[0]
20
21        # Don't consider stopping unless we can do nothing else.
22        if (pacai.core.action.STOP in legal_actions):
23            legal_actions.remove(pacai.core.action.STOP)
24
25        successors = [(state.generate_successor(action, self.rng), action) for action in legal_actions]
26        scores = [(self.evaluate_state(successor, action = action), action) for (successor, action) in successors]
27
28        best_score = max(scores)[0]
29        best_actions = [pair[1] for pair in scores if pair[0] == best_score]
30
31        return self.rng.choice(best_actions)
32
33class GreedyFeatureAgent(GreedyAgent):
34    """
35    A greedy agent that uses weights and features to evaluate game states.
36    Note that the states will already be successors.
37
38    Children should set weights in the constructor,
39    missing weights will be assumed to be 1.0.
40    To compute custom features, children should either override compute_features()
41    or pass in a pacai.core.features.FeatureExtractor on construction.
42    """
43
44    def __init__(self,
45            feature_extractor_func: pacai.core.features.FeatureExtractor | pacai.util.reflection.Reference | str =
46                    pacai.core.features.score_feature_extractor,
47            **kwargs: typing.Any) -> None:
48        super().__init__(**kwargs)
49
50        self.weights: pacai.core.features.WeightDict = pacai.core.features.WeightDict()
51        """ The feature weights. """
52
53        clean_feature_extractor_func = pacai.util.reflection.resolve_and_fetch(pacai.core.features.FeatureExtractor, feature_extractor_func)
54        self.feature_extractor_func: pacai.core.features.FeatureExtractor = clean_feature_extractor_func
55        """ The feature extractor that will be used to get features from a state. """
56
57    def evaluate_state(self,
58            state: pacai.core.gamestate.GameState,
59            action: pacai.core.action.Action | None = None,
60            **kwargs: typing.Any) -> float:
61        if (action is None):
62            action = pacai.core.action.STOP
63
64        features = self.compute_features(state, action)
65
66        score = 0.0
67        for key, value in features.items():
68            score += (self.weights.get(key, 0.0) * value)
69
70        return score
71
72    def compute_features(self,
73            state: pacai.core.gamestate.GameState,
74            action: pacai.core.action.Action,
75            ) -> pacai.core.features.FeatureDict:
76        """
77        Compute the features to use for the given state/action pair.
78        By default, the passed in feature extractor function will be used.
79        """
80
81        return self.feature_extractor_func(state, action, agent = self)
class GreedyAgent(pacai.core.agent.Agent):
11class GreedyAgent(pacai.core.agent.Agent):
12    """
13    An agent that greedily takes the available move with the best score at the time.
14    If multiple moves have the same score, this agent will just randomly choose between them.
15    """
16
17    def get_action(self, state: pacai.core.gamestate.GameState) -> pacai.core.action.Action:
18        legal_actions = state.get_legal_actions()
19        if (len(legal_actions) == 1):
20            return legal_actions[0]
21
22        # Don't consider stopping unless we can do nothing else.
23        if (pacai.core.action.STOP in legal_actions):
24            legal_actions.remove(pacai.core.action.STOP)
25
26        successors = [(state.generate_successor(action, self.rng), action) for action in legal_actions]
27        scores = [(self.evaluate_state(successor, action = action), action) for (successor, action) in successors]
28
29        best_score = max(scores)[0]
30        best_actions = [pair[1] for pair in scores if pair[0] == best_score]
31
32        return self.rng.choice(best_actions)

An agent that greedily takes the available move with the best score at the time. If multiple moves have the same score, this agent will just randomly choose between them.

def get_action(self, state: pacai.core.gamestate.GameState) -> pacai.core.action.Action:
17    def get_action(self, state: pacai.core.gamestate.GameState) -> pacai.core.action.Action:
18        legal_actions = state.get_legal_actions()
19        if (len(legal_actions) == 1):
20            return legal_actions[0]
21
22        # Don't consider stopping unless we can do nothing else.
23        if (pacai.core.action.STOP in legal_actions):
24            legal_actions.remove(pacai.core.action.STOP)
25
26        successors = [(state.generate_successor(action, self.rng), action) for action in legal_actions]
27        scores = [(self.evaluate_state(successor, action = action), action) for (successor, action) in successors]
28
29        best_score = max(scores)[0]
30        best_actions = [pair[1] for pair in scores if pair[0] == best_score]
31
32        return self.rng.choice(best_actions)

Get an action for this agent given the current state of the game. This is simplified version of get_action_full(), see that method for full details.

class GreedyFeatureAgent(GreedyAgent):
34class GreedyFeatureAgent(GreedyAgent):
35    """
36    A greedy agent that uses weights and features to evaluate game states.
37    Note that the states will already be successors.
38
39    Children should set weights in the constructor,
40    missing weights will be assumed to be 1.0.
41    To compute custom features, children should either override compute_features()
42    or pass in a pacai.core.features.FeatureExtractor on construction.
43    """
44
45    def __init__(self,
46            feature_extractor_func: pacai.core.features.FeatureExtractor | pacai.util.reflection.Reference | str =
47                    pacai.core.features.score_feature_extractor,
48            **kwargs: typing.Any) -> None:
49        super().__init__(**kwargs)
50
51        self.weights: pacai.core.features.WeightDict = pacai.core.features.WeightDict()
52        """ The feature weights. """
53
54        clean_feature_extractor_func = pacai.util.reflection.resolve_and_fetch(pacai.core.features.FeatureExtractor, feature_extractor_func)
55        self.feature_extractor_func: pacai.core.features.FeatureExtractor = clean_feature_extractor_func
56        """ The feature extractor that will be used to get features from a state. """
57
58    def evaluate_state(self,
59            state: pacai.core.gamestate.GameState,
60            action: pacai.core.action.Action | None = None,
61            **kwargs: typing.Any) -> float:
62        if (action is None):
63            action = pacai.core.action.STOP
64
65        features = self.compute_features(state, action)
66
67        score = 0.0
68        for key, value in features.items():
69            score += (self.weights.get(key, 0.0) * value)
70
71        return score
72
73    def compute_features(self,
74            state: pacai.core.gamestate.GameState,
75            action: pacai.core.action.Action,
76            ) -> pacai.core.features.FeatureDict:
77        """
78        Compute the features to use for the given state/action pair.
79        By default, the passed in feature extractor function will be used.
80        """
81
82        return self.feature_extractor_func(state, action, agent = self)

A greedy agent that uses weights and features to evaluate game states. Note that the states will already be successors.

Children should set weights in the constructor, missing weights will be assumed to be 1.0. To compute custom features, children should either override compute_features() or pass in a pacai.core.features.FeatureExtractor on construction.

GreedyFeatureAgent( feature_extractor_func: pacai.core.features.FeatureExtractor | pacai.util.reflection.Reference | str = <function score_feature_extractor>, **kwargs: Any)
45    def __init__(self,
46            feature_extractor_func: pacai.core.features.FeatureExtractor | pacai.util.reflection.Reference | str =
47                    pacai.core.features.score_feature_extractor,
48            **kwargs: typing.Any) -> None:
49        super().__init__(**kwargs)
50
51        self.weights: pacai.core.features.WeightDict = pacai.core.features.WeightDict()
52        """ The feature weights. """
53
54        clean_feature_extractor_func = pacai.util.reflection.resolve_and_fetch(pacai.core.features.FeatureExtractor, feature_extractor_func)
55        self.feature_extractor_func: pacai.core.features.FeatureExtractor = clean_feature_extractor_func
56        """ The feature extractor that will be used to get features from a state. """
weights: dict[str, float]

The feature weights.

feature_extractor_func: pacai.core.features.FeatureExtractor

The feature extractor that will be used to get features from a state.

def evaluate_state( self, state: pacai.core.gamestate.GameState, action: pacai.core.action.Action | None = None, **kwargs: Any) -> float:
58    def evaluate_state(self,
59            state: pacai.core.gamestate.GameState,
60            action: pacai.core.action.Action | None = None,
61            **kwargs: typing.Any) -> float:
62        if (action is None):
63            action = pacai.core.action.STOP
64
65        features = self.compute_features(state, action)
66
67        score = 0.0
68        for key, value in features.items():
69            score += (self.weights.get(key, 0.0) * value)
70
71        return score

Evaluate the state to get a decide how good an action was. The base implementation for this function just calls self.evaluation_function, but child classes may override this method to easily implement their own evaluations.

def compute_features( self, state: pacai.core.gamestate.GameState, action: pacai.core.action.Action) -> dict[str, float]:
73    def compute_features(self,
74            state: pacai.core.gamestate.GameState,
75            action: pacai.core.action.Action,
76            ) -> pacai.core.features.FeatureDict:
77        """
78        Compute the features to use for the given state/action pair.
79        By default, the passed in feature extractor function will be used.
80        """
81
82        return self.feature_extractor_func(state, action, agent = self)

Compute the features to use for the given state/action pair. By default, the passed in feature extractor function will be used.