コード例 #1
0
ファイル: test_graph.py プロジェクト: zaharagirones/pelita
 def test_bfs_to_self(self):
     test_layout = (""" ############
         #0.     #.1#
         ############ """)
     universe = CTFUniverse.create(test_layout, 2)
     al = AdjacencyList(universe.free_positions())
     self.assertEqual([], al.bfs((1, 1), [(1, 1), (2, 1)]))
コード例 #2
0
ファイル: our_player.py プロジェクト: dokato/pelita
class BorderPlayer(AbstractPlayer):
    """ A player that makes moves at random. """

    def find_path(self, thingslist):
        """ finds the path to the nearest object
        *thingslist* - list of tuples with objects positions
        """
        self.adjacency = AdjacencyList(self.current_uni.free_positions())
        try:
            pathd =  self.adjacency.bfs(self.current_pos, thingslist)
        except NoPathException:
            return None
        return pathd

    def read_score(self):
        self.score_history[0, self.round_index] = self.current_uni.teams[0].score
        self.score_history[1, self.round_index] = self.current_uni.teams[1].score

    def get_move(self):
        border_path =  self.find_path(self.team_border)
        self.say("Border!!!!")
        if len(border_path)==0:
            return stop
        if border_path==None:
            return stop
        return diff_pos(self.current_pos, border_path.pop())
コード例 #3
0
 def test_bfs_to_self(self):
     test_layout = (
     """ ############
         #0.     #.1#
         ############ """)
     universe = CTFUniverse.create(test_layout, 2)
     al = AdjacencyList(universe.free_positions())
     assert [] == al.bfs((1,1), [(1, 1), (2, 1)])
コード例 #4
0
ファイル: test_graph.py プロジェクト: FrancescAlted/pelita
 def test_bfs_to_self(self):
     test_layout = (
     """ ############
         #0.     #.1#
         ############ """)
     universe = create_CTFUniverse(test_layout, 2)
     al = AdjacencyList(universe)
     self.assertEqual([], al.bfs((1,1), [(1, 1), (2, 1)]))
コード例 #5
0
ファイル: test_graph.py プロジェクト: zaharagirones/pelita
 def test_path_to_same_position(self):
     test_layout = (""" ##################
         #0#.  .  # .     #
         #2#####    #####1#
         #     . #  .  .#3#
         ################## """)
     universe = CTFUniverse.create(test_layout, 4)
     al = AdjacencyList(universe.free_positions())
     self.assertEqual([], al.a_star((1, 1), (1, 1)))
     self.assertEqual([], al.bfs((1, 1), [(1, 1)]))
コード例 #6
0
 def test_path_to_same_position(self):
     test_layout = (
     """ ##################
         #0#.  .  # .     #
         #2#####    #####1#
         #     . #  .  .#3#
         ################## """)
     universe = CTFUniverse.create(test_layout, 4)
     al = AdjacencyList(universe.free_positions())
     assert [] == al.a_star((1, 1), (1, 1))
     assert [] == al.bfs((1, 1), [(1, 1)])
コード例 #7
0
 def test_bfs_exceptions(self):
     test_layout = (""" ############
         #0.     #.1#
         ############ """)
     universe = CTFUniverse.create(test_layout, 2)
     al = AdjacencyList(universe.free_positions())
     with pytest.raises(NoPathException):
         al.bfs((1, 1), [(10, 1)])
     with pytest.raises(NoPathException):
         al.bfs((1, 1), [(10, 1), (9, 1)])
     with pytest.raises(NoPathException):
         al.bfs((0, 1), [(10, 1)])
     with pytest.raises(NoPathException):
         al.bfs((1, 1), [(11, 1)])
コード例 #8
0
 def test_bfs_exceptions(self):
     test_layout = (
     """ ############
         #0.     #.1#
         ############ """)
     universe = CTFUniverse.create(test_layout, 2)
     al = AdjacencyList(universe.free_positions())
     with pytest.raises(NoPathException):
         al.bfs((1, 1), [(10, 1)])
     with pytest.raises(NoPathException):
         al.bfs((1, 1), [(10, 1), (9, 1)])
     with pytest.raises(NoPathException):
         al.bfs((0, 1), [(10, 1)])
     with pytest.raises(NoPathException):
         al.bfs((1, 1), [(11, 1)])
