def act(self, game): all_locs = {(x, y) for x in xrange(19) for y in xrange(19)} spawn = {loc for loc in all_locs if 'spawn' in rg.loc_types(loc)} obstacle = {loc for loc in all_locs if 'obstacle' in rg.loc_types(loc)} team = {loc for loc in game.robots if game.robots[loc].player_id == self.player_id} enemy = set(game.robots) - team adjacent = set(rg.locs_around(self.location)) - obstacle adjacent_enemy = adjacent & enemy adjacent_enemy2 = {loc for loc in adjacent if (set(rg.locs_around(loc)) & enemy)} - team safe = adjacent - adjacent_enemy - adjacent_enemy2 - spawn - team def mindist(bots, loc): return min(bots, key=lambda x: rg.dist(x, loc)) if enemy: closest_enemy = mindist(enemy, self.location) else closest_enemy = rg.CENTER_POINT move = ['guard'] if self.location in spawn: if safe: move = ['move', mindist(safe, rg.CENTER_POINT)] elif adjacent_enemy: if 9 * len(adjacent_enemy) >= self.hp: if safe: move = ['move', mindist(safe, rg.CENTER_POINT)] else: move = ['attack', adjacent_enemy.pop()] elif adjacent_enemy2: move = ['attack', adjacent_enemy2.pop()] elif safe: move = ['move', mindist(safe, closest_enemy)]
def commandGuard(self, game): ######################################################################### #Ustawia status 'alarm' jeżeli wrogi robot jest za blisko ######################################################################### if values.commands[self.robot_id]['action'] == 'nil': for bots in values.enemies: if rg.wdist(self.location, bots) == R_FROM_ENEMY: values.commands[self.robot_id]['action'] = 'guard' values.commands[self.robot_id]['status'] = 'alarm' self.alarm(game) break ######################################################################### #Jeżeli w pobliżu nie ma wrogów, a robot ma status 'alarm', zmienia jego status na 'calm' ######################################################################### if values.commands[self.robot_id]['action'] == 'alarm': sEnemies = set(values.enemies) for loc in rg.locs_around(self.location): sEnemies -= set(loc) if len(sEnemies) == len(values.enemies): values.commands[self.robot_id]['action'] = 'nil' values.commands[self.robot_id]['status'] = 'calm' values.commands[ self.robot_id]['destination'] = values.safeSpace
def _validate_action(robot, action): """ Need to be VERY CAREFUL here not to call any built-in functions on 'action' unless it is known to be completely safe. A malicious bot may return an object with overwritten built-in functions that run arbitrary code. """ Player._validate_type(robot, 'action', action, (list, tuple)) Player._validate_length(robot, 'action', action, (1, 2)) Player._validate_type(robot, 'action[0]', action[0], (str, )) if action[0] in ('move', 'attack'): if len(action) != 2: raise Exception( 'Bot {0}: {1} requires a location as well.'.format( robot.robot_id, action)) Player._validate_type(robot, 'action[1]', action[1], (list, tuple)) Player._validate_length(robot, 'action[1]', action[1], (2, )) Player._validate_type(robot, 'action[1][0]', action[1][0], Player._numeral_types()) Player._validate_type(robot, 'action[1][1]', action[1][1], Player._numeral_types()) valid_locs = rg.locs_around(robot.location, filter_out=['invalid', 'obstacle']) if action[1] not in valid_locs: raise Exception('Bot {0}: {1} is not a valid action.'.format( robot.robot_id, action)) elif action[0] not in ('guard', 'suicide'): raise ValueError('Bot %d: action must be one of "guard", ' '"suicide", "move", or "attack".')
def _surrounding(location): """test closest place location and property Args: location (tuple): location of the map Returns: tuple: return[0], list, a list of location of normal places return[1], list, a list of location of spawn places """ normal = rg.locs_around(location, filter_out=('invalid', 'obstacle', 'spawn')) spawn = rg.locs_around(location, filter_out=('invalid', 'obstacle')) new_spawn = [val for val in spawn if val not in normal] # intersection = [val for val in normal if val in new_spawn] # print "intersection", intersection return normal, new_spawn
def _validate_action(robot, action): """ Need to be VERY CAREFUL here not to call any built-in functions on 'action' unless it is known to be completely safe. A malicious bot may return an object with overwritten built-in functions that run arbitrary code. """ Player._validate_type(robot, 'action', action, (list, tuple)) Player._validate_length(robot, 'action', action, (1, 2)) Player._validate_type(robot, 'action[0]', action[0], (str,)) if action[0] in ('move', 'attack'): if len(action) != 2: raise Exception( 'Bot {0}: {1} requires a location as well.'.format( robot.robot_id, action) ) Player._validate_type(robot, 'action[1]', action[1], (list, tuple)) Player._validate_length(robot, 'action[1]', action[1], (2,)) Player._validate_type( robot, 'action[1][0]', action[1][0], (int, long, float)) Player._validate_type( robot, 'action[1][1]', action[1][1], (int, long, float)) valid_locs = rg.locs_around( robot.location, filter_out=['invalid', 'obstacle']) if action[1] not in valid_locs: raise Exception( 'Bot {0}: {1} is not a valid action.'.format( robot.robot_id, action) ) elif action[0] not in ('guard', 'suicide'): raise Exception('Bot %d: action must be one of "guard", "suicide",' '"move", or "attack".')
def get_possible_actions(self): possible_moves = [s.ACTION_SUICIDE] possible_locs = rg.locs_around(self.location, filter_out=('invalid', 'obstacle')) for loc in possible_locs: possible_moves.append((s.ACTION_MOVE, loc)) possible_moves.append((s.ACTION_ATTACK, loc)) return possible_moves
def commandSuicide(self, game): ######################################################################### #Jeżeli ilość punktów życia jest mniejsza od liczby punktów obrażeń, #które może zebrać od wrogów obok niego, popełnia samobójstwo ######################################################################### ene = set(values.enemies) & set(rg.locs_around(self.location)) if self.hp >= len(ene) * 8 and self.hp <= len(ene) * 10: values.commands[self.robot_id]['action'] = 'suicide' values.commands[self.robot_id]['status'] = 'suicide'
def _get_damage_map(self, actions): damage_map = defaultdict( lambda: [{} for _ in range(settings.player_count)]) for loc, robot in list(self.robots.items()): actor_id = robot.player_id if actions[loc][0] == 'attack': target = actions[loc][1] damage = self._attack_random.randint(*settings.attack_range) damage_map[target][actor_id][loc] = damage elif actions[loc][0] == 'suicide': damage = settings.suicide_damage for target in rg.locs_around(loc): damage_map[target][actor_id][loc] = damage return damage_map
def _get_damage_map(self, actions): damage_map = defaultdict( lambda: [{} for _ in xrange(settings.player_count)]) for loc, robot in self.robots.iteritems(): actor_id = robot.player_id if actions[loc][0] == 'attack': target = actions[loc][1] damage = self._attack_random.randint( *settings.attack_range) damage_map[target][actor_id][loc] = damage elif actions[loc][0] == 'suicide': damage = settings.suicide_damage for target in rg.locs_around(loc): damage_map[target][actor_id][loc] = damage return damage_map
def is_valid_action(self, actor, action): try: if len(str(action)) > self._settings.str_limit: return False if len(repr(action)) > self._settings.str_limit: return False if action[0] in ['move', 'attack']: return action[1] in rg.locs_around( actor, filter_out=['invalid', 'obstacle']) elif action[0] in ['guard', 'suicide']: return True else: return False except: return False
def commandAttack(self, game): ######################################################################### #Jeżeli wrogi robot znajduje się obok, ustawia status 'atack', aby go atakować ######################################################################### for bots in values.enemies: if rg.wdist(self.location, bots) == 1: values.commands[self.robot_id]['action'] = 'attack' values.commands[self.robot_id]['stauts'] = 'attack' values.commands[self.robot_id]['destination'] = bots break ######################################################################### #Jeżeli w pobliżu nie ma wrogów, a robot ma status 'atack', zmienia jego status na 'calm' ######################################################################### if len(set(values.enemies) - set(rg.locs_around(self.location))) == len(values.enemies): values.commands[self.robot_id]['action'] = 'nil' values.commands[self.robot_id]['status'] = 'calm' values.commands[self.robot_id]['destination'] = values.safeSpace
def call_suicide(self, action_table): self.hp = 0 self.call_attack(self.location, action_table, damage=settings.suicide_damage) for loc in rg.locs_around(self.location): self.call_attack(loc, action_table, damage=settings.suicide_damage)
def test_around(self): filtered = set(rg.locs_around((3, 3))) self.assertEqual(filtered, set([(3, 2), (4, 3), (3, 4), (2, 3)]))
def get_delta(self, actions, spawn=True): delta = [] def dest(loc): if actions[loc][0] == 'move': return actions[loc][1] else: return loc hitpoints = defaultdict(lambda: set()) def stuck(loc): # we are not moving anywhere # inform others old_hitpoints = hitpoints[loc] hitpoints[loc] = set([loc]) for rival in old_hitpoints: if rival != loc: stuck(rival) for loc in self.robots: hitpoints[dest(loc)].add(loc) for loc in self.robots: if len(hitpoints[dest(loc)]) > 1 or (self.is_robot(dest(loc)) and dest(loc) != loc and dest(dest(loc)) == loc): # we've got a problem stuck(loc) # calculate new locations for loc, robot in self.robots.iteritems(): if actions[loc][0] == 'move' and loc in hitpoints[loc]: new_loc = loc else: new_loc = dest(loc) delta.append(AttrDict({ 'loc': loc, 'hp': robot.hp, 'player_id': robot.player_id, 'loc_end': new_loc, 'hp_end': robot.hp # will be adjusted later })) # {loc: set(robots collided with loc} collisions = defaultdict(lambda: set()) for loc in self.robots: for loc2 in hitpoints[dest(loc)]: collisions[loc].add(loc2) collisions[loc2].add(loc) # {loc: [damage_dealt_by_player_0, damage_dealt_by_player_1]} damage_map = defaultdict(lambda: [0, 0]) for loc, robot in self.robots.iteritems(): actor_id = robot.player_id if actions[loc][0] == 'attack': target = actions[loc][1] damage = self._attack_random.randint( *self._settings.attack_range) damage_map[target][actor_id] += damage if actions[loc][0] == 'suicide': damage_map[loc][1 - actor_id] += self._settings.robot_hp damage = self._settings.suicide_damage for target in rg.locs_around(loc): damage_map[target][actor_id] += damage # apply damage for delta_info in delta: loc = delta_info.loc loc_end = delta_info.loc_end robot = self.robots[loc] # apply collision damage if actions[loc][0] != 'guard': damage = self._settings.collision_damage for loc2 in collisions[delta_info.loc]: if robot.player_id != self.robots[loc2].player_id: delta_info.hp_end -= damage # apply other damage damage_taken = damage_map[loc_end][1 - robot.player_id] if actions[loc][0] == 'guard': damage_taken /= 2 delta_info.hp_end -= damage_taken if spawn: if self.turn % self._settings.spawn_every == 0: # clear bots on spawn for delta_info in delta: loc_end = delta_info.loc_end if loc_end in self._settings.spawn_coords: delta_info.hp_end = 0 # spawn bots locations = self._get_spawn_locations() for player_id, locs in enumerate(locations): for loc in locs: delta.append(AttrDict({ 'loc': loc, 'hp': 0, 'player_id': player_id, 'loc_end': loc, 'hp_end': self._settings.robot_hp })) return delta
def act(self, game): assert rg.CENTER_POINT is not None assert rg.locs_around((9, 9)) is not None return ["guard"]
def test_around_filter(self): filtered = set(rg.locs_around((3, 3), filter_out=['obstacle'])) self.assertEqual(filtered, set([(4, 3), (3, 4)]))
def act(self, game): assert rg.CENTER_POINT is not None assert rg.locs_around((9, 9)) is not None return ['guard']
def movable_loc(self, loc): good_around = rg.locs_around(self.location, filter_out=['invalid', 'obstacle']) return loc in good_around
def get_robots_around(self, loc): locs_around = rg.locs_around(loc, filter_out=['obstacle', 'invalid']) locs_around.append(loc) robots = [self.field[x] for x in locs_around] return [x for x in robots if x not in (None, self)]