예제 #1
0
def state_delta_from_dict(dict_rep: Dict) -> StateDelta:
    """Creates a StateDelta from a specified dictionary representation."""
    leader: agent.Agent = agent.Agent(
        agent_type=environment_objects.ObjectType.LEADER,
        agent_position=position.v3_pos_to_position(
            eval(dict_rep['leader']['position']), environment_util.HEX_WIDTH,
            environment_util.HEX_DEPTH),
        agent_rotation=rotation.degree_to_rotation(
            int(eval(dict_rep['leader']['rotation'])[1])))
    follower: agent.Agent = agent.Agent(
        agent_type=environment_objects.ObjectType.FOLLOWER,
        agent_position=position.v3_pos_to_position(
            eval(dict_rep['follower']['position']), environment_util.HEX_WIDTH,
            environment_util.HEX_DEPTH),
        agent_rotation=rotation.degree_to_rotation(
            int(eval(dict_rep['follower']['rotation'])[1])))
    card_list: List[card.Card] = environment_util.interpret_card_info(
        dict_rep['cards'], environment_util.HEX_WIDTH,
        environment_util.HEX_DEPTH, False)

    return StateDelta(leader, follower, card_list)
예제 #2
0
    def _execute_leader(self, action: agent_actions.AgentAction):
        leader: agent.Agent = self._current_state_delta.leader
        new_position, new_rotation = planner.get_new_player_orientation(
            leader, action, self._obstacle_positions)

        # Set the leader's state
        self._current_state_delta.leader = agent.Agent(
            environment_objects.ObjectType.LEADER, new_position, new_rotation)

        if action in {
                agent_actions.AgentAction.MB, agent_actions.AgentAction.MF
        }:
            self._update_card_with_move(new_position)
예제 #3
0
def main():
    args: program_args.ProgramArgs = util.get_args()
    server_socket: server.ServerSocket = server.ServerSocket('localhost', 3706)
    server_socket.start_unity()

    game_server: unity_game.UnityGame = unity_game.UnityGame(
        args.get_game_args(), server_socket)

    # TODO: may need to get hexes/obstacles because the intersections may not happen if the elevation is wrong
    game_info: state_delta.StateDelta = game_server.get_game_info(True)

    # Then, for each possible position, reset the state
    pos_rot_dict = dict()
    for x in range(25):
        for y in range(25):
            for rot in rotation.Rotation:
                agent_pos: position.Position = position.Position(x, y)
                game_info.follower = agent.Agent(
                    environment_objects.ObjectType.FOLLOWER, agent_pos, rot)
                game_server.reset_state([],
                                        game_info,
                                        0, [],
                                        allow_exceptions=True)

                # Get the visible hexes
                game_server._connection.send_data('status agent')
                data: bytes = game_server._connection.receive_data()
                json_data = json.loads(data.decode('utf-8'))

                visible_positions = []
                for obj in json_data['eyesightInfo']:
                    if obj['prop'].endswith('cell'):
                        pos = position.v3_pos_to_position(
                            eval(obj['propPosV3']), 17.321, 15.)
                        visible_positions.append(pos)

                pos_rot_dict[(agent_pos, rot)] = visible_positions

    server_socket.close()

    with open("agent/preprocessed/visible_positions.pkl", 'wb') as ofile:
        pickle.dump(pos_rot_dict, ofile)