コード例 #9
0
class BFSPlayer(AbstractPlayer):
    """ This player uses breadth first search to always go to the closest food.

    This player uses an adjacency list [1] to store the topology of the
    maze. It will then do a breadth first search [2] to search for the
    closest food. When found, it will follow the determined path until it
    reaches the food. This continues until all food has been eaten or the
    enemy wins.

    The adjacency lits representation (`AdjacencyList`) and breadth first search
    (`AdjacencyList.bfs`) are imported from `pelita.graph`.

    * [1] http://en.wikipedia.org/wiki/Adjacency_list
    * [2] http://en.wikipedia.org/wiki/Breadth-first_search

    """
    def set_initial(self):
        # Before the game starts we initialise our adjacency list.
        self.adjacency = AdjacencyList(self.current_uni)
        self.current_path = self.bfs_food()

    def bfs_food(self):
        """ Breadth first search for food.

        Returns
        -------
        path : a list of tuples (int, int)
            The positions (x, y) in the path from the current position to the
            closest food. The first element is the final destination.

        """
        try:
            return self.adjacency.bfs(self.current_pos, self.enemy_food)
        except NoPathException:
            return [self.current_pos]

    def get_move(self):
        if self.current_pos == self.initial_pos:
            # we have probably been killed
            # reset the path
            self.current_path = None
        if not self.current_path:
            self.current_path = self.bfs_food()
        new_pos = self.current_path.pop()
        return diff_pos(self.current_pos, new_pos)
