def get_saved_game_proto(self):
        """ Tests the generate_saved_game_proto method """
        # Creating players
        player = ModelBasedPlayer(self.adapter)
        rule_player = RuleBasedPlayer(easy_ruleset)
        players = [player, player, player, player, player, player, rule_player]

        def env_constructor(players):
            """ Env constructor """
            env = gym.make('DiplomacyEnv-v0')
            env = LimitNumberYears(env, 5)
            env = RandomizePlayers(env, players)
            env = AutoDraw(env)
            return env

        # Generating game
        saved_game_proto = None
        if os.path.exists(self.saved_game_cache_path):
            with open(self.saved_game_cache_path, 'rb') as file:
                saved_game_proto = read_next_proto(SavedGameProto,
                                                   file,
                                                   compressed=True)

        if saved_game_proto is None:
            saved_game_proto = yield generate_trajectory(
                players, self.reward_fn, self.advantage, env_constructor)
            with open(self.saved_game_cache_path, 'wb') as file:
                write_proto_to_file(file, saved_game_proto, compressed=True)

        # Validating game
        assert saved_game_proto.id
        assert len(saved_game_proto.phases) >= 10

        # Validating policy details
        for phase in saved_game_proto.phases:
            for power_name in phase.policy:
                nb_locs = len(phase.policy[power_name].locs)
                assert (len(phase.policy[power_name].tokens)
                        == nb_locs * TOKENS_PER_ORDER  # Token-based
                        or len(phase.policy[power_name].tokens) == nb_locs
                        )  # Order-based
                assert len(phase.policy[power_name].log_probs) == len(
                    phase.policy[power_name].tokens)
                assert phase.policy[power_name].draw_action in (True, False)
                assert 0. <= phase.policy[power_name].draw_prob <= 1.

        # Validating rewards
        assert saved_game_proto.reward_fn == DefaultRewardFunction().name
        for power_name in saved_game_proto.assigned_powers:
            assert len(saved_game_proto.rewards[power_name].value) == len(
                saved_game_proto.phases) - 1

        # Returning saved game proto for other tests to use
        return saved_game_proto
def show_opening_moves_data(proto_dataset_path):
    """ Displays a list of opening moves for each power on the standard map
        :param proto_dataset_path: The path to the proto dataset
        :return: Nothing
    """
    if not os.path.exists(proto_dataset_path):
        raise RuntimeError('Unable to find Diplomacy dataset at {}'.format(proto_dataset_path))

    # Openings dict
    map_object = Map('standard')
    openings = {power_name: {} for power_name in get_map_powers(map_object)}

    # Loading the phases count dataset to get the number of games
    total = None
    if os.path.exists(PHASES_COUNT_DATASET_PATH):
        with open(PHASES_COUNT_DATASET_PATH, 'rb') as file:
            total = len(pickle.load(file))
    progress_bar = tqdm(total=total)

    # Loading dataset and building database
    LOGGER.info('... Building an opening move database.')
    with open(PROTO_DATASET_PATH, 'rb') as proto_dataset:

        # Reading games
        while True:
            saved_game_proto = read_next_proto(SavedGameProto, proto_dataset, compressed=False)
            if saved_game_proto is None:
                break
            progress_bar.update(1)

            # Only keeping games with the standard map (or its variations)
            if not saved_game_proto.map.startswith('standard'):
                continue

            initial_phase = saved_game_proto.phases[0]
            for power_name in initial_phase.orders:
                orders = initial_phase.orders[power_name].value
                orders = tuple(sorted(orders, key=lambda order: order.split()[1]))      # Sorted by location
                if orders not in openings[power_name]:
                    openings[power_name][orders] = 0
                openings[power_name][orders] += 1

    # Printing results
    for power_name in get_map_powers(map_object):
        print('=' * 80)
        print(power_name)
        print()
        for opening, count in sorted(openings[power_name].items(), key=lambda item: item[1], reverse=True):
            print(opening, 'Count:', count)

    # Closing
    progress_bar.close()
Exemple #3
0
def render_proto_file(file_path, args, compressed=True):
    """ Renders all saved game proto in a proto file
        :param file_path: The path to the proto file
        :param args: The parsed command line arguments
        :param compressed: Boolean that indicates if compression was used.
    """
    dir_path = os.path.dirname(file_path)
    game_count = 0

    # Aborting if file doesn't exist
    if not os.path.exists(file_path):
        print('File {} does not exist.'.format(file_path))
        return

    # Processing filter
    games_to_render = []
    if args.filter:
        for part in args.filter.split(','):
            if '-' in part:
                start, stop = part.split('-')
                games_to_render += list(range(int(start), int(stop) + 1))
            elif ':' in part:
                start, stop, step = part.split(':')
                games_to_render += list(
                    range(int(start),
                          int(stop) + 1, int(step)))
            else:
                games_to_render += [int(part)]

    # Rendering each game in the proto file
    with open(file_path, 'rb') as file:
        while True:
            saved_game_proto = read_next_proto(SavedGameProto, file,
                                               compressed)
            if saved_game_proto is None:
                break
            game_count += 1
            if game_count in games_to_render or (not games_to_render
                                                 and not args.count):
                print('(Game #%d) ' % game_count, end='')
                render_saved_game_proto(saved_game_proto,
                                        dir_path,
                                        prefix='%05d' % game_count,
                                        json_only=args.json)
            if game_count % 100 == 0 and args.count:
                print('... %d games found so far.' % game_count)

    # Printing the number of games in the proto file
    if args.count:
        print('Found %d games in the proto file.' % game_count)
Exemple #4
0
def load_games_from_file(file_path, compressed=False):
    """ Trying to load games stored on disk to resume training
        :param file_path: The path to the protocol buffer file where games can be stored
        :param compressed: Boolean. Indicates if the content is compressed
        :return: A list of `game.SavedGame` proto.
    """
    if not os.path.exists(file_path):
        return []

    # Loading file and getting games
    saved_games_proto = []
    with open(file_path, 'rb') as file:
        while True:
            saved_game_proto = read_next_proto(SavedGameProto, file,
                                               compressed)
            if saved_game_proto is None:
                break
            saved_games_proto += [saved_game_proto]
    return saved_games_proto