コード例 #1
0
ファイル: extensions.py プロジェクト: lostact/SearchAndDefuse
def _position_get_neighbours(self, world):
    neighbours = [
        Position(x=self.x - 1, y=self.y),
        Position(x=self.x + 1, y=self.y),
        Position(x=self.x, y=self.y - 1),
        Position(x=self.x, y=self.y + 1)
    ]
    valid_neighbours = []
    for neighbour in neighbours:
        if 0 <= neighbour.x < world.width and 0 <= neighbour.y < world.height:
            valid_neighbours.append(neighbour)
    return valid_neighbours
コード例 #2
0
 def seventh_police_strategy(self, agent: Police):
     # Let's find a path from agent's position to one of its circulating areas:
     g = Graph(self.world, (agent.position.y, agent.position.x),
               self._calculate_black_pos(agent))
     _index = self.police_circulate_index[agent.id]
     dest = self.police_circulating_areas[agent.id][_index]
     # Iterating from start to end, then from end to start.
     if _index in [0, len(self.police_circulating_areas[agent.id]) - 1]:
         self.police_circulate_iter[agent.id] *= -1
     if len(self.police_circulating_areas[agent.id]) > 1:
         self.police_circulate_index[
             agent.id] += self.police_circulate_iter[agent.id]
     self.print("Source : (%d, %d)" % (agent.position.y, agent.position.x))
     self.print("Destination : (%d, %d)" % (dest[1], dest[2]))
     path = g.bfs((dest[1], dest[2]), False)
     if path is None:
         return False
     self.path3[agent.id] = path
     self.print(self.path3[agent.id])
     if self.path3[agent.id]:
         if self._move(
                 agent.id,
                 Position(self.path3[agent.id][0][1],
                          self.path3[agent.id][0][0]), agent.position):
             self.path3[agent.id].pop(0)
             return True
         else:
             del self.path3[agent.id]
     else:
         del self.path3[agent.id]
     return False
コード例 #3
0
    def police_move(self, police, target):

        id = police.id

        for p in self.world.polices:
            if p.id == id:
                police = p

        pos = police.position

        # print("police {} from ({} , {}) is going to ({} , {})".format(police.id, pos.x, pos.y, target.x, target.y))

        dist = self.find_dist(pos, target)

        polices_pos = [(p.position.x, p.position.y) for p in self.world.polices]


        node = Position(pos.x, pos.y + 1)
        nodetup = (node.x,node.y)

        if self.check_empty_node(node) and not self.is_bomb(node) and nodetup not in polices_pos and self.find_dist(node, target) + 1 == dist:
            # print(police.id, "Down" ,self.find_dist(node, target) , "<" ,dist , self.check_empty_node(node) , (node.x , node.y))
            self.move(police.id,  ECommandDirection.Down)
            return


        node = Position(pos.x + 1, pos.y)
        nodetup = (node.x, node.y)
        if self.check_empty_node(node) and not self.is_bomb(node) and nodetup not in polices_pos and self.find_dist(node, target) + 1 == dist:
            # print(police.id, "Right" ,self.find_dist(node, target) , "<" ,dist , self.check_empty_node(node) , (node.x , node.y))
            self.move(police.id, ECommandDirection.Right)
            return

        node = Position(pos.x, pos.y - 1)
        nodetup = (node.x, node.y)
        if self.check_empty_node(node) and not self.is_bomb(node) and nodetup not in polices_pos and self.find_dist(node, target) + 1 == dist:
            # print(police.id, "Up" ,self.find_dist(node, target) , "<" ,dist , self.check_empty_node(node) , (node.x , node.y))
            self.move(police.id, ECommandDirection.Up)
            return


        node = Position(pos.x - 1, pos.y)
        nodetup = (node.x, node.y)
        if self.check_empty_node(node) and not self.is_bomb(node) and nodetup not in polices_pos and self.find_dist(node, target) + 1 == dist:
            # print(police.id, "Left" ,self.find_dist(node, target) , "<" ,dist , self.check_empty_node(node) , (node.x , node.y))
            self.move(police.id, ECommandDirection.Left)
            return
コード例 #4
0
 def second_police_strategy(self, agent: Police):
     # Let's continue the path:
     if agent.id in self.path:
         # Walk to bomb or defuse it
         if self.path[agent.id]:
             if self._move(
                     agent.id,
                     Position(self.path[agent.id][0][1],
                              self.path[agent.id][0][0]), agent.position):
                 self.path[agent.id].pop(0)
             else:
                 del self.path[agent.id]
                 return False
         else:
             bomb = self.police_bomb_site[agent.id]
             del self.path[agent.id]
             if not self._defuse(agent.id, Position(bomb[1], bomb[0]),
                                 agent.position):
                 return False
         return True
     return False