コード例 #10
0
ファイル: our_player.py プロジェクト: dokato/pelita
class OurPlayer(AbstractPlayer):
    b = "Bonnie"
    c = "Clyde"
    message_list = [\
        (c, "This here's Miss Bonnie Parker. I'm Clyde Barrow. We rob banks."), \
        (b, "Whooee! A man with a record!"), \
        (c, "Hell, you might just be the best damn girl in Texas."), \
        (b, "Go for it Clyde"), \
        (b, "You're good!"), \
        (c, "I ain't good. I'm the best!"), \
        (b, "And modest."), \
        (b, "Hey, that ain't ours!"), \
        (c, "Sure it is."), \
        (b, "But we come in this one."), \
        (c, "That don't mean we have to go home in it!"), \
        (c, "Next time, I'll aim a little lower!"), \
        (b, "Tell them I don't smoke cigars."), \
        (c, "'Least I ain't a liar."), \
        (c, "We got a dollar ninety-eight, and you're laughing!"), \
        ]
    talkcounter = 0
    
    def __init__(self, name):
        self.name = name
        self.mess = ""

    def set_initial(self):
        self.current_strategy = 0
        self.round_index = None
        self.score_history = np.zeros([2, 300])
        self.tracking_idx = None
        self.path = []
        self.memory = deque([], maxlen = 5)
        self.chase_mode = False
        self.border_mode = True
        self.chase_count = 0
        self.FOOD_MIN = len(self.enemy_food)/3

    def find_path(self, thingslist):
        """ finds the path to the nearest object
        *thingslist* - list of tuples with objects positions
        """
        self.adjacency = AdjacencyList(self.current_uni.free_positions())
        try:
            pathd =  self.adjacency.bfs(self.current_pos, thingslist)
        except NoPathException:
            return None
        return pathd

    def read_score(self):
        self.score_history[0, self.round_index] = self.current_uni.teams[0].score
        self.score_history[1, self.round_index] = self.current_uni.teams[1].score

    @property
    def tracking_target(self):
        """ Bot object we are currently tracking. """
        return self.current_uni.bots[self.tracking_idx]

    @property
    def path_to_target(self):
        """ Path to the target we are currently tracking. """
        self.adjacency = AdjacencyList(self.current_uni.free_positions())
        try:
            return self.adjacency.a_star(self.current_pos,
                    self.tracking_target.current_pos)
        except NoPathException:
            return None

    def talk(self):
        mess = OurPlayer.message_list[0]
        if mess[0] == self.name:
            OurPlayer.message_list = OurPlayer.message_list[1:]
            OurPlayer.message_list.append(mess)
            string = mess[0] + ": " + mess[1]
            self.mess = string

    def start_chase(self):
        #self.say("Chase him!")
        self.chase_mode = True
        self.chase_count += 1
        if self.partner:
            self.partner.chase_mode = True
            self.partner.chase_count += 1
    
    def stop_chase(self):
        #self.say("Stopit!")
        self.chase_mode = False
        if self.partner:
            self.partner.chase_mode = False
    
    def go_for_border(self):
        if (self.me.index==0 or self.me.index==1) and self.border_mode:
            bor_u = [x for x in self.team_border if x[1]>x[0]//2 ]
            border_path =  self.find_path(bor_u)
        elif (self.me.index==2 or self.me.index==3) and self.border_mode:
            bor_d = [x for x in self.team_border if x[1]<=x[0]//2]
            border_path =  self.find_path(bor_d)
        else:
            border_path =  self.find_path(self.team_border)
        if len(border_path)==0:
            return stop
        if border_path==None:
            return stop
        return diff_pos(self.current_pos, border_path.pop())

    def go_for_food(self):
        food_path =  self.find_path(self.enemy_food)
        mandist = manhattan_dist(self.me.current_pos, self.partner.me.current_pos)
        if mandist <=3 and self.round_index<100:
            distlst = [x for x in self.enemy_food if manhattan_dist(x, self.partner.me.current_pos)>5]
            food_path =  self.find_path(distlst)
        if food_path==None:
            return self.random_move()
        if len(food_path)==0:
            return self.random_move()
        return diff_pos(self.current_pos, food_path.pop())

    def safe_move(self, next_move, dontwanna=None):
        #get all the enemy bots that are destroyers
        dangerous_enemies = [enemy for enemy in self.enemy_bots if enemy.is_destroyer]
        #get all the positions where you can move to
        valid_pos = self.legal_moves.values()
        #get all the positions where dangerous enemies can move to (a list of two sublists)
        enemy_valid_pos_values = [self.current_uni.legal_moves(enemy.current_pos).values() for enemy in dangerous_enemies]
        #flatten list
        enemy_valid_pos_values = [item for sublist in enemy_valid_pos_values for item in    sublist]
        #convert your planned next move to a position
        next_pos = tuple([sum(x) for x in zip(next_move,self.current_pos)])
        #if your next position intersects with the enemy position
        if next_pos in enemy_valid_pos_values:
            #get all positions you could move to that are not enemy legal moves and are not the current position
            valid_pos = [i for i in valid_pos if i not in enemy_valid_pos_values and i != self.current_pos]
            if dontwanna:
                valid_pos = [i for i in valid_pos if i not in dontwanna]
            #pick any such safe position
            if len(valid_pos) > 0:
                next_pos = self.rnd.choice(valid_pos)
                next_move = tuple([x[0] - x[1] for x in zip(next_pos,self.current_pos)])
                return(next_move)
            #if there are no valid positions, pick a random legal move
            else:
                try:    
                    self.say("".join(["I love you, ",  + str(self.partner.name)]))
                except:
                    pass
                return(self.rnd.choice(list(self.legal_moves.keys())))
        else:
            return(next_move) 
        

    def random_move(self):
        #self.say("Let the fight begin!")

        legal_moves = self.legal_moves
        # Remove stop
        try:
            del legal_moves[stop]
        except KeyError:
            pass
        # now remove the move that would lead to the previous_position
        # unless there is no where else to go.
        if len(legal_moves) > 1:
            for (k,v) in legal_moves.items():
                if v == self.previous_pos:
                    break
            del legal_moves[k]
        # just in case, there is really no way to go to:
        if not legal_moves:
            return stop
        # and select a move at random
        return self.rnd.choice(list(legal_moves.keys()))

    def attack_move(self):
        self.adjacency = AdjacencyList(self.current_uni.free_positions())
        attackpath = []
        if self.tracking_idx is not None:
            # if the enemy is no longer in our zone
            if not self.team.in_zone(self.tracking_target.current_pos):
                self.tracking_idx = None
                return  self.go_for_food()
            # otherwise update the path to the target
            else:
                attackpath = self.path_to_target
        if self.tracking_idx is None:
            # check the enemy positions
            possible_targets = [enemy for enemy in self.enemy_bots
                    if self.team.in_zone(enemy.current_pos)]
            if possible_targets:
                # get the path to the closest one
                try:
                    possible_paths = [(enemy, 
                        self.adjacency.a_star(self.current_pos, enemy.current_pos))
                                      for enemy in possible_targets]
                except NoPathException:
                    return None
            else:
                return None
            if possible_paths:
                closest_enemy, path = min(possible_paths,
                                          key=lambda enemy_path: len(enemy_path[1]))
                self.tracking_idx = closest_enemy.index
        if len(attackpath)==0:
            return self.random_move()
        if len(attackpath)>0 and self.round_index%20==0:
            return self.random_move()
        return diff_pos(self.current_pos, attackpath.pop())
    
    def get_distance_to_me(self, pos):
        return manhattan_dist(self.current_pos, pos)
    
    def get_closest_eatable_enemy_pos(self):
        enemies = [(enemy.current_pos, self.get_distance_to_me(enemy.current_pos)) for enemy in self.enemy_bots if enemy.is_harvester]
        
        if len(enemies) != 0:
            enemies = sorted(enemies, key=lambda x: x[1])
            return enemies[0]
        return None
        

    def get_move(self):
        if OurPlayer.talkcounter % 13 == 0:
            self.talk()
        if OurPlayer.talkcounter % 13 == 10:
            self.mess = ""
            self.partner.mess = ""
        OurPlayer.talkcounter += 1
        self.say(self.mess)

        if self.round_index is None:
            self.round_index = 0
        else:
            self.round_index += 1
        self.read_score()


        #switch both players to chase mode, if both are close but on two sides
        en = self.get_closest_eatable_enemy_pos()
        en = False
        if en:
            other_bot = [x for x in self.team_bots if x != self.me][0]
            dist_enemy_to_other_bot = manhattan_dist(other_bot.current_pos, en[0])

            if (en[1] <= 5) and (dist_enemy_to_other_bot <= 5) and (self.get_distance_to_me(other_bot.current_pos) > en[1]):
                self.start_chase()
                if self.chase_count > 5:
                    self.stop_chase()
            else:
                self.stop_chase()

            if self.chase_mode:
                #self.say("Chasemode")
                return self.safe_move(self.attack_move())
            
        if self.me.is_destroyer:
            
            if self.border_mode:
                m1 = self.go_for_border()
                if m1 != stop:
                    next_move = m1
                else:
                    next_move = self.go_for_food()
                    self.border_mode = False
            else:
                next_move = self.go_for_food()
            am = self.attack_move()
            if am and not self.border_mode and len(self.enemy_food) < self.FOOD_MIN:
                next_move = am
                self.say("".join(["I'm going for them, ", self.partner.name, '!!']))
        else:
            next_move = self.go_for_food()
        final_move = self.safe_move(next_move)
        final_pos = tuple([sum(i) for i in zip(final_move,self.current_pos)])
        self.memory.append(final_pos)
        st = list(set(self.memory))
        if len(self.memory)>4 and len(st) <= 2:
            final_move = self.safe_move(next_move, st) 
            self.memory[-1] = final_move
        return self.safe_move(next_move)
コード例 #11
0
class BasicDefensePlayer(AbstractPlayer):
    """ A crude defensive player.

    Will move towards the border, and as soon as it notices enemies in its
    territory, it will start to track them. When it kills the enemy it returns to
    the border and waits there for more.

    """
    def set_initial(self):
        self.adjacency = AdjacencyList(self.current_uni)
        self.path = self.path_to_border
        self.tracking = None

    @property
    def path_to_border(self):
        """ Path to the closest border position. """
        return self.adjacency.bfs(self.current_pos, self.team_border)

    @property
    def path_to_target(self):
        """ Path to the target we are currently tracking. """
        return self.adjacency.a_star(self.current_pos,
                self.tracking_target.current_pos)

    @property
    def tracking_target(self):
        """ Bot object we are currently tracking. """
        return self.current_uni.bots[self.tracking]

    def get_move(self):
        # if we were killed, for whatever reason, reset the path
        if self.current_pos == self.initial_pos:
            self.current_path = self.path_to_border
        # if we are not currently tracking anything
        if not self.tracking:
            # check the enemy positions
            possible_targets = [enemy for enemy in self.enemy_bots
                    if self.team.in_zone(enemy.current_pos)]
            if possible_targets:
                # get the path to the closest one
                closest_enemy = min([(len(self.adjacency.a_star(self.current_pos,
                    enemy.current_pos)),enemy) for enemy in possible_targets])
                # track that bot by using its index
                self.tracking = closest_enemy[1].index
            else:
                # otherwise keep going if we aren't already underway
                if not self.path:
                    self.path = self.path_to_border
        elif self.tracking:
            # if the enemy is no longer in our zone
            if not self.team.in_zone(self.tracking_target.current_pos):
                self.tracking = None
                self.path = self.path_to_border
            # otherwise update the path to the target
            else:
                self.path = self.path_to_target
        # if something above went wrong, just stand still
        if not self.path:
            return stop
        else:
            return diff_pos(self.current_pos, self.path.pop())