def test_pos_within(self): test_layout = ( """ ################## #0#. . # . # #2##### #####1# # . # . .#3# ################## """) universe = CTFUniverse.create(test_layout, 4) al = AdjacencyList(universe.free_positions()) free = set(pos for pos, val in universe.maze.items() if not val) self.assertFalse((0, 0) in al) self.assertRaises(NoPathException, al.pos_within, (0, 0), 0) self.assertFalse((6, 2) in al) self.assertRaises(NoPathException, al.pos_within, (6, 2), 0) self.assertTrue((1, 1) in al) self.assertEqual(set([(1, 1)]), al.pos_within((1, 1), 0)) target = set([(1, 1), (1, 2), (1,3), (2, 3), (3, 3), (3, 3)]) self.assertEqual(target, al.pos_within((1, 1), 5)) # assuming a_star is working properly for pos in target: self.assertTrue(len(al.a_star((1, 1), pos)) < 5) for pos in free.difference(target): self.assertTrue(len(al.a_star((1, 1), pos)) >= 5)
def test_pos_within(self): test_layout = ( """ ################## #0#. . # . # #2##### #####1# # . # . .#3# ################## """) universe = CTFUniverse.create(test_layout, 4) al = AdjacencyList(universe.free_positions()) free = set(universe.maze.pos_of(Free)) self.assertFalse((0, 0) in al) self.assertRaises(NoPathException, al.pos_within, (0, 0), 0) self.assertFalse((6, 2) in al) self.assertRaises(NoPathException, al.pos_within, (6, 2), 0) self.assertTrue((1, 1) in al) self.assertEqual(set([(1, 1)]), al.pos_within((1, 1), 0)) target = set([(1, 1), (1, 2), (1,3), (2, 3), (3, 3), (3, 3)]) self.assertEqual(target, al.pos_within((1, 1), 5)) # assuming a_star is working properly for pos in target: self.assertTrue(len(al.a_star((1, 1), pos)) < 5) for pos in free.difference(target): self.assertTrue(len(al.a_star((1, 1), pos)) >= 5)
def test_pos_within(self): test_layout = ( """ ################## #0#. . # . # #2##### #####1# # . # . .#3# ################## """) universe = CTFUniverse.create(test_layout, 4) al = AdjacencyList(universe.free_positions()) free = {pos for pos, val in universe.maze.items() if not val} assert not ((0, 0) in al) with pytest.raises(NoPathException): al.pos_within((0, 0), 0) assert not ((6, 2) in al) with pytest.raises(NoPathException): al.pos_within((6, 2), 0) assert (1, 1) in al unittest.TestCase().assertCountEqual([(1, 1)], al.pos_within((1, 1), 0)) target = [(1, 1), (1, 2), (1,3), (2, 3), (3, 3)] unittest.TestCase().assertCountEqual(target, al.pos_within((1, 1), 5)) # assuming a_star is working properly for pos in target: assert len(al.a_star((1, 1), pos)) < 5 for pos in free.difference(target): assert len(al.a_star((1, 1), pos)) >= 5
def test_pos_within(self): test_layout = (""" ################## #0#. . # . # #2##### #####1# # . # . .#3# ################## """) universe = CTFUniverse.create(test_layout, 4) al = AdjacencyList(universe.free_positions()) free = {pos for pos, val in universe.maze.items() if not val} assert not ((0, 0) in al) with pytest.raises(NoPathException): al.pos_within((0, 0), 0) assert not ((6, 2) in al) with pytest.raises(NoPathException): al.pos_within((6, 2), 0) assert (1, 1) in al unittest.TestCase().assertCountEqual([(1, 1)], al.pos_within((1, 1), 0)) target = [(1, 1), (1, 2), (1, 3), (2, 3), (3, 3)] unittest.TestCase().assertCountEqual(target, al.pos_within((1, 1), 5)) # assuming a_star is working properly for pos in target: assert len(al.a_star((1, 1), pos)) < 5 for pos in free.difference(target): assert len(al.a_star((1, 1), pos)) >= 5
def test_pos_within(self): test_layout = ( """ ################## #0#. . # . # #2##### #####1# # . # . .#3# ################## """) universe = create_CTFUniverse(test_layout, 4) al = AdjacencyList(universe) free = set(universe.maze.pos_of(Free)) self.assertRaises(NoPositionException, al.pos_within, (0, 0), 0) self.assertRaises(NoPositionException, al.pos_within, (6, 2), 0) self.assertEqual(set([(1, 1)]), al.pos_within((1, 1), 0)) target = set([(1, 1), (1, 2), (1,3), (2, 3), (3, 3), (3, 3)]) self.assertEqual(target, al.pos_within((1, 1), 5)) # assuming a_star is working properly for pos in target: self.assertTrue(len(al.a_star((1, 1), pos)) < 5) for pos in free.difference(target): self.assertTrue(len(al.a_star((1, 1), pos)) >= 5)
class JakovPlayer(AbstractPlayer): def set_initial(self): self.adjacency = AdjacencyList(self.current_uni.reachable([self.initial_pos])) self.next_food = None def goto_pos(self, pos): return self.adjacency.a_star(self.current_pos, pos)[-1] def get_move(self): # check, if food is still present if (self.next_food is None or self.next_food not in self.enemy_food): if not self.enemy_food: # all food has been eaten? ok. i’ll stop return datamodel.stop self.next_food = self.rnd.choice(self.enemy_food) # !!! to improve: not random from all enemy_food by from closest food # determine enemy positions dangerous & killable dangerous_enemy_pos = [bot.current_pos for bot in self.enemy_bots if bot.is_destroyer] non_noisy_dangerous_enemy_pos = [bot.current_pos for bot in self.enemy_bots if (bot.is_destroyer and not bot.noisy)] # killable_enemy_pos = [bot.current_pos for bot in self.enemy_bots if bot.is_harvester] try: next_pos = self.goto_pos(self.next_food) # next_pos = self.rnd.choice([(0,1),(0,-1),(1,0),(-1,0)]) move = diff_pos(self.current_pos, next_pos) my_adjecent_pos = self.adjacency.pos_within(self.current_pos,5) legal_moves = self.legal_moves # check if the next position is dangerous # list of dangerous enemy adecent positions # dangerous_enemy_adj_pos = [] acceptable_adjecent_pos = list(my_adjecent_pos) # for position in dangerous_enemy_pos: for position in non_noisy_dangerous_enemy_pos: dangerous_enemy_adj_pos = self.adjacency.pos_within(position,3) for enemy_adj_pos in dangerous_enemy_adj_pos: if enemy_adj_pos in acceptable_adjecent_pos: acceptable_adjecent_pos.remove(enemy_adj_pos) # TODO: improve to -> escape to the direction oposite from the enemy if len(acceptable_adjecent_pos) == 0: return self.rnd.choice(list(legal_moves.keys())) if next_pos not in my_adjecent_pos: next_pos = self.rnd.choice(list(my_adjecent_pos)) move = diff_pos(self.current_pos, next_pos) # Remove stop # try: # del legal_moves[datamodel.stop] # except KeyError: # pass # # now remove the move that would lead to the enemy # # unless there is no where else to go. # if len(legal_moves) > 1: # for (k,v) in legal_moves.items(): # if v in dangerous_enemy_pos: # break # del legal_moves[k] # # just in case, there is really no way to go to: # if not legal_moves: # return datamodel.stop # # and select a move at random # return self.rnd.choice(list(legal_moves.keys())) # selecting one of the moves # while next_pos in dangerous_enemy_pos: # move = self.rnd.choice(possible_moves) # next_pos = (self.current_pos[0] + move[0],self.current_pos[1] + move[1]) self.say("bla bla!") return move except NoPathException: return datamodel.stop
class UniverseNoiser(object): """ Class to make bot positions noisy. Supports uniform noise in maze space. Can be extended to support other types of noise. Noise will only be applied if the enemy bot is with a certain threshold (`sight_distance`). Parameters ---------- universe : CTFUniverse the universe which will later be used noise_radius : int, optional, default: 5 the radius for the uniform noise sight_distance : int, optional, default: 5 the distance at which noise is no longer applied. Attributes ---------- adjacency : AdjacencyList adjacency list representation of the Maze """ def __init__(self, universe, noise_radius=5, sight_distance=5): self.adjacency = AdjacencyList(universe) self.noise_radius = noise_radius self.sight_distance = sight_distance def uniform_noise(self, universe, bot_index): """ Apply uniform noise to the enemies of a Bot. Given a `bot_index` the method looks up the enemies of this bot. It then adds uniform noise in maze space to the enemy positions. If a position is noisy or not is indicated by the `noisy` attribute in the Bot class. The method will modify the reference, therefore it is important to use a copy of the universe as an argument. Parameters ---------- universe : CTFUniverse the universe to add noise to bot_index : int the bot whose enemies should be noisy Returns ------- noisy_universe : CTFUniverse universe with noisy enemy positions """ bot = universe.bots[bot_index] bots_to_noise = universe.enemy_bots(bot.team_index) for b in bots_to_noise: # Check that the distance between this bot and the enemy is larger # than `sight_distance`. if len(self.adjacency.a_star(bot.current_pos, b.current_pos)) > self.sight_distance: # If so then alter the position of the enemy possible_positions = list(self.adjacency.pos_within(b.current_pos, self.noise_radius)) b.current_pos = random.choice(possible_positions) b.noisy = True return universe