コード例 #5
0
 def fifth_terrorist_strategy(self, agent: Terrorist):
     dest = self._terrorist_destination(agent)
     if dest:
         g = Graph(self.world, (agent.position.y, agent.position.x),
                   self._calculate_black_pos(agent))
         path = g.bfs(dest)
         if path:
             # Move!
             if self._move(agent.id, Position(path[0][1], path[0][0]),
                           agent.position):
                 path.pop(0)
                 self.path[agent.id] = path
                 return True
         else:
             # Hey terrorist, you are adjacent to a bombsite... Hurry up and plant!
             del self.terrorist_bomb_site[agent.id]
             if self._plant(agent.id, Position(dest[1], dest[0]),
                            agent.position):
                 return True
             # Your way is closed:) please wait.
     return False
コード例 #6
0
 def fifth_police_strategy(self, agent: Police):
     # Using an extreme police power, sound board!
     sounds = self.sound_board[agent.position.y][agent.position.x]
     # Collecting exact location of a bombsite for a possible hearing sound from agent's position:
     site_pos, dest = [None, None, None], None
     for sound in sounds:
         if sound[0] == ESoundIntensity.Strong:
             site_pos[0] = sound[1], sound[2]
         elif sound[0] == ESoundIntensity.Normal:
             site_pos[1] = sound[1], sound[2]
         elif sound[0] == ESoundIntensity.Weak:
             site_pos[2] = sound[1], sound[2]
     # Listening to server for a sound with priority of strong, normal and week...
     if site_pos[0] and ESoundIntensity.Strong in agent.bomb_sounds:
         self.print("Strong sound bomb found: (%d, %d)" %
                    (site_pos[0][0], site_pos[0][1]))
         dest = site_pos[0]
     elif site_pos[1] and ESoundIntensity.Normal in agent.bomb_sounds:
         self.print("Normal sound bomb found: (%d, %d)" %
                    (site_pos[1][0], site_pos[1][1]))
         dest = site_pos[1]
     '''
     elif site_pos[2] and ESoundIntensity.Weak in agent.bomb_sounds:
         self.print("Weak sound bomb found: (%d, %d)" %(site_pos[2][0], site_pos[2][1]))
         dest = site_pos[2]
     '''
     # Checking that exact destination of a planted bomb is found!
     if dest is None or dest in self.police_defusing_site.values():
         return False
     # Let's go and defuseeee :))
     g = Graph(self.world, (agent.position.y, agent.position.x),
               self._calculate_black_pos(agent))
     path = g.bfs(dest, False)
     if path is None:
         return False
     self.path2[agent.id] = path
     self.police_defusing_site[agent.id] = dest
     if self.path2[agent.id]:
         if self._move(
                 agent.id,
                 Position(self.path2[agent.id][0][1],
                          self.path2[agent.id][0][0]), agent.position):
             self.path2[agent.id].pop(0)
         else:
             del self.path2[agent.id]
             return False
     else:
         del self.path2[agent.id]
         return False
     if agent.id in self.path3:
         del self.path3[agent.id]
     return True
コード例 #7
0
 def third_police_strategy(self, agent: Police):
     # Check each police vision to detect a bomb defusion:
     if self.world.bombs:
         for bomb in self.world.bombs:
             if bomb.defuser_id != -1 or (
                 (bomb.position.y, bomb.position.x)
                     in self.police_defusing_site.values() and
                 (agent.id not in self.police_defusing_site
                  or self.police_defusing_site[agent.id] !=
                  (bomb.position.y, bomb.position.x))):
                 continue
             distance = AI._distance(agent.position, bomb.position)
             if distance <= self.world.constants.police_vision_distance:
                 # Checking wether bomb is going to explode when police arrives
                 g = Graph(self.world, (agent.position.y, agent.position.x),
                           self._calculate_black_pos(agent))
                 path = g.bfs((bomb.position.y, bomb.position.x))
                 if path is None:
                     return True
                 if agent.id in self.path2:
                     del self.path2[agent.id]
                 if agent.id in self.path3:
                     del self.path3[agent.id]
                 self.police_bomb_site[agent.id] = (bomb.position.y,
                                                    bomb.position.x)
                 self.path[agent.id] = path
                 self.police_defusing_site[agent.id] = (bomb.position.y,
                                                        bomb.position.x)
                 if len(
                         self.path[agent.id]
                 ) * 0.5 + self.world.constants.bomb_defusion_time <= bomb.explosion_remaining_time:
                     # Walk to bomb or defuse it
                     if self.path[agent.id]:
                         if self._move(
                                 agent.id,
                                 Position(self.path[agent.id][0][1],
                                          self.path[agent.id][0][0]),
                                 agent.position):
                             self.path[agent.id].pop(0)
                         else:
                             del self.path[agent.id]
                     else:
                         if self._defuse(agent.id, bomb.position,
                                         agent.position):
                             del self.path[agent.id]
                 else:
                     del self.path[agent.id]
                 # Wether police can defuse the bomb or not True can keep the police safe(hold for some cycles) from a path2 leading to the bomb!
                 return True
     return False
コード例 #8
0
 def fourth_police_strategy(self, agent: Police):
     # Let's continue the path2:
     if agent.id in self.path2:
         if self.path2[agent.id]:
             if self._move(
                     agent.id,
                     Position(self.path2[agent.id][0][1],
                              self.path2[agent.id][0][0]), agent.position):
                 self.path2[agent.id].pop(0)
                 return True
             else:
                 del self.path2[agent.id]
         else:
             del self.path2[agent.id]
     return False
