def test_get_single_biggest_jradar_points(self): self.ai.reset_jradar_field() self.ai.jradar_values[messages.Pos(0,0)] = 11 self.ai.jradar_values[messages.Pos(3,0)] = 11 self.ai.jradar_values[messages.Pos(-3,0)] = 11 point = self.ai.get_single_biggest_jradar_points() self.assertEqual(point, (messages.Pos(0,0), 67))
def test_optimal_radars_on_field(self): positions = self.ai.optimal_radars_on_field(radar=self.ai.config.radar) expected_positions_subset = set(( messages.Pos(x=0, y=0), messages.Pos(x=6, y=-14), )) self.assertTrue(positions.issuperset(expected_positions_subset))
def test_triangle_points_2(self, mocked_randint): positions = set(self.ai.triangle_points(x=0, y=0, radius=1)) expected_positions = set(( messages.Pos(x=1, y=0), messages.Pos(x=-1, y=1), messages.Pos(x=0, y=-1), )) self.assertEqual(positions, expected_positions)
def test_get_biggest_jradar_points(self): self.ai.reset_jradar_field() self.ai.jradar_values[messages.Pos(0,0)] = 11 self.ai.jradar_values[messages.Pos(3,0)] = 11 self.ai.jradar_values[messages.Pos(-3,0)] = 11 points = set(self.ai.get_biggest_jradar_points()) expected_points = set([ (messages.Pos(x=0, y=0), 67) ]) self.assertEqual(points, expected_points)
def test_increase_jradar_values(self): self.ai.reset_jradar_field() self.ai.increase_jradar_values() self.ai.jradar_values[messages.Pos(1,1)] = 25 self.ai.jradar_values[messages.Pos(0,0)] = 10 self.ai.increase_jradar_values() self.ai.increase_jradar_values() for key, value in self.ai.jradar_values.items(): if key == messages.Pos(1,1): self.assertEqual(value, 27) elif key == messages.Pos(0,0): self.assertEqual(value, 12) else: self.assertEqual(value, 4) self.assertEqual(self.ai.get_biggest_jradar()[1], 27)
def get_single_biggest_jradar_points(self): points = self.get_biggest_jradar_points() if len(points) == 1: return points[0] elif len(points) >= 2: return random.choice(points) return (messages.Pos(0, 0), 0) # This should never happen
def test_get_positions_in_range_2(self): positions = set(self.ai.get_positions_in_range(1, 1, 3)) expected_positions = set([ messages.Pos(x=1, y=1) ]) self.assertEqual(len(positions), 37) self.assertTrue(expected_positions.issubset(positions))
def test_reset_jradar_field(self): self.ai.reset_jradar_field() self.ai.jradar_values[messages.Pos(1,0)] = 25 self.ai.jradar_values[messages.Pos(0,0)] = 25 self.ai.jradar_values[messages.Pos(0,1)] = 25 self.ai.reset_jradar_field() self.assertEqual(self.ai.jradar_values[messages.Pos(1,0)], self.ai.jradar_initial_value) self.assertEqual(self.ai.jradar_values[messages.Pos(0,0)], self.ai.jradar_initial_value) self.assertEqual(self.ai.jradar_values[messages.Pos(0,1)], self.ai.jradar_initial_value) self.assertEqual(self.ai.jradar_values[messages.Pos(1,1)], self.ai.jradar_initial_value)
def test_get_positions_in_origo_range(self): positions = set(self.ai.get_positions_in_range(x=0, y=0, radius=1)) expected_positions = set(( messages.Pos(x=0, y=0), messages.Pos(x=0, y=-1), messages.Pos(x=1, y=-1), messages.Pos(x=1, y=0), messages.Pos(x=0, y=1), messages.Pos(x=-1, y=1), messages.Pos(x=-1, y=0), )) self.assertEqual(positions, expected_positions)
def test_get_positions_in_range_3(self): positions = set(self.ai.get_positions_in_range(0, 0, 1)) expected_positions = set([ messages.Pos(x=0, y=0), messages.Pos(x=1, y=0), messages.Pos(x=0, y=1), messages.Pos(x=-1, y=1), messages.Pos(x=-1, y=0), messages.Pos(x=0, y=-1), messages.Pos(x=1, y=-1) ]) self.assertEqual(positions, expected_positions)
def test_get_positions_in_non_origo_range(self): positions = set(self.ai.get_positions_in_range(x=2, y=-3, radius=1)) expected_positions = set(( messages.Pos(x=2, y=-3), messages.Pos(x=2, y=-4), messages.Pos(x=3, y=-4), messages.Pos(x=3, y=-3), messages.Pos(x=2, y=-2), messages.Pos(x=1, y=-2), messages.Pos(x=1, y=-3), )) self.assertEqual(positions, expected_positions)
def test_circle_on_field(self): positions = set( self.ai.circle_on_field(x=13, y=0, radius=2, field_radius=14)) expected_positions = set(( messages.Pos(x=14, y=-2), messages.Pos(x=13, y=-2), messages.Pos(x=12, y=-1), messages.Pos(x=11, y=0), messages.Pos(x=11, y=1), messages.Pos(x=11, y=2), messages.Pos(x=12, y=2), )) self.assertEqual(positions, expected_positions)
def triangle_points(self, x, y, radius=1): points = [] # 2 different possibilities, random between them choise = random.randint(1, 2) if choise == 1: points.append(self.northeast(x, y, radius)) points.append(self.southeast(x, y, radius)) points.append(self.west(x, y, radius)) elif choise == 2: points.append(self.northwest(x, y, radius)) points.append(self.southwest(x, y, radius)) points.append(self.east(x, y, radius)) else: # Fallback, should never happen, 3 same points to given coordinates for i in range(0, 3): points.append(messages.Pos(x, y)) return points
def test_circle_1(self): positions = set(self.ai.circle(x=0, y=0, radius=1)) expected_positions = set(( messages.Pos(x=1, y=0), messages.Pos(x=0, y=1), messages.Pos(x=-1, y=1), messages.Pos(x=-1, y=0), messages.Pos(x=0, y=-1), messages.Pos(x=1, y=-1), )) self.assertEqual(positions, expected_positions)
def test_reset_jradar(self): self.ai.reset_jradar_field() self.ai.increase_jradar_values() self.ai.increase_jradar_values() self.ai.jradar_values[messages.Pos(1,0)] = 25 self.ai.jradar_values[messages.Pos(0,0)] = 10 self.ai.reset_jradar(0,0) self.assertEqual(self.ai.get_biggest_jradar()[1], 3) self.assertEqual(self.ai.jradar_values[messages.Pos(1,0)], self.ai.jradar_initial_value) self.assertEqual(self.ai.jradar_values[messages.Pos(0,0)], self.ai.jradar_initial_value) self.assertEqual(self.ai.jradar_values[messages.Pos(-4,0)], 3) self.assertEqual(self.ai.jradar_values[messages.Pos(0,14)], 3)
def optimal_radars_on_field(self, radar=4): # start from origo points_to_check = set([messages.Pos(0, 0)]) checked_points = set([]) looper = 0 while len(points_to_check) >= 1: looper += 1 if looper >= 50: break p = points_to_check.pop() new_points = set(self.optimal_radar_around(p.x, p.y, radar)) # new points must be in the field new_points &= self.field_points # new points cannot be already checked points new_points -= checked_points points_to_check |= new_points checked_points.add(p) return checked_points
def southeast(self, x=0, y=0, n=1): return messages.Pos(x, y + n)
def test_circle_3(self): positions = set(self.ai.circle(x=1, y=1, radius=3)) expected_positions = set(( messages.Pos(x=4, y=1), messages.Pos(x=3, y=2), messages.Pos(x=2, y=3), messages.Pos(x=1, y=4), messages.Pos(x=0, y=4), messages.Pos(x=-1, y=4), messages.Pos(x=-2, y=4), messages.Pos(x=-2, y=3), messages.Pos(x=-2, y=2), messages.Pos(x=-2, y=1), messages.Pos(x=-1, y=0), messages.Pos(x=0, y=-1), messages.Pos(x=1, y=-2), messages.Pos(x=2, y=-2), messages.Pos(x=3, y=-2), messages.Pos(x=4, y=-2), messages.Pos(x=4, y=-1), messages.Pos(x=4, y=0), )) self.assertEqual(positions, expected_positions)
def west(self, x=0, y=0, n=1): return messages.Pos(x - n, y)
def test_get_positions_in_range_wo_cur_pos_2(self): positions = set(self.ai.get_positions_in_range_wo_cur_pos(1, 1, 3)) expected_positions = set([ messages.Pos(x=1, y=1) ]) self.assertFalse(expected_positions.issubset(positions))
def northwest(self, x=0, y=0, n=1): return messages.Pos(x, y - n)
def northeast(self, x=0, y=0, n=1): return messages.Pos(x + n, y - n)
def test_get_positions_in_range_1(self): positions = set(self.ai.get_positions_in_range(0, 0, 3)) expected_positions = set([ messages.Pos(x=0, y=0) ]) self.assertTrue(expected_positions.issubset(positions))
def get_positions_in_range(self, x=0, y=0, radius=1): for dx in xrange(-radius, radius + 1): for dy in xrange(max(-radius, -dx - radius), min(radius, -dx + radius) + 1): yield messages.Pos(dx + x, dy + y)
def get_positions_in_range_wo_cur_pos(self, x=0, y=0, radius=1): for dx in xrange(-radius, radius + 1): for dy in xrange(max(-radius, -dx - radius), min(radius, -dx + radius) + 1): if dx != 0 and dy != 0: # Force move somewhere yield messages.Pos(dx + x, dy + y)
def pos_on_field(self, x=0, y=0, field_radius=14): if messages.Pos(x, y) in self.field_points: return True return False
def southwest(self, x=0, y=0, n=1): return messages.Pos(x - n, y + n)
def east(self, x=0, y=0, n=1): return messages.Pos(x + n, y)
def move(self, bots, events): """ Move the bot to a random legal positon. Args: bots: List of bot states for own team events: List of events form previous round Returns: List of actions to perform this round. """ response = [] self.round_no += 1 cur_round = Round(self.round_no) cur_round.events = events found = False hit = False my_bot_ids = [] for bot in bots: my_bot_ids.append(bot.bot_id) if len(events) >= 1: for e in events: if e.event == "hit": if e.bot_id not in my_bot_ids: # Don't count friendly fire print "HIT: Our bot {} hit to bot {}".format( e.source, e.bot_id) hit = True # If we hit don't loose the bot we hit. Radar the shoot point later. # Default game config and with 1 move radar should catch the bot. radar_this = self.get_last_round( ).get_bot_shoot_coordinate(e.source) print "Interesting point to radar {}".format( radar_this) self.add_radar_this(radar_this) else: print "Friendlyfire: Bot {} shot bot {}".format( e.source, e.bot_id) elif e.event == "die": print "DIE: Bot {} died".format(e.bot_id) elif e.event == "radarEcho": print "RADARECHO" self.last_radar_pos = e.pos self.mode = "hunt" found = True elif e.event == "see": print "SEE" for bot in bots: if bot.bot_id == e.bot_id: print "set bot {} as detected".format(bot.bot_id) bot.detected = True # Hack to radar seen enemies self.add_radar_this(messages.Pos(e.pos.x, e.pos.y)) elif e.event == "detected": print "DETECTED" for bot in bots: if bot.bot_id == e.bot_id: print "set bot {} as detected".format(bot.bot_id) bot.detected = True elif e.event == "damaged": print "DAMAGED" for bot in bots: if bot.bot_id == e.bot_id: print "set bot {} as detected".format(bot.bot_id) bot.detected = True elif e.event == "move": print "MOVE" elif e.event == "end": print "END" elif e.event == "noaction": print "NOACTION" else: print "WARNING: Unknown event" #{'name': u'hunter 1', 'hp': 10, 'pos': Pos(x=6, y=-12), 'alive': True, 'team_id': 0, 'detected': False, 'bot_id': 0} print "Event: {}".format(e.__dict__) if not found: self.last_radar_pos = None self.mode = "radar" else: self.last_radar_pos = None self.mode = "radar" # If the last triangle shot missed try to radar the last triangle middle # point to find the enemy again if self.get_last_round().triangle_shot is not None and not hit: self.add_radar_this(self.get_last_round().triangle_shot) if self.expecting_direct_hit: if not hit: self.enemy_can_flank_counter += 1 if self.enemy_can_flank_counter >= self.enemy_can_flank_counter_limit: self.enemy_can_flank = True else: self.enemy_can_flank_counter = 0 self.expecting_direct_hit = False # Preparations self.alive_bots_no = 0 self.attacking_bots_no = 0 for i, bot in enumerate(bots): print "Bot: {}".format(bot.__dict__) if bot.alive: self.alive_bots_no += 1 if not bot.detected: self.attacking_bots_no += 1 print "{} bots alive and {} will attack".format( self.alive_bots_no, self.attacking_bots_no) radars = [] radaring_bot = False triangle_points = [] for i, bot in enumerate(bots, start=1): # If the bot is dead don't do anything if bot.alive: # Always flank first if bot.detected: print "{} PANIC".format(bot.bot_id) move_pos = self.move_random_max_in_field(bot) response.append(move_pos) bot.move = messages.Pos(move_pos.x, move_pos.y) else: if self.mode == "radar": print "{} radaring".format(bot.bot_id) radar_action = None if len(self.radar_these) > 0: print "POP: {}".format(self.radar_these) radar_pos = self.radar_these.pop(0) # FIFO radar_action = actions.Radar(bot_id=bot.bot_id, x=radar_pos.x, y=radar_pos.y) else: radar_action = self.radar_random_optimal_wall_wo_overlap( bot, radars) radars.append( messages.Pos(radar_action.x, radar_action.y)) response.append(radar_action) bot.radar = messages.Pos(radar_action.x, radar_action.y) else: # hunt if self.attacking_bots_no == 3 or self.enemy_can_flank: if len(triangle_points) == 0: if self.enemy_can_flank and self.attacking_bots_no != 3: triangle_points = self.triangle_points( self.last_radar_pos.x, self.last_radar_pos.y, radius=1) else: triangle_points = self.triangle_points( self.last_radar_pos.x, self.last_radar_pos.y) point_to_shoot = triangle_points[i % 3] print "{} triangle shooting to {}".format( bot.bot_id, point_to_shoot) bot.shoot = point_to_shoot cur_round.triangle_shot = messages.Pos( self.last_radar_pos.x, self.last_radar_pos.y) response.append( self.cannon(bot, point_to_shoot.x, point_to_shoot.y)) else: # Direct shot # One bot always radars if not radaring_bot: radaring_bot = True print "{} radaring".format(bot.bot_id) radar_pos = self.radar(bot, self.last_radar_pos.x, self.last_radar_pos.y) response.append(radar_pos) bot.radar = messages.Pos( radar_pos.x, radar_pos.y) else: self.expecting_direct_hit = True print "{} shooting to {}".format( bot.bot_id, self.last_radar_pos) cannon_pos = self.cannon( bot, self.last_radar_pos.x, self.last_radar_pos.y) response.append(cannon_pos) bot.shoot = messages.Pos( cannon_pos.x, cannon_pos.y) cur_round.bots.append(bot) print "Round {} actions and stuff".format(self.round_no) print cur_round.__dict__ cur_round.print_bots() self.rounds.append(cur_round) return response