-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzombie.py
executable file
·220 lines (181 loc) · 10.8 KB
/
zombie.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
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/bin/python
"""
CS Games 2011
AI Competition
Chris Iverach-Brereton
This file contains the Zombie class, which is controlled
entirely by the computer
Competitors should NOT need to edit this file
#################
We asked if we could import this, and some guy with a wicked beard said so
#################
"""
import sys
from entity import *
import gameSquare
import math
class Zombie(Entity):
# how far away can the zombie see people?
_agroRange = 5
def __init__(self, configStr=None):
self._team = 1
Entity.__init__(self, configStr)
self._hp = 5
def __str__(self):
return Entity.__str__(self)
def takeTurn(self, board):
#print '[info] Entity',self._id,'starting turn'
src = board.getEntities(Entity.HUMAN_TEAM)
humans = []
for h in src:
if not h.isDead():
humans.insert(0,h)
random.shuffle(humans)
# find the closest human
closestHuman = None
shortestDistance = math.sqrt(board.getWidth()**2+board.getHeight()**2)
for h in humans:
if not h.isDead() and h._square!=None and (board._checkLOS(self._square, h._square) or board.isAdjacent(self._square, h._square)):
dy = self._square.getRow() - h._square.getRow()
dx = self._square.getColumn() - h._square.getColumn()
if math.sqrt(dy**2 + dx**2) < shortestDistance:
closestHuman = h
shortestDistance = math.sqrt(dy**2 + dx**2)
#sys.stderr.write('ZOMBIE EMULATOR %s\n' % closestHuman)
if closestHuman != None and int(shortestDistance) <= self._agroRange:
print '[info] Entity',self._id,'smells living flesh'
# move towards the human or attack if possible
dy = self._square.getRow() - closestHuman._square.getRow()
dx = self._square.getColumn() - closestHuman._square.getColumn()
if abs(dy) <=1 and abs(dx) <=1:
self.attack(closestHuman._square, False, board)
else:
# for this section we identfy the preferred directions to gi
# i.e. the ones that move us closest to the target
# if the primary direction fails try the backup (if one exists)
# if two directions are equally weighted then randomly pick one
# if nothing works don't move
if dy > 0 and dx > 0: # move up/left
# move along primary direction
if abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
# primary failed; move along secondary
elif abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
# tied primaries
# try either direction in a random order
elif abs(dy) == abs(dx):
r = random.randint(0,1)
if r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif dy < 0 and dx > 0: # move down/left
# move along primary direction
if abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
# primary failed; move along secondary
elif abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
# tied primaries
# try either direction in a random order
elif abs(dy) == abs(dx):
r = random.randint(0,1)
if r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif dy > 0 and dx < 0: # move up/right
# move along primary direction
if abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
# primary failed; move along secondary
elif abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
# tied primaries
# try either direction in a random order
elif abs(dy) == abs(dx):
r = random.randint(0,1)
if r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif dy < 0 and dx < 0: # move down/right
# move along primary direction
if abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
# primary failed; move along secondary
elif abs(dy) > abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
elif abs(dy) < abs(dx) and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
# tied primaries
# try either direction in a random order
elif abs(dy) == abs(dx):
r = random.randint(0,1)
if r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif r==0 and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
elif r==1 and self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif dy > 0: # move up only
if self.checkMove(gameSquare.GameSquare.DIRECTION_UP):
self.move(gameSquare.GameSquare.DIRECTION_UP)
elif dy < 0: # move down only
if self.checkMove(gameSquare.GameSquare.DIRECTION_DOWN):
self.move(gameSquare.GameSquare.DIRECTION_DOWN)
elif dx > 0: # move left only
if self.checkMove(gameSquare.GameSquare.DIRECTION_LEFT):
self.move(gameSquare.GameSquare.DIRECTION_LEFT)
elif dx < 0: # move right only
if self.checkMove(gameSquare.GameSquare.DIRECTION_RIGHT):
self.move(gameSquare.GameSquare.DIRECTION_RIGHT)
else: # this should never happen
print '* Entity',self._id,'smells brains but can\'t reach them'
else:
print '[info] Entity',self._id,'staggers randomly'
# move in a random direction
direction = random.randint(1,4)
increment = random.randint(0,1)
if increment == 0:
increment = -1
for i in range(4):
if self.checkMove(direction):
self.move(direction)
return
#print 'can\'t move',direction
direction = direction + increment
if direction <=0:
direction = 4
elif direction > 4:
direction = 1
#print '[info] Entity',self._id,'done turn'