comparison gamelib/animal.py @ 82:bf28f499c6b4

Tweak fox avoidance behaviour
author Neil Muller <drnlmuller@gmail.com>
date Tue, 01 Sep 2009 14:35:22 +0000
parents aa4bd93575d9
children 5494af02a0e8
comparison
equal deleted inserted replaced
81:8a46055c7d08 82:bf28f499c6b4
77 self.landmarks = [self.pos] 77 self.landmarks = [self.pos]
78 self.hunting = True 78 self.hunting = True
79 self.dig_pos = None 79 self.dig_pos = None
80 self.tick = 0 80 self.tick = 0
81 81
82 def _cost_tile(self, pos, gameboard):
83 if gameboard.in_bounds(pos):
84 this_tile = gameboard.tv.get(pos.to_tuple())
85 cost = self.costs.get(tiles.TILE_MAP[this_tile], 100)
86 else:
87 cost = 100 # Out of bounds is expensive
88 return cost
89
82 def _cost_path(self, path, gameboard): 90 def _cost_path(self, path, gameboard):
83 """Calculate the cost of a path""" 91 """Calculate the cost of a path"""
84 total = 0 92 total = 0
85 for pos in path: 93 for pos in path:
86 if gameboard.in_bounds(pos): 94 total += self._cost_tile(pos, gameboard)
87 this_tile = gameboard.tv.get(pos.to_tuple())
88 cost = self.costs.get(tiles.TILE_MAP[this_tile], 100)
89 else:
90 cost = 100 # Out of bounds is expensive
91 total += cost
92 return total 95 return total
93 96
94 def _gen_path(self, start_pos, final_pos): 97 def _gen_path(self, start_pos, final_pos):
95 """Construct a direct path from start_pos to final_pos, 98 """Construct a direct path from start_pos to final_pos,
96 excluding start_pos""" 99 excluding start_pos"""
116 min_path = direct_path 119 min_path = direct_path
117 # is there a point nearby that gives us a cheaper direct path? 120 # is there a point nearby that gives us a cheaper direct path?
118 # This is delibrately not finding the optimal path, as I don't 121 # This is delibrately not finding the optimal path, as I don't
119 # want the foxes to be too intelligent, although the implementation 122 # want the foxes to be too intelligent, although the implementation
120 # isn't well optimised yet 123 # isn't well optimised yet
121 poss = [Position(x, y) for x in range(self.pos.x - 2, self.pos.x + 3) 124 poss = [Position(x, y) for x in range(self.pos.x - 3, self.pos.x + 4)
122 for y in range(self.pos.y - 2, self.pos.y + 3)] 125 for y in range(self.pos.y - 3, self.pos.y + 4)
126 if (x, y) != (0,0)]
123 for start in poss: 127 for start in poss:
124 if start == self.pos:
125 continue # don't repeat work we don't need to
126 cand_path = self._gen_path(self.pos, start) + \ 128 cand_path = self._gen_path(self.pos, start) + \
127 self._gen_path(start, final_pos) 129 self._gen_path(start, final_pos)
128 cost = self._cost_path(cand_path, gameboard) 130 cost = self._cost_path(cand_path, gameboard)
129 if cost < min_cost: 131 if cost < min_cost:
130 min_cost = cost 132 min_cost = cost
167 169
168 def _update_pos(self, gameboard, new_pos): 170 def _update_pos(self, gameboard, new_pos):
169 """Update the position, making sure we don't step on other foxes""" 171 """Update the position, making sure we don't step on other foxes"""
170 final_pos = new_pos 172 final_pos = new_pos
171 moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2) 173 moves = [Position(x, y) for x in range(self.pos.x-1, self.pos.x + 2)
172 for y in range(self.pos.y-1, self.pos.y + 2)] 174 for y in range(self.pos.y-1, self.pos.y + 2)
175 if (x,y) != (0,0)]
173 blocked = False 176 blocked = False
174 for fox in gameboard.foxes: 177 for fox in gameboard.foxes:
175 if fox is not self and fox.pos == new_pos: 178 if fox is not self and fox.pos == new_pos:
176 blocked = True 179 blocked = True
177 if fox.pos in moves: 180 if fox.pos in moves:
178 moves.remove(fox.pos) 181 moves.remove(fox.pos)
179 if blocked: 182 if blocked:
180 # find the closest point in moves to new_pos that's not a fence 183 # find the cheapest point in moves to new_pos that's not blocked
181 final_pos = None 184 final_pos = None
182 dist = 10 185 min_cost = 1000
183 for poss in moves: 186 for poss in moves:
184 if gameboard.in_bounds(poss): 187 cost = self._cost_tile(poss, gameboard)
185 this_tile = gameboard.tv.get(poss.to_tuple()) 188 if cost < min_cost:
186 else: 189 min_cost = cost
187 this_tile = tiles.REVERSE_TILE_MAP['woodland']
188 new_dist = poss.dist(new_pos)
189 if new_dist < dist:
190 dist = new_dist
191 final_pos = poss 190 final_pos = poss
192 if gameboard.in_bounds(final_pos): 191 if gameboard.in_bounds(final_pos):
193 this_tile = gameboard.tv.get(final_pos.to_tuple()) 192 this_tile = gameboard.tv.get(final_pos.to_tuple())
194 else: 193 else:
195 this_tile = tiles.REVERSE_TILE_MAP['woodland'] 194 this_tile = tiles.REVERSE_TILE_MAP['woodland']