コード例 #9
0
 def fourth_terrorist_strategy(self, agent: Terrorist):
     # Continue to your path or plant a bomb
     if agent.id in self.path:
         if self.path[agent.id]:
             path = self.path[agent.id]
             if self._move(agent.id, Position(path[0][1], path[0][0]),
                           agent.position):
                 self.print("Agent %d is moving: (%d, %d) --> (%d, %d)" %
                            (agent.id, agent.position.y, agent.position.x,
                             path[0][0], path[0][1]))
                 path.pop(0)
                 return True
             else:
                 del self.path[agent.id]
         else:
             # Hey terrorist, you are adjacent to a bombsite... Hurry up and plant!
             dest = self.terrorist_bomb_site[agent.id]
             del self.terrorist_bomb_site[agent.id]
             del self.path[agent.id]
             if self._plant(agent.id, Position(dest[1], dest[0]),
                            agent.position):
                 self.print("Agent %d is planting a bomb!" % agent.id)
                 return True
     return False
コード例 #10
0
 def sixth_police_strategy(self, agent: Police):
     if agent.id in self.police_defusing_site:
         del self.police_defusing_site[agent.id]
     # Let's continue the path3:
     if agent.id in self.path3:
         if not self.path3[agent.id]:
             del self.path3[agent.id]
             return False
         if self._move(
                 agent.id,
                 Position(self.path3[agent.id][0][1],
                          self.path3[agent.id][0][0]), agent.position):
             self.path3[agent.id].pop(0)
             return True
         else:
             del self.path3[agent.id]
     return False
コード例 #11
0
    def get_sorted_bombs_list(self, source, number, checked = set() , verifiedBobms = None):  # finds nearest bombs from the source position
        bombs_list = []  # [position]
        if verifiedBobms is not None:
            verifiedBobms = {(b.x,b.y) for b in verifiedBobms}
        Q = queue.Queue()
        Q.put(source)
        adjs = [[0, -1],
                [0, +1],
                [-1, 0],
                [+1, 0]]

        while not Q.empty() and len(bombs_list) < number:

            node = Q.get()  # bfs is checking for bombs from the source to board edges ...

            if (node.x, node.y) in checked:
                continue

            checked.add((node.x, node.y))

            if verifiedBobms is not None:
                if (node.x, node.y) in verifiedBobms:
                    bombs_list.append(node)
                    if (node.x, node.y) != (source.x, source.y):
                        continue


            elif self.is_bomb(node):
                bombs_list.append(node)
                if (node.x, node.y) != (source.x, source.y):
                    continue   # cause we cant see pass the bomb so we dont see its adjs

            for adj in adjs:
                new_node = Position(x=node.x + adj[0], y=node.y + adj[1])
                if self.check_empty_node(new_node):
                    Q.put(new_node)

        return bombs_list
コード例 #12
0
    def find_dist(self, policePos, bombPos):

        posQ = queue.Queue()
        posQ.put(policePos)
        distQ = queue.Queue()
        distQ.put(0)
        checked = set()
        adjs = [[ 0,-1],
                [ 0,+1],
                [-1, 0],
                [+1, 0]]

        policesPos = [(police.position.x, police.position.y) for police in self.world.polices]

        while not posQ.empty():
            node = posQ.get()
            dist = distQ.get()

            if (node.x, node.y) in checked:
                continue
            if (node.x, node.y) in policesPos and (node.x, node.y) != (policePos.x, policePos.y) :
                continue

            checked.add((node.x, node.y))

            for adj in adjs:
                new_node = Position(x=node.x + adj[0], y=node.y + adj[1])

                if (new_node.x, new_node.y) == (bombPos.x, bombPos.y):
                    return dist + 1

                elif self.check_empty_node(new_node) and not self.is_bomb(new_node):
                    posQ.put(new_node)
                    distQ.put(dist + 1)

        # print("could find a way ...100000")
        return 100000
