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)
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), {}