forked from applied-ai-collective/Pacman-Deep-Q-Network
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ghostAgents.py
94 lines (76 loc) · 3.09 KB
/
ghostAgents.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# ghostAgents.py
# --------------
# Licensing Information: You are free to use or extend these projects for
# educational purposes provided that (1) you do not distribute or publish
# solutions, (2) you retain this notice, and (3) you provide clear
# attribution to UC Berkeley, including a link to http://ai.berkeley.edu.
#
# Attribution Information: The Pacman AI projects were developed at UC Berkeley.
# The core projects and autograders were primarily created by John DeNero
# ([email protected]) and Dan Klein ([email protected]).
# Student side autograding was added by Brad Miller, Nick Hay, and
# Pieter Abbeel ([email protected]).
from game import Agent
from game import Actions
from game import Directions
import random
from util import manhattanDistance
import util
class GhostAgent(Agent):
def __init__(self, index):
self.index = index
def getAction(self, state):
dist = self.getDistribution(state)
if len(dist) == 0:
return Directions.STOP
else:
return util.chooseFromDistribution(dist)
def getDistribution(self, state):
"Returns a Counter encoding a distribution over actions from the provided state."
util.raiseNotDefined()
class RandomGhost(GhostAgent):
"A ghost that chooses a legal action uniformly at random."
def getDistribution(self, state):
dist = util.Counter()
for a in state.getLegalActions(self.index):
dist[a] = 1.0
dist.normalize()
return dist
class DirectionalGhost(GhostAgent):
"A ghost that prefers to rush Pacman, or flee when scared."
def __init__(self, index, prob_attack=0.8, prob_scaredFlee=0.8):
self.index = index
self.prob_attack = prob_attack
self.prob_scaredFlee = prob_scaredFlee
def getDistribution(self, state):
# Read variables from state
ghostState = state.getGhostState(self.index)
legalActions = state.getLegalActions(self.index)
pos = state.getGhostPosition(self.index)
isScared = ghostState.scaredTimer > 0
speed = 1
if isScared:
speed = 0.5
actionVectors = [Actions.directionToVector(
a, speed) for a in legalActions]
newPositions = [(pos[0] + a[0], pos[1] + a[1]) for a in actionVectors]
pacmanPosition = state.getPacmanPosition()
# Select best actions given the state
distancesToPacman = [manhattanDistance(
pos, pacmanPosition) for pos in newPositions]
if isScared:
bestScore = max(distancesToPacman)
bestProb = self.prob_scaredFlee
else:
bestScore = min(distancesToPacman)
bestProb = self.prob_attack
bestActions = [action for action, distance in zip(
legalActions, distancesToPacman) if distance == bestScore]
# Construct distribution
dist = util.Counter()
for a in bestActions:
dist[a] = bestProb / len(bestActions)
for a in legalActions:
dist[a] += (1 - bestProb) / len(legalActions)
dist.normalize()
return dist