Exemple #1
0
    def process(self, map_state: MapState, state: State):
        super().process(map_state, state)

        # if we tried to grab a block previous tick, check if we have actually received it from god.
        if self.pending_goal is not None:
            res = state.get_with_property({'carried_by': map_state.agent_id})
            if res is not None and self.pending_goal['filled']['id'] in [
                    x['obj_id'] for x in res['is_carrying']
            ]:
                goal_id = self.pending_goal['filled']['id']
                self.agent.grab_block([
                    self.pending_goal['priority'],  # priority(order)
                    self.pending_goal['location'],
                    self.pending_goal['filled'],
                    True
                    if goal_id in map_state.carried_blocks.keys() else False
                ])
                map_state.pop_block(goal_id)
            else:
                self.remaining.insert(0, self.pending_goal)
            self.pending_goal = None

        # pickup all blocks and redeliver them
        if self.remaining is None:
            self.remaining = [
                goal_block.copy() for goal_block in map_state.goal_blocks
                if goal_block['filled'] is not None
            ]
            self.remaining.sort(key=lambda goal_block: utils.get_distance(
                map_state.get_agent_location(), goal_block['location']))
            for i, goal_block in enumerate(self.remaining):
                self.remaining[i]['filled'] = map_state.blocks.get(
                    goal_block['filled'])

        # pickup all blocks
        while len(self.remaining) > 0:
            goal_block = self.remaining[0]

            # if we're too far away, temporarily set new destination to get closer to the block and pick it up
            # TODO extract hardcoded distance
            if utils.get_distance(map_state.get_agent_location(),
                                  goal_block['location']) > 1:
                if len(self.navigator.get_all_waypoints()
                       ) == 0 or self.navigator.is_done:
                    self.navigator.reset_full()
                    self.navigator.add_waypoint(goal_block['location'])
                return self.navigator.get_move_action(self.state_tracker), {}

            # otherwise grab this block
            self.pending_goal = goal_block
            self.remaining.remove(goal_block)
            return GrabObject.__name__, {
                'object_id': goal_block['filled']['id']
            }

        next_state = DeliveringState(self.strategy, self.navigator,
                                     self.state_tracker)
        self.agent.change_state(next_state)
        return next_state.process(map_state, state)
Exemple #2
0
    def get_door_order(self):
        """
        Returns the optimal order in which to visit the rooms.
        Starts with the room closest to our current location and iteratively adds the room closest to the last room.
        """
        objects = list(self.state.keys())
        doors = [self.state[obj] for obj in objects if ('door' in obj)]

        ret = []

        current_loc = self.state[self.agent_id]['location']

        while len(doors):
            min_dist = 1e9
            door = None
            for x in doors:
                dist = get_distance(x['location'], current_loc)
                if dist < min_dist:
                    door = x
                    min_dist = dist

            current_loc = door['location']
            doors.remove(door)
            ret.append(door)
        return ret
Exemple #3
0
    def get_grabbable_blocks(self, blocks):
        """
        Return the blocks which the agent is able to pick up, i.e. in the pickup range,
        and that correspond to a drop zone
        """
        ret = []

        for block in blocks:
            if get_distance(block['location'],
                            self.state[self.agent_id]['location']) <= 1:
                for drop in self.left_to_find().values():
                    if self.check_look_same(drop,
                                            self.knowledge[block['obj_id']]):
                        ret.append(block)
                        break

        return ret
Exemple #4
0
    def process(self, map_state: MapState, state: State):
        super().process(map_state, state)

        # if we tried to grab a block previous tick, check if we have actually received it from god.
        if self.pending_block is not None:
            res = state.get_with_property({'carried_by': map_state.agent_id})
            if res is not None and self.pending_block[2]['id'] in [
                    x['obj_id'] for x in res['is_carrying']
            ]:
                self.agent.grab_block(self.pending_block)
                map_state.pop_block(self.pending_block[2])
            self.pending_block = None

        if self.strategy.is_all_blocks_found(map_state):
            next_state = DeliveringState(self.strategy, self.navigator,
                                         self.state_tracker)
            self.agent.change_state(next_state)
            return next_state.process(map_state, state)

        room = map_state.get_room(self.room_id)

        # if just started exploring the room, then initialise the unvisited squares and go towards one of those squares
        if self.unvisited_squares is None:
            self.unvisited_squares = set(room['indoor_area'])

        if len(self.navigator.get_all_waypoints()) == 0:
            self.navigator.add_waypoint(next(iter(self.unvisited_squares)))

        # check if any of the blocks match the goal blocks
        matching_blocks = self.strategy.get_matching_blocks_nearby(map_state)

        # check if the blocks in the room has been visited if so change traverse strategy
        if map_state.are_nearby_blocks_visited():
            map_state.visit_room(self.room_id)
            nearby_agents = map_state.get_nearby_agent(state)
            ability = map_state.agent_ability

            def switch_traverse_order(self):
                next_state = WalkingState(self.strategy, self.navigator,
                                          self.state_tracker)
                next_state.strategy.switch_traverse_order()
                self.agent.change_state(next_state)
                return next_state.process(map_state, state)

            if len(nearby_agents) == 0:
                return switch_traverse_order(self)
            else:
                num_agents_same_ability = sum(
                    [1 for i in nearby_agents if i['ability'] == ability])
                if num_agents_same_ability == 0 and map_state.agent_ability == 3:
                    return switch_traverse_order(self)
                random.seed(map_state.agent_id, version=2)
                if num_agents_same_ability != 0 and random.randint(
                        1, 10) > (10 / num_agents_same_ability):
                    return switch_traverse_order(self)

        for block in filter(lambda b: not b[3], matching_blocks):
            # if we're too far away, temporarily set new destination to get closer to the block and pick it up
            # TODO extract hardcoded distance
            if utils.get_distance(map_state.get_agent_location(),
                                  block[2]['location']) > 1:
                self.navigator.reset_full()
                self.navigator.add_waypoint(block[2]['location'])
                return self.navigator.get_move_action(self.state_tracker), {}

            # otherwise grab this block
            self.navigator.is_done = True
            self.pending_block = block
            return GrabObject.__name__, {'object_id': block[2]['id']}

        # # if full capacity, start delivering
        # # TODO make this smarter by cooperating with other agents
        # if self.strategy.is_all_blocks_found:
        #     self.agent.change_state(DeliveringState(self.strategy, self.navigator, self.state_tracker))
        #     return None, {}

        # update the unvisited squares
        self.__update_visited_squares(map_state.get_agent_location())

        # if we visited all squares in this room, we can go back to walking
        if len(self.unvisited_squares) == 0:
            self.navigator.reset_full()
            map_state.visit_room(self.room_id)
            next_state = WalkingState(self.strategy, self.navigator,
                                      self.state_tracker)
            self.agent.change_state(next_state)
            return next_state.process(map_state, state)

        # if we have already arrived to our destination, choose a new destination from the unvisited squares in the room
        if self.navigator.is_done:
            self.navigator.reset_full()
            self.navigator.add_waypoint(next(iter(self.unvisited_squares)))

        return self.navigator.get_move_action(self.state_tracker), {}
