-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathghost.py
63 lines (58 loc) · 2.17 KB
/
ghost.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
from util import *
class Ghost:
def __init__(self, y=0, x=0):
self.y = y
self.x = x
def random_cand(self, state):
cand_pos = []
if state[self.y - 1][self.x] != WALL:
cand_pos.append((self.y - 1, self.x))
if state[self.y][self.x - 1] != WALL:
cand_pos.append((self.y, self.x - 1))
if state[self.y][self.x + 1] != WALL:
cand_pos.append((self.y, self.x + 1))
if state[self.y + 1][self.x] != WALL:
cand_pos.append((self.y + 1, self.x))
return cand_pos
def follow_cand(self, state):
cand_pos = []
top = self.bfs(state, self.y - 1, self.x)
left = self.bfs(state, self.y, self.x - 1)
right = self.bfs(state, self.y, self.x + 1)
bottom = self.bfs(state, self.y + 1, self.x)
if top <= left and top <= right and top <= bottom:
cand_pos.append((self.y - 1, self.x))
elif left <= top and left <= right and left <= bottom:
cand_pos.append((self.y, self.x - 1))
elif right <= top and right <= left and right <= bottom:
cand_pos.append((self.y, self.x + 1))
else:
cand_pos.append((self.y + 1, self.x))
return cand_pos
def next_pos(self, state):
if self.bfs(state, self.y, self.x) < 4:
cand_pos = self.follow_cand(state)
else:
cand_pos = self.random_cand(state)
return random.choice(cand_pos)
def bfs(self, state, y, x):
if state[y][x] == WALL:
return 99999
visit = set()
q = deque([(y, x, 0)])
while len(q) > 0:
y, x, size = q.popleft()
if (y, x) in visit:
continue
visit.add((y, x))
if state[y][x] in [USER, PUSER]:
return size
if state[y - 1][x] != WALL:
q.append((y - 1, x, size + 1))
if state[y][x - 1] != WALL:
q.append((y, x - 1, size + 1))
if state[y][x + 1] != WALL:
q.append((y, x + 1, size + 1))
if state[y + 1][x] != WALL:
q.append((y + 1, x, size + 1))
return 99999