コード例 #13
0
ファイル: ai.py プロジェクト: lostact/SearchAndDefuse
    def decide(self):
        start = time.time()
        print('decide' + ' ' + str(self.current_cycle))
        if self.my_side == 'Police':
            my_agents = self.world.polices
            # return 0
        else:
            my_agents = self.world.terrorists
        # ignore dead agents
        alive_agents = []
        for agent in my_agents:
            if agent.status == EAgentStatus.Dead:
                if self.my_side == 'Terrorist':
                    if self.target_bombsites[agent.id]:
                        if self.target_bombsites[agent.id] in self.bombsites:
                            self.bombsites[self.target_bombsites[agent.id]]['task'] = 0
                            self.bombsites[self.target_bombsites[agent.id]]['status'] = -1
                        self.target_bombsites[agent.id] = None
            else:
                alive_agents.append(agent)
        # update bombsites if terrorists score is changed:
        exploded_bombsites = []
        if self.last_scores['Terrorist'] != self.world.scores['Terrorist']:
            for bombsite in self.bombsites:
                if self.world.board[bombsite[0]][bombsite[1]] == ECell.Empty:   
                    exploded_bombsites.append(bombsite)
            for bombsite in exploded_bombsites:
                del self.bombsites[bombsite]
            if exploded_bombsites:
                print(exploded_bombsites)
                updated,unreachables,bypassed_bombsites_list = False, [], []
                for i,bombsite in enumerate(self.unreachable_bombsites):
                    distance, path, bypassed_bombsites = self._a_star(self.start_pos,bombsite,agent_block=False,bombsite_block=False)
                    if not bypassed_bombsites:
                        self.bombsites[bombsite] = {'size':self.world.board[bombsite[0]][bombsite[1]],'initial_distance':distance, 'status':-2,'task':0,'bscore':0, 'failed':0, 'agent':None,'ert':-1}
                        updated = True
                        print('unreachable opened:',bombsite,self.bombsites[bombsite])
                    else:
                        unreachables.append(bombsite)
                        bypassed_bombsites_list.append((bombsite,bypassed_bombsites))
                self.unreachable_bombsites = unreachables
                if updated:
                    for bombsite in self.bombsites:
                        self.bombsites[bombsite]['bscore'] = 0
                    for bombsite, bypassed_bombsites in bypassed_bombsites_list:
                        bypassed_bombsite = bypassed_bombsites[-1]
                        unreachable_size = self.world.board[bombsite[0]][bombsite[1]]
                        self.bombsites[bypassed_bombsite]['bscore'] += (self.BOMBSITE_COEFFICIENT[unreachable_size] * self.unreachable_bscore_coefficient)
                if self.my_side == 'Police':
                    bombsite_positions = sorted(self.bombsites, key = lambda x: self.bombsites[x]['initial_distance'])
                    self.clusters, self.cluster_centers = kmeans(bombsite_positions, len(my_agents))
                    self.cluster_index = [0] * len(my_agents)
                    print(self.clusters,self.cluster_centers)
        # prevent passing by exploding bombs
        for bomb in self.world.bombs:
            if bomb.explosion_remaining_time == 1:
                for neighbor in  bomb.position.get_neighbours(self.world):
                    self.world.board[neighbor.y][neighbor.x] = ECell.Wall

        if self.my_side == 'Terrorist':
            # update bombsites if bomb(s) is defused
            if self.last_scores['Police'] != self.world.scores['Police']:
                bomb_count = len(self.world.bombs)
                for last_bomb in self.last_bombs:
                    for index,bomb in enumerate(self.world.bombs):
                        if bomb.position == last_bomb.position:
                            break
                        elif index == bomb_count - 1:
                            bombsite_position = self._position_to_tuple(last_bomb.position)
                            if bombsite_position in self.bombsites:
                                self.bombsites[bombsite_position]['status'] = -1
                                self.bombsites[bombsite_position]['failed'] += 2
            self.last_bombs = self.world.bombs


            # choose nearest agent for each bombsite if bombsites number is smaller than agents number
            not_planted_bombsites = 0
            for bombsite in self.bombsites:
                if self.bombsites[bombsite]['status'] != 2:
                    not_planted_bombsites += 1
            if not_planted_bombsites < len(alive_agents):
                for agent_id,agent in enumerate(my_agents):
                    if agent.planting_remaining_time == -1:
                        self.target_bombsites[agent_id] = None

                for bombsite in self.bombsites:
                    if self.bombsites[bombsite]['status'] != 2:
                        min_distance = 1000
                        for agent in alive_agents:
                            if not self.target_bombsites[agent.id]:
                                distance, _ = self._a_star(agent.position,bombsite)
                                if distance < min_distance:
                                    best_agent = agent.id
                                    min_distance = distance
                        self.bombsites[bombsite]['task'] = 1
                        self.target_bombsites[best_agent] = bombsite
            print('targets:',self.target_bombsites)
        else:# police
            # update bombsites status according to sounds and visions
            for bombsite in self.bombsites:
                if self.bombsites[bombsite]['status'] < 0:
                    self.bombsites[bombsite]['status'] += 1
            in_vision_bombs = []
            for bomb in self.world.bombs:
                bombsite = self._position_to_tuple(bomb.position)
                self.bombsites[bombsite]['brt'] = bomb.explosion_remaining_time
                in_vision_bombs.append(bombsite)
            for agent in alive_agents:
                if agent.defusion_remaining_time == -1:
                    for bombsite in self.bombsites:
                        if self.bombsites[bombsite]['status'] >= 0:
                            if self._heuristic(bombsite,agent.position) <= self.world.constants.police_vision_distance:
                                if not bombsite in in_vision_bombs:
                                    if self._heuristic(bombsite,agent.position) == 1:
                                        self.bombsites[bombsite]['status'] = -1 * self.world.constants.bomb_planting_time - 1
                                    else:
                                        self.bombsites[bombsite]['status'] = -2
                                    self.bombsites[bombsite]['task'] = 0
                                else:
                                    self.bombsites[bombsite]['status'] = 2
                sound_counts = {ESoundIntensity.Weak:0,ESoundIntensity.Normal:0,ESoundIntensity.Strong:0}
                in_range_sites = {ESoundIntensity.Weak:[],ESoundIntensity.Normal:[],ESoundIntensity.Strong:[]}
                for sound in agent.bomb_sounds:
                    sound_counts[sound] += 1
                for bombsite in self.bombsites:
                    if self._heuristic(bombsite,agent.position) <= self.world.constants.sound_ranges[ESoundIntensity.Weak]:
                        distance, _ = self._a_star(agent.position, bombsite, not_valid_ecells=[ECell.Wall],agent_block=False)
                        if distance:
                            minimum_distance = self.world.constants.police_vision_distance
                            for sound_kind in self.sound_kinds:
                                if distance <= self.world.constants.sound_ranges[sound_kind] and distance > minimum_distance:
                                    if sound_counts[sound_kind]:
                                        status = self.bombsites[bombsite]['status']
                                        in_range_sites[sound_kind].append((bombsite,status,distance))
                                    else:
                                        self.bombsites[bombsite]['status'] = -2
                                        if self.target_bombsites[agent.id] == bombsite:
                                            self.checked_bombsites[agent.id].append(bombsite)
                                    break
                                minimum_distance = self.world.constants.sound_ranges[sound_kind]
                for sound_kind in self.sound_kinds:
                    if sound_counts[sound_kind] > 0:
                        possibles,sures = [], []
                        for index,(bombsite,status,distance) in enumerate(in_range_sites[sound_kind]):
                            if status >= 2:
                                sures.append(bombsite)
                            elif status >= 0:
                                possibles.append(bombsite)
                        if len(sures) == sound_counts[sound_kind]:
                            for bombsite in possibles:
                                self.bombsites[bombsite]['status'] = -2
                        else:
                            status = int((len(sures) + len(possibles)) <= sound_counts[sound_kind]) + 1
                            for bombsite in possibles:
                                self.bombsites[bombsite]['status'] = status
                                # print(agent.id,'at',agent.position,bombsite,status,in_range_sites)
            for bombsite in self.bombsites:
                if self.bombsites[bombsite]['ert'] > -1:
                    self.bombsites[bombsite]['ert'] -= 1
                elif self.bombsites[bombsite]['status'] == 2:
                    self.bombsites[bombsite]['ert'] = self.world.constants.bomb_explosion_time

        self.last_scores = self.world.scores
        # print(self.bombsites)
        for agent in alive_agents:
            if self.my_side == 'Police':
                bombsite_direction = self._find_bombsite_direction(agent)
                doing_bomb_operation = (agent.defusion_remaining_time != - 1)
                if doing_bomb_operation: # defusing
                    bombsite_position = self._sum_pos_tuples(self.DIR_TO_POS[bombsite_direction],(agent.position.y,agent.position.x))
                    self._agent_print(agent.id, 'Continuing bomb operation')
                    self.bombsites[bombsite_position]['status'] = 2
                    if agent.defusion_remaining_time == 1:
                        self.bombsites[bombsite_position]['status'] =  -1 * self.world.constants.bomb_planting_time - 1
                        self.bombsites[bombsite_position]['task'] = 0
                    continue
                if bombsite_direction:
                    try:
                        multiple = len(bombsite_direction)
                    except:
                        multiple = False
                    if multiple:
                        bombsite_direction = bombsite_direction[0]
                    bombsite_position = self._sum_pos_tuples(self.DIR_TO_POS[bombsite_direction],(agent.position.y,agent.position.x))
                    if self.target_bombsites[agent.id] == bombsite_position or multiple:
                        for bomb in self.world.bombs:
                            if self._position_to_tuple(bomb.position) == bombsite_position:
                                if bomb.explosion_remaining_time < self.world.constants.bomb_defusion_time:
                                    has_time = False
                                else:
                                    has_time = True
                                break
                        if has_time:
                            self._agent_print(agent.id, 'Starting bomb operation')
                            self.defuse(agent.id, bombsite_direction)
                            self.bombsites[bombsite_position]['task'] = 2
                            continue
                        else:
                            # self.scape_bombsite(agent)
                            self._agent_print(agent.id, 'direction: Ignoring bomb due to lack of time :(')
                            self.bombsites[bombsite_position]['status'] = 3
                            self.bombsites[bombsite_position]['task'] = 1
                            self.bombsites[bombsite_position]['agent'] = -1
                if self.world.bombs and not bombsite_direction: # bomb in vision:
                    found = False
                    for bomb in self.world.bombs:
                        bombsite_position = self._position_to_tuple(bomb.position)
                        if self.bombsites[bombsite_position]['task'] < 2 and self.bombsites[bombsite_position]['status'] < 3 and self.target_bombsites[agent.id] == bombsite_position and self._heuristic(agent.position,bombsite_position) <= self.world.constants.police_vision_distance:
                            distance, path = self._a_star(agent.position, bomb.position)
                            time_needed = distance + self.world.constants.bomb_defusion_time
                            if time_needed < bomb.explosion_remaining_time:
                                found = True
                                self.bombsites[bombsite_position]['task'] = 1
                                self.bombsites[bombsite_position]['agent'] = agent.id
                                self.path_move(agent,path)
                                self._agent_print(agent.id, 'Going to defuse.')
                                break
                                # print('time status:',time_needed,bomb.explosion_remaining_time)
                            else:
                                self._agent_print(agent.id, 'Ignoring bomb due to lack of time :(')
                                self.bombsites[bombsite_position]['task'] = 1
                                self.bombsites[bombsite_position]['agent'] = -1
                                self.bombsites[bombsite_position]['status'] = 3

                    if found:
                        continue
                # patrol:
                cluster = self.clusters[agent.id]

                if cluster:
                    best_bombsite, (best_distance, best_path) = self.best_bombsite_patrol(agent)
                    if best_path:
                        if len(best_path) > 1:
                            self.path_move(agent, best_path)
                else:
                    # len(bombsites) < len(agents)
                    pass
            else: # terrorist
                if self.last_position[agent.id] == agent.position:
                    self.gir_count[agent.id] += 1
                else:
                    self.gir_count[agent.id] = 0
                self.last_position[agent.id] = agent.position
                bombsite_direction = self._find_bombsite_direction(agent)
                doing_bomb_operation = agent.planting_remaining_time != -1
                threatened = False
                if ESoundIntensity.Strong in agent.footstep_sounds:
                    self.heard_sound_count[agent.id] += 1
                else:
                    self.heard_sound_count[agent.id] = 0
                if doing_bomb_operation:
                    try:
                        multiple = len(bombsite_direction)
                    except:
                        multiple = False
                    if multiple:
                        bombsite_direction = bombsite_direction[0]
                    bombsite_position = self.target_bombsites[agent.id]
                    if self.heard_sound_count[agent.id] >= (self.world.constants.terrorist_vision_distance - self.world.constants.police_vision_distance):
                        threatened = True
                        # self.heard_sound_count[agent.id] = 0
                    if not threatened:
                        self.gir_count[agent.id] = 0
                        if agent.planting_remaining_time <= 1:
                            self._agent_print(agent.id, 'Finishing bomb operation')
                            self.bombsites[bombsite_position]['task'] = 0
                            self.bombsites[bombsite_position]['status'] = 2
                            self.target_bombsites[agent.id] = None
                        else:
                            self._agent_print(agent.id, 'Continuing bomb operation')
                            self.bombsites[bombsite_position]['task'] = 2
                    else:
                        self._agent_print(agent.id, 'I swear I heard police footsteps, time to look around or maybe scape')
                        if len(self._empty_directions(agent.position)) == 1:
                            self.scape_bombsite(agent)
                        else:
                            self.move(agent.id, agent.position.direction_to(Position(bombsite_position[1],bombsite_position[0])))
                        self.bombsites[bombsite_position]['task'] = 1
                    continue
                if bombsite_direction:
                    bombsite_position = self._sum_pos_tuples(self.DIR_TO_POS[bombsite_direction],(agent.position.y,agent.position.x))
                    threatening_polices = []
                    for police in self.world.polices:
                        distance = self._heuristic(police.position,agent.position)
                        if distance <= self.world.constants.terrorist_vision_distance and police.status == EAgentStatus.Alive:
                            threatening_polices.append(police)
                    if threatening_polices:
                        self.scape_polices(agent,threatening_polices)
                        threatened = True
                        self.bombsites[bombsite_position]['failed'] += 1
                        self._agent_print(agent.id, "I see police(s). I can always plant, Now I must Scape.")
                        continue
                    if not threatened and self.bombsites[bombsite]['task'] != 2:
                        if bombsite_position == self.target_bombsites[agent.id] and self.bombsites[bombsite_position]['failed'] <= 5:
                            self._agent_print(agent.id, "Starting bomb operation, I don't see any polices.")
                            self.plant(agent.id, bombsite_direction)
                            self.bombsites[bombsite_position]['task'] = 2
                            continue
                # go to best bombsite
                if self.gir_count[agent.id] >= 4:
                    self._agent_print(agent.id, "Doing random move because GIR KARDAM !!!")
                    self.move(agent.id, random.choice(self._empty_directions(agent.position)))
                    continue
                best_bombsite, best_distance, best_path = self.best_bombsite_plant(agent)
                if len(best_path) > 1: # there IS a possible bombsite
                    self.bombsites[best_bombsite]['task'] = 1
                    self.target_bombsites[agent.id] = best_bombsite
                    self.last_distance[agent.id] = best_distance
                    self._agent_print(agent.id, 'Going to bombsite.')
                    self.path_move(agent,best_path)
                else: # no bombsites left to plant
                    threatening_polices = []
                    for police in self.world.polices:
                        if self._heuristic(agent.position,police.position) <= self.world.constants.police_vision_distance + 1:
                            threatening_polices.append(police)
                    if threatening_polices:
                        self.scape_polices(agent,threatening_polices)
                        self._agent_print(agent.id, 'Nothing to do, Scaping police(s).')
                        continue
                    else:
                        bombsite_position = self._find_bombsite_direction(agent,possible_only=False)
                        if bombsite_position:
                            self.scape_bombsite(agent)
                            self._agent_print(agent.id, 'Nothing to do, Getting a safe distance with the last planted bomb.')
                            continue
                        else:
                            self._agent_print(agent.id, 'Nothing to do, waiting ZzZzZ...')



        # if self.my_side == 'Police':
        #     for agent_1 in patrol_moves:
        #         for agent_2 in patrol_moves:
        #             if agent_1 != agent_2 and self._position_to_tuple(agent_1.position) == patrol_moves[agent_2] and self._position_to_tuple(agent_2.position) == patrol_moves[agent_1]:
        #                 self.cluster_index[agent_1.id],self.cluster_index[agent_2.id] = self.cluster_index[agent_2.id],self.cluster_index[agent_1.id]
        #                 bombsite_position_1 = self.bombsite_positions[self.cluster_index[agent_1.id]]
        #                 bombsite_position_2 = self.bombsite_positions[self.cluster_index[agent_2.id]]
        #                 _, path_1 = self._a_star(agent_1.position, bombsite_position_1)
        #                 _, path_2 = self._a_star(agent_2.position, bombsite_position_1)
        #                 patrol_moves[agent_1] = path_1[1]
        #                 patrol_moves[agent_2] = path_2[1]
        #     for agent in patrol_moves:
        #         if patrol_moves[agent]:
        #             self.position_move(agent,patrol_moves[agent])
        # else:
        #     print(self.heard_sound_count)
        if self.my_side == 'Police':
            print(self.target_bombsites)
            # print(self.bombsites)
            # for bombsite in self.bombsites:
            #     print(bombsite,'status:',self.bombsites[bombsite]['status'],'task:',self.bombsites[bombsite]['task'],end=',')
            # print()
        end = time.time()
        print('time:',end - start)
