def can_heal_players(self, treat_radius, mobs=None): # FIXME done? if not mobs: mobs = self.mobs return all( distance(m, p) > treat_radius for p in self.players for m in mobs if mobs[m].kind in bad_mobs) and any( p.hp < p.max_hp for p in self.players.values())
def share(self, player_name, item_name): try: player = next(p for p in self.world.players.values() if p.name == player_name) item = next(i for i in self.inventory if i.name == item_name) if distance(self.position, player.position) <= self.talking_distance: self.inventory.remove(item) player.inventory.append(item) self.last_happend = '{} передал {} в руки {}'.format(self.name, item_name, player_name) else: self.last_happend = '{} слишком далеко от {}'.format(self.name, player_name) except StopIteration: self.last_happend = "{} не может дать {} в руки {}".format(self.name, item_name, player_name)
def generate_game_board(shape): start_position = (random.randrange(5, shape[0] - 5), random.randrange(5, shape[1] - 5)) exit_position = (random.randrange(3, shape[0] - 3), random.randrange(3, shape[1] - 3)) if distance(start_position, exit_position) < shape[0] / 3: return generate_game_board(shape) g = BoardGenerator(shape) g.add_figure(add((-5, -5), start_position), random_orientation(create_figure(starting_area))) g.add_figure(add((-1, -1), exit_position), random_orientation(create_figure(exit_area))) return g.generate(), start_position, [exit_position]
def use(self): self.user.ap -= self.cost local_log = " использовал волшебный взрыв" target_enemyes = [ self.user.world.mobs[m] for m in self.user.world.mobs_near( circle(self.user.position, self.range)) if self.user.world.mobs[m].kind in self.user.opponents ] for m in target_enemyes: self.damage = int(self.max_damage - self.decrement * distance(m.position, self.user.position)) local_log += '\nон' + self.user.hit(m, self) return local_log
def plot(self): start_line = '\n╔' + '══' * self.window_width + '╗' end_line = '\n╚' + '══' * self.window_width + '╝' map_plotted = start_line for i in range(self.position[0] - self.window_height // 2, self.position[0] + self.window_height // 2 + 1): line = '' for j in range(self.position[1] - self.window_width // 2, self.position[1] + self.window_width // 2 + 1): if abs(distance(self.position, (i, j)) - self.see) <= 1: line += '░░' elif distance(self.position, (i, j)) > self.see: line += '▒▒' elif self.world.is_occupied((i, j)): line += self.world.mobs[(i, j)].look elif self.world.is_drop((i, j)): line += self.world.drop[(i, j)][-1].look elif self.world.board.is_inside((i, j)): line += self.world.board.square((i, j)).look else: line += '▓▓' map_plotted += '\n║' + line + '║' map_plotted += end_line return map_plotted
def update_possible(square, possible, explored, entity): possible.remove(square) for direction in DIRS.values(): if (entity.world.can_move(entity, direction.go(square.position)) and direction.go(square.position) not in explored and distance(entity.position, direction.go( square.position)) <= entity.see): s = Node(direction.go(square.position), entity.world.board.squares[square.position].points_to_go) if square.value + s.cost < s.value: s.value = square.value + s.cost s.previous = square possible.append(s) return possible
def plot_for_web(self): start_line = '╔' + '══' * self.window_width + '╗' end_line = '<br>╚' + '══' * self.window_width + '╝' descriptions = {} map_plotted = start_line for i in range(self.position[0] - self.window_height // 2, self.position[0] + self.window_height // 2 + 1): line = '' for j in range(self.position[1] - self.window_width // 2, self.position[1] + self.window_width // 2 + 1): if abs(distance(self.position, (i, j)) - self.see) <= 1: line += '░░' elif distance(self.position, (i, j)) > self.see: line += '▒▒' elif self.world.is_occupied((i, j)): tile_id = f"tile_{i}_{j}" descriptions[tile_id] = self.world.mobs[(i, j)].show() style = "" if self.world.board.is_inside((i, j)): style = self.world.board.square((i, j)).style line += f"<span class='map_tile' id='{tile_id}' style='{style}'>{self.world.mobs[(i, j)].look}</span>" elif self.world.is_drop((i, j)): tile_id = f"tile_{i}_{j}" descriptions[tile_id] = str(self.world.drop[(i, j)][-1]) style = "" if self.world.board.is_inside((i, j)): style = self.world.board.square((i, j)).style line += f"<span class='map_tile' id='{tile_id}' style='{style}'>{self.world.drop[(i, j)][-1].look}</span>" elif self.world.board.is_inside((i, j)): tile_id = f"tile_{i}_{j}" descriptions[tile_id] = self.world.board.square((i, j)).description style = self.world.board.square((i, j)).style line += f"<span class='map_tile' style='{style}' id='{tile_id}'>{self.world.board.square((i, j)).look}</span>" else: line += '▓▓' map_plotted += '<br>║' + line + '║' map_plotted += end_line return map_plotted, descriptions
def path(entity, positions, max_deph=15): start_position = entity.position possible = [ StartNode(start_position, entity.world.board.squares[start_position].points_to_go) ] explored = [] for _ in range(max_deph): square = best_point(possible, positions) if len(possible) == 0: break if square == 0: break if any(distance(square.position, p) == 0 for p in positions): return build_path(entity, square) else: explored.append(square.position) possible = update_possible(square, possible, explored, entity) return []
def use(self, direction): self.user.ap -= self.cost p = direction.go(self.user.position) dirs = {d for d in DIRS.values() if d != anti_dir(direction)} queue = [p] visited = set() log_message = "" # FIXME Something still wrong, one mob hit twice while len(queue) > 0: a = queue.pop(0) if a in visited: continue visited.add(a) if self.user.world.if_mob_is(a, self.user.opponents): log_message += "\n" + self.user.hit(self.user.world.mobs[a], self) queue.extend([ d.go(a) for d in dirs if distance(d.go(a), self.user.position) <= self.range_ and d.go(a) not in visited ]) if len(log_message) == 0: return " никуда не попал хлыстом" return " своим хлыстом:" + log_message
def test_distance(): assert distance((0, 0), (0, 3)) == 3 assert distance((1, 1), (4, 5)) == 5
def best_point(possible, positions): return min(possible, key=lambda x: min(x.cost + distance(p, x.position) for p in positions), default=0)
def observable(self, entity): # TODO may be this is stupid return self.see * self.awareness >= distance(entity.position, self.position) * entity.masking()
def can_see(self, position): return self.see >= distance(self.position, position)
def nearest_exit_to(self, position): return min(self.exits, key=lambda x: distance(x, position))