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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
- # layout.py
- # ---------
- # Licensing Information: Please do not distribute or publish solutions to this
- # project. You are free to use and extend these projects for educational
- # purposes. The Pacman AI projects were developed at UC Berkeley, primarily by
- # John DeNero (denero@cs.berkeley.edu) and Dan Klein (klein@cs.berkeley.edu).
- # For more info, see http://inst.eecs.berkeley.edu/~cs188/sp09/pacman.html
- from utilities.util import manhattanDistance
- from utilities.game import Grid
- import os
- import random
- VISIBILITY_MATRIX_CACHE = {}
- class Layout:
- """
- A Layout manages the static information about the game board.
- """
- def __init__(self, layoutText):
- self.width = len(layoutText[0])
- self.height = len(layoutText)
- self.walls = Grid(self.width, self.height, False)
- self.food = Grid(self.width, self.height, False)
- self.capsules = []
- self.agentPositions = []
- self.numGhosts = 0
- self.processLayoutText(layoutText)
- self.layoutText = layoutText
- # self.initializeVisibilityMatrix()
- def getNumGhosts(self):
- return self.numGhosts
- def initializeVisibilityMatrix(self):
- global VISIBILITY_MATRIX_CACHE
- if reduce(str.__add__, self.layoutText) not in VISIBILITY_MATRIX_CACHE:
- from utilities.game import Directions
- vecs = [(-0.5, 0), (0.5, 0), (0, -0.5), (0, 0.5)]
- dirs = [Directions.NORTH, Directions.SOUTH, Directions.WEST, Directions.EAST]
- vis = Grid(self.width, self.height,
- {Directions.NORTH: set(), Directions.SOUTH: set(), Directions.EAST: set(),
- Directions.WEST: set(), Directions.STOP: set()})
- for x in range(self.width):
- for y in range(self.height):
- if self.walls[x][y] == False:
- for vec, direction in zip(vecs, dirs):
- dx, dy = vec
- nextx, nexty = x + dx, y + dy
- while (nextx + nexty) != int(nextx) + int(nexty) or not \
- self.walls[int(nextx)][int(nexty)]:
- vis[x][y][direction].add((nextx, nexty))
- nextx, nexty = x + dx, y + dy
- self.visibility = vis
- VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)] = vis
- else:
- self.visibility = VISIBILITY_MATRIX_CACHE[reduce(str.__add__, self.layoutText)]
- def isWall(self, pos):
- x, col = pos
- return self.walls[x][col]
- def getRandomLegalPosition(self):
- x = random.choice(range(self.width))
- y = random.choice(range(self.height))
- while self.isWall((x, y)):
- x = random.choice(range(self.width))
- y = random.choice(range(self.height))
- return (x, y)
- def getRandomCorner(self):
- poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1),
- (self.width - 2, self.height - 2)]
- return random.choice(poses)
- def getFurthestCorner(self, pacPos):
- poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1),
- (self.width - 2, self.height - 2)]
- dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses])
- return pos
- def isVisibleFrom(self, ghostPos, pacPos, pacDirection):
- row, col = [int(x) for x in pacPos]
- return ghostPos in self.visibility[row][col][pacDirection]
- def __str__(self):
- return "\n".join(self.layoutText)
- def deepCopy(self):
- return Layout(self.layoutText[:])
- def processLayoutText(self, layoutText):
- """
- Coordinates are flipped from the input format to the (x,y) convention here
-
- The shape of the maze. Each character
- represents a different type of object.
- % - Wall
- . - Food
- o - Capsule
- G - Ghost
- P - Pacman
- Other characters are ignored.
- """
- maxY = self.height - 1
- for y in range(self.height):
- for x in range(self.width):
- layoutChar = layoutText[maxY - y][x]
- self.processLayoutChar(x, y, layoutChar)
- self.agentPositions.sort()
- self.agentPositions = [(i == 0, pos) for i, pos in self.agentPositions]
- def processLayoutChar(self, x, y, layoutChar):
- if layoutChar == '%':
- self.walls[x][y] = True
- elif layoutChar == '.':
- self.food[x][y] = True
- elif layoutChar == 'o':
- self.capsules.append((x, y))
- elif layoutChar == 'P':
- self.agentPositions.append((0, (x, y)))
- elif layoutChar in ['G']:
- self.agentPositions.append((1, (x, y)))
- self.numGhosts += 1
- elif layoutChar in ['1', '2', '3', '4']:
- self.agentPositions.append((int(layoutChar), (x, y)))
- self.numGhosts += 1
- def getLayout(name, back=2):
- if name.endswith('.lay'):
- layout = tryToLoad('utilities/layouts/' + name)
- if layout == None: layout = tryToLoad(name)
- else:
- layout = tryToLoad('utilities/layouts/' + name + '.lay')
- if layout == None: layout = tryToLoad(name + '.lay')
- if layout == None and back >= 0:
- curdir = os.path.abspath('.')
- os.chdir('..')
- layout = getLayout(name, back - 1)
- os.chdir(curdir)
- return layout
- def tryToLoad(fullname):
- if (not os.path.exists(fullname)): return None
- f = open(fullname)
- try:
- return Layout([line.strip() for line in f])
- finally:
- f.close()
|