コード例 #14
0
ファイル: extensions.py プロジェクト: lostact/SearchAndDefuse
def _position_from_tuple(t):

    return Position(x=t[0], y=t[1])
コード例 #15
0
ファイル: ai.py プロジェクト: lostact/SearchAndDefuse
 def position_move(self,agent,position):
     # try:
         direction = agent.position.direction_to(Position(x=position[1],y=position[0]))
         self.move(agent.id, direction)
         agent.position = Position(x=position[1],y=position[0])
コード例 #16
0
ファイル: ai.py プロジェクト: lostact/SearchAndDefuse
    def _dist_between(self, goal,agent_positions=[],police_positions=[], bombsite_block = True):
        dist_between = 1

        min_distance = 1000
        for police_position in police_positions:
            distance = self._heuristic(goal,police_position)
            if distance < min_distance:
                min_distance = distance
        if min_distance <= self.world.constants.police_vision_distance + 1:
            dist_between += abs(min_distance - (self.world.constants.police_vision_distance + 2)) * 1000
        elif min_distance == self.world.constants.police_vision_distance + 2 and len(self._empty_directions(Position(y=goal[0],x=goal[1]))) == 1:
            dist_between += 2000
        if not bombsite_block:
            if self.world.board[goal[0]][goal[1]] != ECell.Wall and self.world.board[goal[0]][goal[1]] != ECell.Empty:
                dist_between += 100

        return dist_between
