comparison gamelib/gameboard.py @ 401:7405f7db469f

Tweak fox attack logic - we no longer ignore chickens we accidently step on
author Neil Muller <drnlmuller@gmail.com>
date Wed, 18 Nov 2009 15:54:31 +0000
parents d146b7bb9b99
children c7cfa230f5d4
comparison
equal deleted inserted replaced
400:d146b7bb9b99 401:7405f7db469f
290 self.animal_to_place = None 290 self.animal_to_place = None
291 self.sprite_cursor = None 291 self.sprite_cursor = None
292 self.chickens = set() 292 self.chickens = set()
293 self.foxes = set() 293 self.foxes = set()
294 self.buildings = [] 294 self.buildings = []
295 self._fox_pos_cache = [] 295 self._pos_cache = { 'fox' : [], 'chicken' : []}
296 self.cash = 0 296 self.cash = 0
297 self.eggs = 0 297 self.eggs = 0
298 self.days = 0 298 self.days = 0
299 self.killed_foxes = 0 299 self.killed_foxes = 0
300 self.add_cash(level.starting_cash) 300 self.add_cash(level.starting_cash)
365 def start_night(self): 365 def start_night(self):
366 self.day, self.night = False, True 366 self.day, self.night = False, True
367 self.tv.sun(False) 367 self.tv.sun(False)
368 self.reset_states() 368 self.reset_states()
369 self.toolbar.update_fin_tool(self.day) 369 self.toolbar.update_fin_tool(self.day)
370 self._cache_fox_positions() 370 self._cache_animal_positions()
371 371
372 def start_day(self): 372 def start_day(self):
373 self.day, self.night = True, False 373 self.day, self.night = True, False
374 self.tv.sun(True) 374 self.tv.sun(True)
375 self.reset_states() 375 self.reset_states()
376 self.toolbar.update_fin_tool(self.day) 376 self.toolbar.update_fin_tool(self.day)
377 self._pos_cache = { 'fox' : [], 'chicken' : []}
377 378
378 def in_bounds(self, pos): 379 def in_bounds(self, pos):
379 """Check if a position is within the game boundaries""" 380 """Check if a position is within the game boundaries"""
380 if pos.x < 0 or pos.y < 0: 381 if pos.x < 0 or pos.y < 0:
381 return False 382 return False
802 if not over: 803 if not over:
803 self.foxes_attack() 804 self.foxes_attack()
804 self.chickens_attack() 805 self.chickens_attack()
805 return over 806 return over
806 807
807 def _cache_fox_positions(self): 808 def _cache_animal_positions(self):
808 """Cache the current set of fox positions for the avoiding checks""" 809 """Cache the current set of fox positions for the avoiding checks"""
809 w, h = self.tv.size 810 w, h = self.tv.size
810 self._fox_pos_cache = [[[False for z in range(5)] for y in range(h)] 811 self._pos_cache['fox'] = [[[None for z in range(5)] for y in range(h)]
811 for x in range(w)] # NB: Assumes z in [0, 4] 812 for x in range(w)] # NB: Assumes z in [0, 4]
813 self._pos_cache['chicken'] = [[[None for z in range(5)] for y in range(h)]
814 for x in range(w)]
812 for fox in self.foxes: 815 for fox in self.foxes:
813 if self.in_bounds(fox.pos): 816 self._add_to_pos_cache(fox, 'fox')
814 self._fox_pos_cache[fox.pos.x][fox.pos.y][fox.pos.z] = True 817 for chick in self.chickens:
815 818 self._add_to_pos_cache(chick, 'chicken')
816 def _update_fox_pos_cache(self, old_pos, new_pos): 819
817 if self.is_fox_at_pos(old_pos): 820 def _add_to_pos_cache(self, animal, cache_type):
818 self._fox_pos_cache[old_pos.x][old_pos.y][old_pos.z] = False 821 self._pos_cache[cache_type][animal.pos.x][animal.pos.y][animal.pos.z] = animal
819 if new_pos and self.in_bounds(new_pos): 822
820 self._fox_pos_cache[new_pos.x][new_pos.y][new_pos.z] = True 823 def _update_pos_cache(self, old_pos, animal, cache_type):
821 824 if self.in_bounds(old_pos):
822 def is_fox_at_pos(self, pos): 825 self._pos_cache[cache_type][old_pos.x][old_pos.y][old_pos.z] = None
826 if animal:
827 pos = animal.pos
828 if self.in_bounds(pos):
829 self._pos_cache[cache_type][pos.x][pos.y][pos.z] = animal
830
831 def get_animal_at_pos(self, pos, cache_type):
832 if not self._pos_cache[cache_type]:
833 return None # We don't maintain the cache during the day
823 if self.in_bounds(pos): 834 if self.in_bounds(pos):
824 return self._fox_pos_cache[pos.x][pos.y][pos.z] 835 return self._pos_cache[cache_type][pos.x][pos.y][pos.z]
825 return False 836 return None
826 837
827 def foxes_move(self): 838 def foxes_move(self):
828 over = True 839 over = True
829 for fox in self.foxes: 840 for fox in self.foxes:
830 old_pos = fox.pos 841 old_pos = fox.pos
831 fox.move(self) 842 fox.move(self)
832 if not fox.safe: 843 if not fox.safe:
833 over = False 844 over = False
834 if fox.pos != old_pos: 845 if fox.pos != old_pos:
835 self._update_fox_pos_cache(old_pos, fox.pos) 846 self._update_pos_cache(old_pos, fox, 'fox')
836 return over 847 return over
837 848
838 def foxes_attack(self): 849 def foxes_attack(self):
839 for fox in self.foxes: 850 for fox in self.foxes:
840 fox.attack(self) 851 fox.attack(self)
892 903
893 def kill_fox(self, fox): 904 def kill_fox(self, fox):
894 self.killed_foxes += 1 905 self.killed_foxes += 1
895 self.toolbar.update_fox_counter(self.killed_foxes) 906 self.toolbar.update_fox_counter(self.killed_foxes)
896 self.add_cash(self.level.sell_price_dead_fox) 907 self.add_cash(self.level.sell_price_dead_fox)
897 self._update_fox_pos_cache(fox.pos, None) 908 self._update_pos_cache(fox.pos, None, 'fox')
898 self.remove_fox(fox) 909 self.remove_fox(fox)
899 910
900 def remove_fox(self, fox): 911 def remove_fox(self, fox):
901 self.foxes.discard(fox) 912 self.foxes.discard(fox)
902 if fox.building: 913 if fox.building:
913 if chick.abode: 924 if chick.abode:
914 chick.abode.clear_occupant() 925 chick.abode.clear_occupant()
915 self.toolbar.update_chicken_counter(len(self.chickens)) 926 self.toolbar.update_chicken_counter(len(self.chickens))
916 if chick in self.tv.sprites and chick.outside(): 927 if chick in self.tv.sprites and chick.outside():
917 self.tv.sprites.remove(chick) 928 self.tv.sprites.remove(chick)
929 self._update_pos_cache(chick.pos, None, 'chicken')
918 930
919 def remove_building(self, building): 931 def remove_building(self, building):
920 if building in self.buildings: 932 if building in self.buildings:
921 self.buildings.remove(building) 933 self.buildings.remove(building)
922 self.tv.sprites.remove(building, layer='buildings') 934 self.tv.sprites.remove(building, layer='buildings')