comparison gamelib/animal.py @ 149:2a1064fae608

More memory for the foxes, to ensure we avoid short loops
author Neil Muller <drnlmuller@gmail.com>
date Thu, 03 Sep 2009 20:12:54 +0000
parents 423050ec188b
children baf857805867
comparison
equal deleted inserted replaced
148:225be1220053 149:2a1064fae608
174 self.hunting = True 174 self.hunting = True
175 self.dig_pos = None 175 self.dig_pos = None
176 self.tick = 0 176 self.tick = 0
177 self.safe = False 177 self.safe = False
178 self.closest = None 178 self.closest = None
179 self.last_steps = []
179 180
180 def _cost_tile(self, pos, gameboard): 181 def _cost_tile(self, pos, gameboard):
181 if gameboard.in_bounds(pos): 182 if gameboard.in_bounds(pos):
182 this_tile = gameboard.tv.get(pos.to_tuple()) 183 this_tile = gameboard.tv.get(pos.to_tuple())
183 cost = self.costs.get(tiles.TILE_MAP[this_tile], 100) 184 cost = self.costs.get(tiles.TILE_MAP[this_tile], 100)
272 """Catch a chicken""" 273 """Catch a chicken"""
273 sound.play_sound("kill-chicken.ogg") 274 sound.play_sound("kill-chicken.ogg")
274 self.closest = None 275 self.closest = None
275 gameboard.remove_chicken(chicken) 276 gameboard.remove_chicken(chicken)
276 self.hunting = False 277 self.hunting = False
278 self.last_steps = [] # Forget history here
277 279
278 def _update_pos(self, gameboard, new_pos): 280 def _update_pos(self, gameboard, new_pos):
279 """Update the position, making sure we don't step on other foxes""" 281 """Update the position, making sure we don't step on other foxes"""
280 final_pos = new_pos
281 if new_pos == self.pos: 282 if new_pos == self.pos:
282 # We're not moving, so we can skip all the checks 283 # We're not moving, so we can skip all the checks
283 return final_pos 284 return new_pos
284 blocked = False 285 final_pos = new_pos
286 blocked = final_pos in self.last_steps
285 moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2) 287 moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2)
286 for y in range(self.pos.y-1, self.pos.y + 2) 288 for y in range(self.pos.y-1, self.pos.y + 2)
287 if (x,y) != (0,0)] 289 if Position(x,y) != self.pos and \
290 Position(x, y) not in self.last_steps]
288 for fox in gameboard.foxes: 291 for fox in gameboard.foxes:
289 if fox is not self and fox.pos == new_pos: 292 if fox is not self and fox.pos == final_pos:
290 blocked = True 293 blocked = True
291 if fox.pos in moves: 294 if fox.pos in moves:
292 moves.remove(fox.pos) 295 moves.remove(fox.pos)
293 if blocked: 296 if blocked:
294 # find the cheapest point in moves to new_pos that's not blocked 297 # find the cheapest point in moves to new_pos that's not blocked
297 for poss in moves: 300 for poss in moves:
298 cost = self._cost_tile(poss, gameboard) 301 cost = self._cost_tile(poss, gameboard)
299 if cost < min_cost: 302 if cost < min_cost:
300 min_cost = cost 303 min_cost = cost
301 final_pos = poss 304 final_pos = poss
305 if not final_pos:
306 # No good choice, so stay put
307 return self.pos
302 if gameboard.in_bounds(final_pos): 308 if gameboard.in_bounds(final_pos):
303 this_tile = gameboard.tv.get(final_pos.to_tuple()) 309 this_tile = gameboard.tv.get(final_pos.to_tuple())
304 else: 310 else:
305 this_tile = tiles.REVERSE_TILE_MAP['woodland'] 311 this_tile = tiles.REVERSE_TILE_MAP['woodland']
306 if tiles.TILE_MAP[this_tile] == 'broken fence' and self.hunting: 312 if tiles.TILE_MAP[this_tile] == 'broken fence' and self.hunting:
307 # We'll head back towards the holes we make/find 313 # We'll head back towards the holes we make/find
308 self.landmarks.append(final_pos) 314 self.landmarks.append(final_pos)
309 elif tiles.TILE_MAP[this_tile] == 'fence' and not self.dig_pos: 315 elif tiles.TILE_MAP[this_tile] == 'fence' and not self.dig_pos:
310 self._dig(final_pos) 316 self._dig(final_pos)
311 return self.pos 317 return self.pos
318 self.last_steps.append(final_pos)
319 if len(self.last_steps) > 3:
320 self.last_steps.pop(0)
312 return final_pos 321 return final_pos
313 322
314 def _dig(self, dig_pos): 323 def _dig(self, dig_pos):
315 """Setup dig parameters, to be overridden if needed""" 324 """Setup dig parameters, to be overridden if needed"""
316 self.tick = 5 325 self.tick = 5
368 gameboard.remove_chicken(chicken) 377 gameboard.remove_chicken(chicken)
369 self.closest = None 378 self.closest = None
370 self.chickens_eaten += 1 379 self.chickens_eaten += 1
371 if self.chickens_eaten > 2: 380 if self.chickens_eaten > 2:
372 self.hunting = False 381 self.hunting = False
382 self.last_steps = []
373 383
374 def visible(watcher, watchee): 384 def visible(watcher, watchee):
375 roll = random.randint(1, 100) 385 roll = random.randint(1, 100)
376 distance = watcher.pos.dist(watchee.pos) - 1 386 distance = watcher.pos.dist(watchee.pos) - 1
377 return roll > watchee.STEALTH + 10*distance 387 return roll > watchee.STEALTH + 10*distance