コード例 #17
0
ファイル: ai.py プロジェクト: lostact/SearchAndDefuse
    def _a_star(self, start_position, goal_position, valid_ecells=[ECell.Empty],not_valid_ecells=None,agent_block=True,bombsite_block=True):
        start = self._position_to_tuple(start_position)
        goal = self._position_to_tuple(goal_position)
        blocked_by_agent = False

        if not not_valid_ecells:
            check = self._check_valid
            ecells = valid_ecells
        else:
            check = self._check_not_valid
            ecells = not_valid_ecells

        if not bombsite_block:
            ecells = [ECell.Empty]
            for ecell in self.BOMBSITES_ECELL:
                ecells.append(ecell)
        police_positions = []
        agent_positions = []
        if agent_block:
            if self.my_side == 'Police':
                agents = self.world.polices
            else:
                agents = self.world.terrorists
                for police in self.world.polices:
                    if police.status == EAgentStatus.Alive:
                        police_positions.append(police.position)
            for agent in agents:
                if agent.status == EAgentStatus.Alive and self._position_to_tuple(agent.position) != start:
                    agent_positions.append(agent.position)

        closed_set = {}
        # key: position, value: f_score
        open_set = {start: self._heuristic(start, goal)}
        came_from = {}
        g_score = {start: 0}
        min_blocking_distance = 100000
        while open_set:
            current = min(open_set, key=open_set.get)
            if current == goal:
                return self._reconstruct_path(came_from, current, bombsite_block=bombsite_block)

            del open_set[current]
            closed_set[current] = True
            for neighbor_position in Position(x=current[1],y=current[0]).get_neighbours(self.world):
                neighbor = (neighbor_position.y,neighbor_position.x)
                if neighbor in closed_set:
                    continue
                if not check(self.world.board[neighbor[0]][neighbor[1]],ecells) and neighbor != goal:
                    continue
                if agent_block:
                    if neighbor_position in agent_positions:
                        if self._heuristic(goal,neighbor_position) < min_blocking_distance:
                            best_blocking_neighbor = neighbor
                            best_blocking_current = current
                            min_blocking_distance = self._heuristic(goal,neighbor_position) + self._dist_between(neighbor,agent_positions,police_positions)
                            blocked_by_agent = True
                        continue
                tentative_g_score = g_score[current] + self._dist_between(neighbor,agent_positions,police_positions, bombsite_block=bombsite_block)
                if tentative_g_score > 1000:
                    continue
                if neighbor in open_set and tentative_g_score >= g_score[neighbor]:
                    continue

                came_from[neighbor] = current
                g_score[neighbor] = tentative_g_score
                open_set[neighbor] = g_score[neighbor] + self._heuristic(neighbor, goal)
        if blocked_by_agent:
            came_from[best_blocking_neighbor] = best_blocking_current
            return self._reconstruct_path(came_from,best_blocking_neighbor)
        if bombsite_block:
            return None, []
        else:
            return None, [], []
