예제 #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)
예제 #2
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), {}