예제 #4
0
def find_path_between_positions(
    avoid_locations: List[position.Position],
    start_config: agent.Agent,
    target_config: agent.Agent,
    ignore_target_rotation: bool = False
) -> Optional[List[Tuple[agent.Agent, agent_actions.AgentAction]]]:
    """Finds a path between two positions in the map.

    Args:
        avoid_locations: A list of locations to avoid, including obstacles and cards that should not be touched.
        start_config: The starting configuration (position/rotation) of the agent.
        target_config: The target configuration (position/rotation) of the agent.
        ignore_target_rotation: Whether the final rotation of the agent matters.
    """
    queue: PositionRotationQueue = PositionRotationQueue()
    queue.put(start_config.get_position(), start_config.get_rotation(), 0)
    paths: Dict[Tuple[position.Position, rotation.Rotation],
                Optional[Tuple[Tuple[position.Position, rotation.Rotation],
                               List[agent_actions.AgentAction]]]] = dict()
    paths[(start_config.get_position(), start_config.get_rotation())] = None

    total_dist: Dict[Tuple[position.Position, rotation.Rotation], int] = dict()
    total_dist[(start_config.get_position(), start_config.get_rotation())] = 0

    has_ended: bool = False
    current_pos_and_rot: Tuple[Optional[position.Position],
                               Optional[rotation.Rotation]] = (None, None)

    while not queue.is_empty():
        current_pos_and_rot: Tuple[position.Position,
                                   rotation.Rotation] = queue.get()
        current_position: position.Position = current_pos_and_rot[0]
        current_rotation: rotation.Rotation = current_pos_and_rot[1]
        if current_position == target_config.get_position():
            has_ended = True
            break

        for next_position in position.get_neighbors(
                current_position, environment_util.ENVIRONMENT_WIDTH,
                environment_util.ENVIRONMENT_DEPTH):
            if next_position not in avoid_locations:
                action_rot_pairs: List[Tuple[
                    List[agent_actions.AgentAction], rotation.
                    Rotation]] = rotation_planner.rotation_possibilities(
                        current_position, next_position, current_rotation)

                # There could be several ways to get from one hex to another by rotation. Iterate through all of them,
                # considering the cost of backwards moves.
                for move_possibility in action_rot_pairs:
                    actions: List[
                        agent_actions.AgentAction] = move_possibility[0]
                    resulting_rotation: rotation.Rotation = move_possibility[1]

                    new_dist: int = total_dist[
                        current_pos_and_rot] + follower_action_cost(actions)

                    move_pair: Tuple[position.Position,
                                     rotation.Rotation] = (next_position,
                                                           resulting_rotation)
                    if new_dist < total_dist.get(move_pair, sys.maxsize):
                        total_dist[move_pair] = new_dist
                        paths[move_pair] = (current_pos_and_rot, actions)
                        priority: int = new_dist + metric.manhattan_distance(
                            target_config.get_position(), next_position)
                        queue.put(next_position, resulting_rotation, priority)

    if not has_ended:
        return None

    final_rotation: rotation.Rotation = current_pos_and_rot[1]
    path_positions: List[position.Position] = []
    actions: List[agent_actions.AgentAction] = []

    while current_pos_and_rot != (start_config.get_position(),
                                  start_config.get_rotation()):
        segment_actions = paths[current_pos_and_rot][1]
        segment_actions.reverse()
        actions += segment_actions
        path_positions.append(current_pos_and_rot[0])
        current_pos_and_rot = paths[current_pos_and_rot][0]

    actions.reverse()
    path_positions.reverse()

    if not ignore_target_rotation and target_config.get_rotation(
    ) != final_rotation:
        num_right: int = 0
        temp_right_rotation: rotation.Rotation = final_rotation
        while temp_right_rotation != target_config.get_rotation():
            num_right += 1
            temp_right_rotation = rotation.rotate_clockwise(
                temp_right_rotation)

        if num_right <= 3:
            actions.extend(
                [agent_actions.AgentAction.RR for _ in range(num_right)])
        else:
            actions.extend(
                [agent_actions.AgentAction.RL for _ in range(6 - num_right)])

    path_positions = [start_config.get_position()] + path_positions

    # Now create an actual list of states and actions
    position_action_list: List[Tuple[agent.Agent,
                                     agent_actions.AgentAction]] = list()
    pos_idx: int = 0
    current_rotation: rotation.Rotation = start_config.get_rotation()
    for action in actions:
        position_action_list.append(
            (agent.Agent(environment_objects.ObjectType.FOLLOWER,
                         path_positions[pos_idx], current_rotation), action))
        if action in {
                agent_actions.AgentAction.MF, agent_actions.AgentAction.MB
        }:
            pos_idx += 1
        elif action in {
                agent_actions.AgentAction.RR, agent_actions.AgentAction.RL
        }:
            if action == agent_actions.AgentAction.RR:
                current_rotation = rotation.rotate_clockwise(current_rotation)
            else:
                current_rotation = rotation.rotate_counterclockwise(
                    current_rotation)
        else:
            raise ValueError('Action should not be generated: ' + str(action))

    # Should end up in the expected rotation.
    if not ignore_target_rotation:
        assert current_rotation == target_config.get_rotation()

    return position_action_list