コード例 #18
0
 def first_terrorist_strategy(self, agent: Terrorist):
     # If there's a police near, change direction and run!
     police_positions, police_pos, police = [], None, None
     for polices in self.world.polices:
         if AI._distance(
                 polices.position, agent.position
         ) <= self.world.constants.terrorist_vision_distance:
             police_positions.append(polices.position)
             police = polices
     # Escaping from two or more polices:
     if len(police_positions) > 1:
         escape_directions = self._escape_direction(agent,
                                                    police_positions[0])[1]
         for police_pos in police_positions[1:]:
             escape_directions = list(
                 set(escape_directions)
                 & set(self._escape_direction(agent, police_pos)[1]))
         selected_direction, directions = None, self._empty_directions(
             agent)
         for direction in escape_directions:
             if direction in directions:
                 selected_direction = direction
                 break
         if selected_direction:
             if agent.id in self.terrorist_bomb_site:
                 del self.terrorist_bomb_site[agent.id]
             if agent.id in self.path:
                 del self.path[agent.id]
             self.waiting_counter[agent.id] = 1
             self.move(agent.id, selected_direction)
             self.print("Escaping from two or more polices to: ", end='')
             self.print(selected_direction)
             return True
     elif len(police_positions) == 1:
         police_pos = police_positions[0]
         # A police found around, let's make sure that he/she is defusing a bomb or not:
         for bomb in self.world.bombs:
             if bomb.defuser_id == police.id:
                 # Police is defusing a bomb, let's escape from a better way!
                 self.bomb_defuser_pos = (police.position.y,
                                          police.position.x)
                 black_pos = self._calculate_black_pos(agent)
                 # Although we are not escaping from a police, we should watch out for defuser police position!
                 black_pos.append(self.bomb_defuser_pos)
                 g = Graph(self.world, (agent.position.y, agent.position.x),
                           black_pos)
                 dest = self._terrorist_destination(
                     agent, (police_pos.y, police_pos.x))
                 path = g.bfs(dest)
                 if police.defusion_remaining_time and police.defusion_remaining_time < len(
                         path):
                     aim_point = path[police.defusion_remaining_time - 1]
                     if self._distance(
                             police.position,
                             Position(aim_point[1], aim_point[0])
                     ) > self.world.constants.police_vision_distance:
                         # Escapeeeeeeee.
                         police_pos = None
                         self.terrorist_bomb_site[agent.id] = dest
                         self.path[agent.id] = path
                         break
     '''
     police_pos = None
     for police in self.world.polices:
         if AI._distance(police.position, agent.position) <= self.world.constants.terrorist_vision_distance:
             police_pos = police.position
             '''
     if police_pos:
         selected_direction = self._escape_direction(agent, police_pos)[0]
         if selected_direction:
             if agent.id in self.terrorist_bomb_site:
                 del self.terrorist_bomb_site[agent.id]
             if agent.id in self.path:
                 del self.path[agent.id]
             self.waiting_counter[agent.id] = 1
             self.move(agent.id, selected_direction)
         else:
             # Let's try our chance and speculate where police wants to go after this cycle, then escape!
             stay = False
             for bomb in self.world.bombs:
                 if self._distance(
                         bomb.position, agent.position
                 ) <= self.world.constants.terrorist_vision_distance:
                     stay = True
                     break
             if not stay:
                 g = Graph(self.world, (police_pos.y, police_pos.x))
                 police_path = g.bfs((agent.position.y, agent.position.x))
                 self.print("Police speculated path while escaping:")
                 self.print(police_path)
                 if police_path:
                     selected_direction = self._escape_direction(
                         agent,
                         Position(police_path[0][1], police_path[0][0]))[0]
                     if agent.id in self.terrorist_bomb_site:
                         del self.terrorist_bomb_site[agent.id]
                     if agent.id in self.path:
                         del self.path[agent.id]
                     self.waiting_counter[agent.id] = 1
                     self.move(agent.id, selected_direction)
         return True
     return False
コード例 #19
0
ファイル: ai.py プロジェクト: lostact/SearchAndDefuse
 def path_move(self,agent,path):
     direction = agent.position.direction_to(Position(x=path[1][1],y=path[1][0]))
     self.move(agent.id, direction)
     agent.position = Position(x=path[1][1],y=path[1][0])