Mercurial > rinkhals
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'] |