예제 #5
0
파일: util.py 프로젝트: lil-lab/cerealbar
def construct_object(
        prop_name: str, object_position: position.Position,
        object_rotation: Tuple[str],
        card_info: List[card.Card]) -> environment_objects.EnvironmentObject:
    """ Constructs an environment_objects.EnvironmentObject.

    Inputs:
        prop_name (str): The name of the prop (from Unity)
        position (position.Position): The hex (x,y) position of the object.
        rotation (Tuple[str]): The rotation object (from Unity)
        card_info (List[Card]): A list of cards on the board.

    Returns:
        environment_objects.EnvironmentObject representing the object.

    Raises:
        ValueError, if the prop name does not end with '(Clone)' (as all props in Unity should) or the prop name did not
        match any of the expected object types.
    """
    if not prop_name.endswith('(Clone)'):
        raise ValueError(
            'Prop name should end with the string \'(Clone\'); was ' +
            prop_name)
    upper_prop_name: str = prop_name.replace('(Clone)', '').upper()

    rot_degree = int(float(object_rotation[1]))

    # Iterate through tree and plant types first.
    for tree_type in tree.TreeType:
        if tree_type.value == upper_prop_name:
            return tree.Tree(object_position, rot_degree, tree_type)
    for plant_type in plant.PlantType:
        if plant_type.value == upper_prop_name:
            return plant.Plant(object_position, rot_degree, plant_type)

    if upper_prop_name.startswith('CARDBASE'):
        # Find the card that is in card_info
        for card_rep in card_info:
            if card_rep.get_position() == object_position:
                return card_rep

    elif upper_prop_name.startswith(environment_objects.ObjectType.HUT.value):
        return hut.Hut(object_position,
                       rotation.degree_to_rotation(rot_degree),
                       hut.get_hut_color(upper_prop_name))
    elif upper_prop_name.startswith(
            environment_objects.ObjectType.LAMPPOST.value):
        return structures.Lamppost(object_position, rot_degree)
    elif upper_prop_name.startswith(
            environment_objects.ObjectType.WINDMILL.value):
        return structures.Windmill(object_position,
                                   rotation.degree_to_rotation(rot_degree))
    elif upper_prop_name.startswith(
            environment_objects.ObjectType.TOWER.value):
        return structures.Tower(object_position,
                                rotation.degree_to_rotation(rot_degree))
    elif upper_prop_name.startswith(environment_objects.ObjectType.TENT.value):
        return structures.Tent(object_position,
                               rotation.degree_to_rotation(rot_degree))
    elif upper_prop_name == 'AGENT_HUMAN':
        return agent.Agent(
            environment_objects.ObjectType.LEADER,
            agent_position=object_position,
            agent_rotation=rotation.degree_to_rotation(rot_degree))
    elif upper_prop_name.startswith('AGENT_A'):
        return agent.Agent(
            environment_objects.ObjectType.FOLLOWER,
            agent_position=object_position,
            agent_rotation=rotation.degree_to_rotation(rot_degree))

    raise ValueError('Could not construct object: ' + upper_prop_name)