Exemple #5
0
    def decide_on_bw4t_action(self, state: State):

        # Open any nearby closed doors
        if self.phase is Phase.EXPLORING:
            for doorId in self._nearbyDoors(state):
                if not state[doorId]['is_open']:
                    return OpenDoorAction.__name__, {'object_id': doorId}

            current_loc = self.state[self.agent_id]['location']

            if current_loc in self.tiles:
                possible_match = [
                    x for x in self.get_nearby_blocks(self.state) if any([
                        self.check_partially_look_same(x, y)
                        for y in self.left_to_find().values()
                    ])
                ]

                blocks = set(map(lambda x: x['location'], possible_match))

                next_waypoints = list(
                    map(lambda x: x[1],
                        self.navigator.get_upcoming_waypoints()))
                to_remove = list(
                    x for x in next_waypoints
                    if get_distance(x, current_loc) <= self.block_range
                    and x not in blocks)
                new_waypoints = [
                    x for x in next_waypoints if x not in to_remove
                ]
                self.navigator.reset_full()
                self.navigator.add_waypoints(new_waypoints)

        # Try to grab/drop objects if you are in pickup phase
        elif self.phase is Phase.PICKUP:
            return GrabObject.__name__, {
                'object_id': random.choice(self.can_grab)['obj_id']
            }
        elif self.phase is Phase.DROP:
            # Check if the agent is on a drop zone
            if self.targets and self.state[self.agent_id][
                    'location'] == self.state[self.targets[0]]['location']:
                loc = self.state[self.agent_id]['location']
                # Check underneath you
                possible_match = [
                    x for x in self.state.values()
                    if ('location' in x and x['location'] == (loc[0],
                                                              loc[1] + 1))
                ]

                # If there is a wall below or a box is dropped immediately below this tile we can drop our box
                # possible_match == 1 means wall underneath
                if len(possible_match) == 1 or (loc[0], loc[1] +
                                                1) in self.dropped or any([
                                                    x['is_collectable']
                                                    for x in possible_match
                                                    if 'is_collectable' in x
                                                ]):
                    object_id = None

                    # Checks to see if any blocks are placed above current location
                    blocks_above = [
                        x for x in self.get_nearby_blocks(self.state)
                        if x['location'] == (loc[0], loc[1] - 1)
                    ]

                    if blocks_above:
                        try:
                            # Try and get the drop zone corresponding to the location (if it exists)
                            new_target = \
                                [x for x in self.drops if self.drops[x]['location'] == blocks_above[0]['location']][0]
                            # Add the above dropzone to the targets list
                            self.targets.insert(1, new_target)
                            # Update the navigator to go through the drop zone above
                            new_waypoints = [
                                self.drops[new_target]['location']
                            ]
                            new_waypoints.extend(
                                list(
                                    map(
                                        lambda x: x[1],
                                        self.navigator.get_upcoming_waypoints(
                                        ))))
                            self.navigator.reset_full()
                            self.navigator.add_waypoints(new_waypoints)
                            # Grab the object placed above
                            return GrabObject.__name__, {
                                'object_id': blocks_above[0]['obj_id']
                            }
                        except:
                            pass

                    # Select drop zone the agent is standing on
                    for drop in self.drop_to_block:
                        if self.state[drop]['location'] == loc:
                            object_id = drop
                            break

                    self.targets.pop(0)

                    blockid_to_drop = self.drop_to_block[object_id]

                    # Send drop message after the drop action has been executed
                    self.current_action_tick_started = state['World'][
                        'nr_ticks']
                    self.message_queue.append(
                        (dropped, (self, self.knowledge[blockid_to_drop],
                                   state[self.agent_id]['location'])))

                    return DropObject.__name__, {'object_id': blockid_to_drop}
                else:
                    # Wait for someone to drop their object before you drop yours
                    return None, {}

        self.state_tracker.update(state)

        try:
            action = self.navigator.get_move_action(self.state_tracker)
        except:
            return None, {}

        return action, {}