comparison gamelib/animal.py @ 145:490ede177f50

Tweak fox behaviour around henhouses. Add some memory to avoid the indecisive fox loop
author Neil Muller <drnlmuller@gmail.com>
date Thu, 03 Sep 2009 15:14:13 +0000
parents 96c5ef7613b5
children 423050ec188b
comparison
equal deleted inserted replaced
144:a9b800b4175e 145:490ede177f50
137 'grassland' : 2, 137 'grassland' : 2,
138 'woodland' : 1, # Try to keep to the woods if possible 138 'woodland' : 1, # Try to keep to the woods if possible
139 'broken fence' : 2, 139 'broken fence' : 2,
140 'fence' : 10, 140 'fence' : 10,
141 'guardtower' : 2, # We can pass under towers 141 'guardtower' : 2, # We can pass under towers
142 'henhouse' : 2, 142 'henhouse' : 30, # Don't go into a henhouse unless we're going to
143 # catch a chicken there
144 'hendominium' : 30,
143 } 145 }
144 146
145 def __init__(self, pos): 147 def __init__(self, pos):
146 image_left = imagecache.load_image(self.IMAGE_FILE) 148 image_left = imagecache.load_image(self.IMAGE_FILE)
147 image_right = imagecache.load_image(self.IMAGE_FILE, ("right_facing",)) 149 image_right = imagecache.load_image(self.IMAGE_FILE, ("right_facing",))
149 self.landmarks = [self.pos] 151 self.landmarks = [self.pos]
150 self.hunting = True 152 self.hunting = True
151 self.dig_pos = None 153 self.dig_pos = None
152 self.tick = 0 154 self.tick = 0
153 self.safe = False 155 self.safe = False
156 self.closest = None
154 157
155 def _cost_tile(self, pos, gameboard): 158 def _cost_tile(self, pos, gameboard):
156 if gameboard.in_bounds(pos): 159 if gameboard.in_bounds(pos):
157 this_tile = gameboard.tv.get(pos.to_tuple()) 160 this_tile = gameboard.tv.get(pos.to_tuple())
158 cost = self.costs.get(tiles.TILE_MAP[this_tile], 100) 161 cost = self.costs.get(tiles.TILE_MAP[this_tile], 100)
222 225
223 def _find_path_to_chicken(self, gameboard): 226 def _find_path_to_chicken(self, gameboard):
224 """Find the path to the closest chicken""" 227 """Find the path to the closest chicken"""
225 # Find the closest chicken 228 # Find the closest chicken
226 min_dist = 999 229 min_dist = 999
227 closest = None 230 if self.closest not in gameboard.chickens:
228 for chicken in gameboard.chickens: 231 # Either no target, or someone ate it
229 dist = chicken.pos.dist(self.pos) 232 for chicken in gameboard.chickens:
230 if dist < min_dist: 233 dist = chicken.pos.dist(self.pos)
231 min_dist = dist 234 if chicken.abode:
232 closest = chicken 235 dist += 10 # Prefer free-ranging chickens
233 if not closest: 236 if dist < min_dist:
237 min_dist = dist
238 self.closest = chicken
239 if not self.closest:
234 # No more chickens, so leave 240 # No more chickens, so leave
235 self.hunting = False 241 self.hunting = False
236 return self.pos 242 return self.pos
237 if closest.pos == self.pos: 243 if self.closest.pos == self.pos:
238 # Caught a chicken 244 # Caught a chicken
239 self._catch_chicken(closest, gameboard) 245 self._catch_chicken(self.closest, gameboard)
240 return self.pos 246 return self.pos
241 return self._find_best_path_step(closest.pos, gameboard) 247 return self._find_best_path_step(self.closest.pos, gameboard)
242 248
243 def _catch_chicken(self, chicken, gameboard): 249 def _catch_chicken(self, chicken, gameboard):
244 """Catch a chicken""" 250 """Catch a chicken"""
245 sound.play_sound("kill-chicken.ogg") 251 sound.play_sound("kill-chicken.ogg")
252 self.closest = None
246 gameboard.remove_chicken(chicken) 253 gameboard.remove_chicken(chicken)
247 self.hunting = False 254 self.hunting = False
248 255
249 def _update_pos(self, gameboard, new_pos): 256 def _update_pos(self, gameboard, new_pos):
250 """Update the position, making sure we don't step on other foxes""" 257 """Update the position, making sure we don't step on other foxes"""
251 final_pos = new_pos 258 final_pos = new_pos
259 if new_pos == self.pos:
260 # We're not moving, so we can skip all the checks
261 return final_pos
262 blocked = False
252 moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2) 263 moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2)
253 for y in range(self.pos.y-1, self.pos.y + 2) 264 for y in range(self.pos.y-1, self.pos.y + 2)
254 if (x,y) != (0,0)] 265 if (x,y) != (0,0)]
255 blocked = False
256 for fox in gameboard.foxes: 266 for fox in gameboard.foxes:
257 if fox is not self and fox.pos == new_pos: 267 if fox is not self and fox.pos == new_pos:
258 blocked = True 268 blocked = True
259 if fox.pos in moves: 269 if fox.pos in moves:
260 moves.remove(fox.pos) 270 moves.remove(fox.pos)
332 Fox.__init__(self, pos) 342 Fox.__init__(self, pos)
333 self.chickens_eaten = 0 343 self.chickens_eaten = 0
334 344
335 def _catch_chicken(self, chicken, gameboard): 345 def _catch_chicken(self, chicken, gameboard):
336 gameboard.remove_chicken(chicken) 346 gameboard.remove_chicken(chicken)
347 self.closest = None
337 self.chickens_eaten += 1 348 self.chickens_eaten += 1
338 if self.chickens_eaten > 2: 349 if self.chickens_eaten > 2:
339 self.hunting = False 350 self.hunting = False
340 351
341 def visible(watcher, watchee): 352 def visible(watcher, watchee):