-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGhost.py
More file actions
119 lines (105 loc) · 5.06 KB
/
Ghost.py
File metadata and controls
119 lines (105 loc) · 5.06 KB
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
import copy as copy
from random import randint
class Ghost(object):
# Constructor
def __init__(self, respawn):
self.onDot = False
self.location = respawn
self.respawn = respawn
# Returns variable actions the Ghost has
def actions(self, board):
actions = []
ghostX = self.location[0]
ghostY = self.location[1]
# Check up
if (board.board[ghostX - 1][ghostY] != '=') & (board.board[ghostX - 1][ghostY] != '|'):
actions.append("up")
# Check down
if (board.board[ghostX + 1][ghostY] != '=') & (board.board[ghostX + 1][ghostY] != '|'):
actions.append("down")
# Check left
if (board.board[ghostX][ghostY - 1] != '|') & (board.board[ghostX][ghostY - 1] != '='):
actions.append("left")
# Check right
if (board.board[ghostX][ghostY + 1] != '|') & (board.board[ghostX][ghostY + 1] != '='):
actions.append("right")
return actions
# Returns a tuple containing (state after an action is taken,
def takeAction(self, board, action):
# Get location of new position after action is taken
if action == 'up':
# check for teleportation
if board[(self.location[0] - 1, self.location[1])] == 't':
board.move(self, board.height - 2, self.location[1])
else:
board.move(self, self.location[0] - 1, self.location[1])
elif action == 'down':
# check for teleportation
if board[(self.location[0] + 1, self.location[1])] == 't':
board.move(self, 1, self.location[1])
else:
board.move(self, self.location[0] + 1, self.location[1])
elif action == 'left':
# check for teleportation
if board[(self.location[0], self.location[1] - 1)] == 't':
board.move(self, self.location[0], board.length - 2)
else:
board.move(self, self.location[0], self.location[1] - 1)
elif action == 'right':
# check for teleportation
if board[(self.location[0], self.location[1] + 1)] == 't':
board.move(self, self.location[0], 1)
else:
board.move(self, self.location[0], self.location[1] + 1)
# Causes the ghost to perform a random move every turn
def randomMove(self, board):
moves = Ghost.actions(self, board)
move = moves[randint(0, len(self.actions(board)) - 1)]
return self.takeAction(board, move)
# Returns the move that takes Ghost closest to Pacman
def takeActionShortestDistance(self, board, locOfPacman):
#Positive means we want to move Right
xDiff = locOfPacman[1] - self.location[1]
#Positive means we want to move Down
yDiff = locOfPacman[0] - self.location[0]
for action in Ghost.actions(self,board):
if (action == 'up') & (yDiff < 0):
return Ghost.takeAction(self, board, action)
if (action == 'left') & (xDiff < 0):
return Ghost.takeAction(self, board, action)
if (action == 'down') & (yDiff > 0):
return Ghost.takeAction(self, board, action)
if (action == 'right') & (xDiff > 0):
return Ghost.takeAction(self, board, action)
return Ghost.randomMove(self, board)
# Helps Intelligent Move in finding the best direction to take to get to Pacman
def depthLimitedSearch(self, board, locOfPacman, actions, takeAction, depthLimit):
if self.location == locOfPacman:
return []
if depthLimit == 0:
return "cutoff"
cutOffOccurred = False
for action in actions(self, board):
copyBoard = copy.deepcopy(board)
copySelf = copy.deepcopy(self)
takeAction(copySelf, copyBoard, action)
result = Ghost.depthLimitedSearch(copySelf, copyBoard, locOfPacman, actions, takeAction, depthLimit-1)
if result is "cutoff":
cutOffOccurred = True
elif result is not "failure":
return action
if cutOffOccurred:
return "cutoff"
else:
return "failure"
# Causes the ghost to scan through the board, making the most intelligent shortest path decision
def intelligentMove(self, board, locOfPacman, maxDepth=4):
if self.location == locOfPacman:
return
for depth in range(maxDepth):
result = Ghost.depthLimitedSearch(self, board, locOfPacman, Ghost.actions, Ghost.takeAction, depth)
if result != "cutoff" and result != "failure":
return Ghost.takeAction(self, board, result)
# If we get here, this means we were cutoff. Essentially, we couldn't find Pacman within maxDepth moves
# At this point, we just want to make a move in the direction that Pacman is in
return Ghost.takeActionShortestDistance(self, board, locOfPacman)