示例#1
0
def process_game(root, game):
    try:
        hidden_state = reconstruct_hidden_state(game)
        if len(hidden_state) >= 7:
            return
        print game['id']
        possible = possible_hidden_states(set(hidden_state),
                                          num_players=len(hidden_state))
        perspectives = [
            perspective_from_hidden_states(
                starting_hidden_states(player, hidden_state, possible))
            for player, _ in enumerate(hidden_state)
        ]
        tree_roots = [
            root.setdefault((player, perspective), {
                'move_counts': {},
                'transitions': {}
            }) for player, perspective in enumerate(perspectives)
        ]
        state = AvalonState.start_state(len(hidden_state))
        for round_ in game['log']:
            tree_roots, state = handle_round(tree_roots, state, hidden_state,
                                             round_)
    except AssertionError:
        print game['id'], 'is bad'
示例#2
0
def run_large_tournament(bots_classes, roles, games_per_matching=50):
    print "Running {}".format(' '.join(map(lambda c: c.__name__,
                                           bots_classes)))

    start_state = AvalonState.start_state(len(roles))
    result = []
    all_hidden_states = possible_hidden_states(set(roles),
                                               num_players=len(roles))

    seen_hidden_states = set([])
    for hidden_state in itertools.permutations(roles):
        if hidden_state in seen_hidden_states:
            continue
        seen_hidden_states.add(hidden_state)

        beliefs = [
            starting_hidden_states(player, hidden_state, all_hidden_states)
            for player in range(len(hidden_state))
        ]
        seen_bot_orders = set([])
        for bot_order in itertools.permutations(bots_classes):
            bot_order_str = tuple([bot_cls.__name__ for bot_cls in bot_order])
            if bot_order_str in seen_bot_orders:
                continue
            seen_bot_orders.add(bot_order_str)

            for _ in range(games_per_matching):
                bots = [
                    bot_cls.create_and_reset(start_state, player, role,
                                             beliefs[player])
                    for player, (
                        bot_cls,
                        role) in enumerate(zip(bot_order, hidden_state))
                ]
                values, game_end = run_game(start_state, hidden_state, bots)
                game_stat = {
                    'winner': game_end[0],
                    'win_type': game_end[1],
                }
                for player, (bot_cls,
                             role) in enumerate(zip(bot_order, hidden_state)):
                    game_stat['bot_{}'.format(player)] = bot_cls.__name__
                    game_stat['bot_{}_role'.format(player)] = role
                    game_stat['bot_{}_payoff'.format(player)] = values[player]
                result.append(game_stat)

    df = pd.DataFrame(result, columns=sorted(result[0].keys()))
    df['winner'] = df['winner'].astype('category')
    df['win_type'] = df['win_type'].astype('category')
    for player in range(len(roles)):
        df['bot_{}'.format(player)] = df['bot_{}'.format(player)].astype(
            'category')
        df['bot_{}_role'.format(player)] = df['bot_{}_role'.format(
            player)].astype('category')

    return df
示例#3
0
def run_learning_tournament(bot_classes,
                            winrate_track=None,
                            winrate_window=10000000):
    bots = [(bot_class(), bot_class.__name__, num == winrate_track)
            for num, bot_class in enumerate(bot_classes)]

    hidden_state = ['merlin', 'servant', 'servant', 'assassin', 'minion']
    all_hidden_states = possible_hidden_states(set(hidden_state),
                                               num_players=len(hidden_state))

    beliefs_for_hidden_state = {}
    start_state = AvalonState.start_state(len(hidden_state))

    wins = []
    game_num = 0

    while True:
        game_num += 1
        random.shuffle(hidden_state)
        random.shuffle(bots)
        bot_ids = [bot_name for _, bot_name, _ in bots]

        if tuple(hidden_state) not in beliefs_for_hidden_state:
            beliefs_for_hidden_state[tuple(hidden_state)] = [
                starting_hidden_states(player, tuple(hidden_state),
                                       all_hidden_states)
                for player in range(len(hidden_state))
            ]

        beliefs = beliefs_for_hidden_state[tuple(hidden_state)]

        track_num = None

        bot_objs = []
        for i, (bot, bot_name, track) in enumerate(bots):
            if track:
                track_num = i
            bot.reset(start_state, i, hidden_state[i], beliefs[i])
            bot.set_bot_ids(bot_ids)
            bot_objs.append(bot)

        results, _ = run_game(start_state, tuple(hidden_state), bot_objs)

        for i, (bot, bot_name, track) in enumerate(bots):
            bot.show_roles(hidden_state, bot_ids)

        if track_num is not None:
            wins.append(int(results[track_num] > 0))
            if len(wins) > winrate_window:
                wins.pop(0)

        if game_num % 10 == 0 and winrate_track is not None:
            print "Winrate: {}%".format(100 * float(sum(wins)) / len(wins))
示例#4
0
def read_data_load_counts():
    global counts
    if counts is not None:
        return counts

    if counts is None and os.path.isfile(STRATEGY_DATAFILE):
        with open(STRATEGY_DATAFILE, 'r') as f:
            counts = pickle.load(f)
        return counts

    print "Creating counts data..."
    counts = {
        'propose': defaultdict(zeros_10),
        'vote': defaultdict(zeros_2),
        'run': defaultdict(zeros_2),
        'merlin': defaultdict(zeros_5)
    }

    human_games = load_human_json()
    for game in human_games:
        hidden_state = reconstruct_hidden_state(game)
        if len(hidden_state) != 5 or frozenset(hidden_state) != frozenset(
            ['merlin', 'assassin', 'minion', 'servant']):
            continue
        print game['id']
        start_state = AvalonState.start_state(len(hidden_state))
        fails = []
        perspectives = [
            get_python_perspective(hidden_state, player)
            for player in range(len(hidden_state))
        ]
        for state, moves in game_state_generator(start_state, game,
                                                 hidden_state):
            moving_players = state.moving_players()
            for player, move in zip(moving_players, moves):
                legal_actions = state.legal_actions(player, hidden_state)
                perspective_bucket = get_hidden_states_bucket(
                    perspectives[player], fails)
                index = legal_actions.index(move)
                counts[state.status][(state.as_key(), perspectives[player],
                                      perspective_bucket)][index] += 1

            if state.status == 'run' and any([move.fail for move in moves]):
                fails.append((state.proposal,
                              len([move for move in moves if move.fail])))

    print "Writing counts data..."
    with open(STRATEGY_DATAFILE, 'w') as f:
        pickle.dump(counts, f)

    return counts
示例#5
0
def check_config(config):
    role_counts = defaultdict(lambda: 0)

    start_state = AvalonState.start_state(len(config))

    for bot in config:
        # Count roles
        role_counts[bot['role']] += 1

    assert 'merlin' in role_counts
    assert 'assassin' in role_counts
    for role, count in role_counts.items():
        assert role == 'servant' or role == 'minion' or count == 1
        assert role in GOOD_ROLES or role in EVIL_ROLES
def determine_reachable(base_bot, roles, num_players):
    hidden_state_to_index = {
        hs: i for i, hs in enumerate(possible_hidden_states(roles, num_players))
    }

    possible = possible_hidden_states(roles, num_players)

    start_state = AvalonState.start_state(num_players)
    cache = {}

    for hidden_state in hidden_state_to_index:
        for player in range(num_players):
            starting_belief = get_starting_belief(hidden_state, player, hidden_state_to_index)
            determine_reachable_from_belief_state(cache, start_state, starting_belief, player, hidden_state_to_index)

    print len(cache)
示例#7
0
def run_large_tournament_parallel(pool,
                                  bots_classes,
                                  roles,
                                  games_per_matching=50):
    print "Running {}".format(' '.join(map(lambda c: c.__name__,
                                           bots_classes)))

    start_state = AvalonState.start_state(len(roles))
    async_results = []
    all_hidden_states = possible_hidden_states(set(roles),
                                               num_players=len(roles))

    seen_hidden_states = set([])
    for hidden_state in itertools.permutations(roles):
        if hidden_state in seen_hidden_states:
            continue
        seen_hidden_states.add(hidden_state)

        beliefs = [
            starting_hidden_states(player, hidden_state, all_hidden_states)
            for player in range(len(hidden_state))
        ]
        seen_bot_orders = set([])
        for bot_order in itertools.permutations(bots_classes):
            bot_order_str = tuple([bot_cls.__name__ for bot_cls in bot_order])
            if bot_order_str in seen_bot_orders:
                continue
            seen_bot_orders.add(bot_order_str)

            for _ in range(games_per_matching):
                async_result = pool.apply_async(
                    large_tournament_parallel_helper,
                    (bot_order, hidden_state, beliefs, start_state))
                async_results.append(async_result)

    result = [async_result.get() for async_result in async_results]

    df = pd.DataFrame(result, columns=sorted(result[0].keys()))
    df['winner'] = df['winner'].astype('category')
    df['win_type'] = df['win_type'].astype('category')
    for player in range(len(roles)):
        df['bot_{}'.format(player)] = df['bot_{}'.format(player)].astype(
            'category')
        df['bot_{}_role'.format(player)] = df['bot_{}_role'.format(
            player)].astype('category')

    return df
示例#8
0
def run_single_threaded_tournament(config, num_games=1000, granularity=100):
    tournament_statistics = {
        'bots': [{
            'bot': bot['bot'].__name__,
            'role': bot['role'],
            'wins': 0,
            'total': 0,
            'win_percent': 0,
            'payoff': 0.0
        } for bot in config],
        'end_types': {}
    }

    hidden_state = tuple([bot['role'] for bot in config])
    all_hidden_states = possible_hidden_states(set(hidden_state),
                                               num_players=len(config))
    beliefs = [
        starting_hidden_states(player, hidden_state, all_hidden_states)
        for player in range(len(config))
    ]

    start_state = AvalonState.start_state(len(hidden_state))
    bots = [bot['bot']() for bot in config]

    # pool = multiprocessing.Pool()
    results = []

    for i in range(num_games):
        if i % granularity == 0:
            print i
        for player, (bot, c) in enumerate(zip(bots, config)):
            bot.reset(start_state, player, c['role'], beliefs[player])

        payoffs, end_type = run_game(start_state, hidden_state, bots)
        tournament_statistics['end_types'][
            end_type] = 1 + tournament_statistics['end_types'].get(
                end_type, 0)

        for b, payoff in zip(tournament_statistics['bots'], payoffs):
            b['wins'] += 1 if payoff > 0.0 else 0
            b['payoff'] += payoff
            b['total'] += 1

    for b in tournament_statistics['bots']:
        b['win_percent'] = float(b['wins']) / float(b['total'])

    return tournament_statistics
示例#9
0
def process_game(game,
                 bot_class,
                 stats,
                 verbose=True,
                 num_players=None,
                 max_num_players=7,
                 min_game_id=0,
                 max_game_id=50000,
                 roles=None):
    try:
        hidden_state = reconstruct_hidden_state(game)
        if num_players is not None:
            if len(hidden_state) != num_players:
                return
        else:
            if len(hidden_state) >= max_num_players:
                return

        if game['id'] >= max_game_id or game['id'] < min_game_id:
            return

        if roles is not None:
            if not all(role in roles for role in hidden_state):
                return

        if verbose:
            print game['id']
            print hidden_state
        possible = possible_hidden_states(set(hidden_state),
                                          num_players=len(hidden_state))
        perspectives = [
            starting_hidden_states(player, hidden_state, possible)
            for player, _ in enumerate(hidden_state)
        ]
        state = AvalonState.start_state(len(hidden_state))
        bots = [
            bot_class.create_and_reset(state, player, role,
                                       perspectives[player])
            for player, role in enumerate(hidden_state)
        ]
        for round_ in game['log']:
            state = handle_round(game, state, hidden_state, bots, round_,
                                 stats)
    except AssertionError:
        if verbose:
            print game['id'], 'is bad'
示例#10
0
def get_bot_merlin_prediction(bot_class, game):
    hidden_state = reconstruct_hidden_state(game)
    state = AvalonState.start_state(len(hidden_state))

    possible = possible_hidden_states(set(hidden_state),
                                      num_players=len(hidden_state))
    perspectives = [
        starting_hidden_states(player, hidden_state, possible)
        for player, _ in enumerate(hidden_state)
    ]

    assassin_player = hidden_state.index('assassin')
    assassin_perspective = perspectives[assassin_player]
    assassin_bot = bot_class.create_and_reset(state, assassin_player,
                                              'assassin', assassin_perspective)

    for round_ in game['log']:
        state = handle_round(game, state, hidden_state, assassin_bot,
                             assassin_player, round_)

    final_round = game['log'][-1]

    assert 'findMerlin' in final_round
    find_merlin = round_['findMerlin']
    assert find_merlin['assassin'] == assassin_player

    legal_moves = state.legal_actions(assassin_player, hidden_state)
    move_probs = assassin_bot.get_move_probabilities(state, legal_moves)

    return {
        'human_guess': find_merlin['merlin_guess'],
        'bot_human_prob': move_probs[find_merlin['merlin_guess']],
        'correct_guess': hidden_state.index('merlin'),
        'bot_correct_prob': move_probs[hidden_state.index('merlin')],
        'top_pick': np.argmax(move_probs),
        'top_pick_prob': np.max(move_probs),
        'game': game['id'],
        'merlin': game['players'][hidden_state.index('merlin')]['player_id'],
        'assassin':
        game['players'][hidden_state.index('assassin')]['player_id']
    }
示例#11
0
def predict_evil_using_voting_on_game(game, vote_same_if_same_prob, vote_same_if_diff_prob):
    try:
        dataframe_data = []
        hidden_state = reconstruct_hidden_state(game)
        assert len(hidden_state) <= 7
        team = tuple([role in EVIL_ROLES for role in hidden_state])
        avalon_start = AvalonState.start_state(len(hidden_state))
        game_generator = human_game_state_generator(avalon_start, game, hidden_state)

        same_team_prob = np.ones((len(hidden_state), len(hidden_state))) / 2

        vote_count = 0
        mission_num = 0
        who_failed = []
        for old_state, new_state, observation in game_generator:
            if old_state.status == 'run':
                mission_num += 1
                if old_state.fails > new_state.fails:
                    who_failed.append((old_state.proposal, observation))
            if old_state.status == 'vote':
                vote_count += 1
                update_pairings(observation, vote_same_if_same_prob, vote_same_if_diff_prob, same_team_prob)
                (nll_picked, pick), nll_correct = most_likely_team(same_team_prob, len(hidden_state), who_failed, team)
                dataframe_data.append({
                    'game': game['id'],
                    'num_players': len(hidden_state),
                    'vsis_prob': vote_same_if_same_prob,
                    'vsid_prob': vote_same_if_diff_prob,
                    'mission': mission_num,
                    'vote_count': vote_count,
                    'nll_correct': nll_correct,
                    'nll_picked': nll_picked,
                    'correct': pick == team,
                })
        sys.stdout.flush()
        return dataframe_data
    except ValueError:
        return []
    except AssertionError:
        return []
示例#12
0
def predict_evil_over_human_game(game, as_bot, tremble):
    try:
        print game['id']
        sys.stdout.flush()
        hidden_state = reconstruct_hidden_state(game)
        assert frozenset(hidden_state) == frozenset(['merlin', 'assassin', 'minion', 'servant'])
        avalon_start = AvalonState.start_state(len(hidden_state))
        game_generator = human_game_state_generator(avalon_start, game, hidden_state)
        nll, particles = get_hidden_state_nll_for_game(avalon_start, game_generator, hidden_state, as_bot, tremble)
        data = {
            'bot': as_bot.__name__,
            'game': game['id'],
            'num_players': len(hidden_state),
            'trembling_hand_prob': tremble,
            'nll': nll
        }
        for p in range(len(hidden_state)):
            data['player_{}'.format(p)] = game['players'][p]['player_id']
            data['role_{}'.format(p)] = hidden_state[p]

        return data, particles
    except AssertionError:
        return None, None
示例#13
0
def test_calculate():
    roles = ['merlin', 'assassin', 'minion', 'servant']
    # bot_classes = [ RandomBot, RandomBot, ObserveBot, RandomBot, RandomBot ]
    bot_classes = [ HumanLikeBot ] * 5
    # observation_history = [
    #     # Round 1
    #     ('propose', (1, 2)),
    #     ('vote', (True, True, False, False, False)),
    #     ('propose', (0, 2)),
    #     ('vote', (False, True, True, True, False)),
    #     ('run', 1),
    #     # Round 2
    #     ('propose', (2, 3, 4)),
    #     ('vote', (False, True, True, True, False)),
    #     ('run', 0),
    #     # Round 3
    #     ('propose', (2, 3)),
    #     ('vote', (False, True, True, True, False)),
    #     ('run', 0),
    #     # Round 4
    #     ('propose', (2, 3, 4)),
    #     ('vote', (False, True, True, True, False)),
    #     ('run', 1),
    #     # Round 5
    #     ('propose', (2, 3, 4)),
    #     ('vote', (False, True, True, False, False)),
    #     ('propose', (1, 2, 3)),
    #     ('vote', (True, True, False, False, False)),
    #     ('propose', (0, 1, 3)),
    #     ('vote', (True, False, False, False, True)),
    # ]
    # observation_history = [
    #     # Round 1
    #     ('propose', (0, 4)),
    #     ('vote', (True, True, True, True, False)),
    #     ('run', 1),
    #     # Round 2
    #     ('propose', (1, 3, 4)),
    #     ('vote', (True, True, False, True, False)),
    #     ('run', 1),
    #     # Round 3
    #     ('propose', (1, 2)),
    #     ('vote', (True, True, False, False, False)),
    #     ('propose', (2, 3)),
    #     ('vote', (False, False, True, True, True)),
    #     ('run', 0),
    #     # Round 4
    #     ('propose', (2, 3, 4)),
    #     ('vote', (False, False, True, True, True)),
    #     ('run', 0),
    #     # # Round 5
    #     ('propose', (0, 1, 3)),
    #     ('vote', (True, True, False, False, False)),
    #     ('propose', (1, 3, 4)),
    #     ('vote', (True, True, False, False, False)),
    #     ('propose', (0, 2, 3)),
    #     ('vote', (True, True, False, False, False)),
    #     ('propose', (2, 3, 4)),
    #     ('vote', (False, False, False, True, True)),
    #     ('propose', (2, 3, 4)),
    #     ('vote', (True, True, True, False, True))
    # ]
    observation_history = [
        # Round 1
        ('propose', (0, 4)),
        ('vote', (True, True, True, True, False)),
        ('run', 1),
        # Round 2
        ('propose', (1, 3, 4)),
        ('vote', (True, True, False, True, False)),
        ('run', 1),
        # Round 3
        ('propose', (1, 2)),
        ('vote', (True, True, False, False, False)),
        ('propose', (2, 3)),
        ('vote', (False, False, True, False, True)),
        ('propose', (2, 4)),
        ('vote', (False, False, True, True, True)),
        ('run', 0),
        # Round 4
        ('propose', (2, 3, 4)),
        ('vote', (False, False, True, True, True)),
        ('run', 0),
        # # Round 5
        # person 1
        ('propose', (0, 1, 3)),
        ('vote', (True, True, False, False, False)),
        # person 2
        ('propose', (1, 3, 4)),
        ('vote', (True, True, False, False, False)),
        # person 3
        ('propose', (0, 2, 3)),
        ('vote', (True, True, False, False, False)),
    ]

    hidden_states, lls = calculate_subgame_ll(roles, 5, bot_classes, observation_history, tremble=1e-8)
    lls -= np.max(lls)
    
    probs = np.exp(lls)
    probs /= np.sum(probs)
    multiple = np.max(probs) / 50
    for hidden_state, prob in zip(hidden_states, probs):
        print "{: >10} {: >10} {: >10} {: >10} {: >10}: {prob}".format(*hidden_state, prob='#' * int(prob / multiple))

    print "Solving subgame"
    state = AvalonState(proposer=3, propose_count=3, succeeds=2, fails=2, status='propose', proposal=None, game_end=None, num_players=5)
    solve_subgame(hidden_states, lls, state, iterations=100000)
示例#14
0
def calculate_observation_ll(hidden_state, bot_classes, observation_history, tremble=0.0):
    all_hidden_states = possible_hidden_states(set(hidden_state), num_players=len(hidden_state))
    beliefs = [
        starting_hidden_states(player, hidden_state, all_hidden_states) for player in range(len(hidden_state))
    ]
    state = AvalonState.start_state(len(hidden_state))
    bots = [ bot() for bot in bot_classes ]
    for i, bot in enumerate(bots):
        bot.reset(state, i, hidden_state[i], beliefs[i])

    log_likelihood = 0.0

    for obs_type, obs in observation_history:
        assert obs_type == state.status, "Incorrect matchup {} != {}".format(obs_type, state.status)

        moving_players = state.moving_players()
        moves = []

        if obs_type == 'propose':
            player = moving_players[0]
            legal_actions = state.legal_actions(player, hidden_state)
            move = ProposeAction(proposal=obs)
            index = legal_actions.index(move)
            moves.append(move)
            move_probs = bots[player].get_move_probabilities(state, legal_actions)
            move_probs = (1.0 - tremble) * move_probs + tremble * (np.ones(len(legal_actions))/len(legal_actions))
            log_likelihood += np.log(move_probs[index])
        elif obs_type == 'vote':
            for p, vote_up in zip(moving_players, obs):
                legal_actions = state.legal_actions(p, hidden_state)
                move = VoteAction(up=vote_up)
                index = legal_actions.index(move)
                moves.append(move)
                move_probs = bots[p].get_move_probabilities(state, legal_actions)
                move_probs = (1.0 - tremble) * move_probs + tremble * (np.ones(len(legal_actions))/len(legal_actions))
                log_likelihood += np.log(move_probs[index])
        elif obs_type == 'run':
            bad_guys_on_mission = [p for p in state.proposal if hidden_state[p] in EVIL_ROLES ]
            if len(bad_guys_on_mission) < obs:
                # Impossible - fewer bad than failed
                return np.log(0.0)

            player_fail_probability = {}
            for bad in bad_guys_on_mission:
                legal_actions = state.legal_actions(bad, hidden_state)
                move = MissionAction(fail=True)
                index = legal_actions.index(move)
                move_probs = bots[bad].get_move_probabilities(state, legal_actions)
                move_probs = (1.0 - tremble) * move_probs + tremble * (np.ones(len(legal_actions))/len(legal_actions))
                player_fail_probability[bad] = move_probs[index]


            failure_prob = 0.0
            moves = [ MissionAction(fail=False) ] * len(state.proposal)
            for bad_failers in itertools.combinations(bad_guys_on_mission, r=obs):
                specific_fail_prob = 1.0
                for bad in bad_guys_on_mission:
                    moves[state.proposal.index(bad)] = MissionAction(fail=True) if bad in bad_failers else MissionAction(fail=False)
                    specific_fail_prob *= player_fail_probability[bad] if bad in bad_failers else (1.0 - player_fail_probability[bad])
                failure_prob += specific_fail_prob
            log_likelihood += np.log(failure_prob)

        new_state, _, observation = state.transition(moves, hidden_state)
        for player, bot in enumerate(bots):
            if player in moving_players:
                move = moves[moving_players.index(player)]
            else:
                move = None
            bot.handle_transition(state, new_state, observation, move=move)
        state = new_state
    return log_likelihood
示例#15
0
def run_game_and_create_bots(hidden_state, beliefs, config):
    start_state = AvalonState.start_state(len(hidden_state))
    bots = [bot['bot']() for bot in config]
    for player, (bot, config) in enumerate(zip(bots, config)):
        bot.reset(start_state, player, config['role'], beliefs[player])
    return run_game(start_state, hidden_state, bots)
示例#16
0
def run_and_print_game(config):
    bot_counts = {}
    bot_names = []
    for bot in config:
        base_name = bot['bot'].__name__
        bot_counts[base_name] = bot_counts.get(base_name, 0) + 1
        bot_names.append("{}_{}".format(base_name, bot_counts[base_name]))

    print "       Role |                      Bot | Evil "
    print "----------------------------------------------"
    for name, bconf in zip(bot_names, config):
        print "{: >11} | {: >24} | {: >4}".format(
            bconf['role'], name, 'Yes' if bconf['role'] in EVIL_ROLES else '')

    hidden_state = tuple([bot['role'] for bot in config])
    all_hidden_states = possible_hidden_states(set(hidden_state),
                                               num_players=len(config))
    beliefs = [
        starting_hidden_states(player, hidden_state, all_hidden_states)
        for player in range(len(config))
    ]
    state = AvalonState.start_state(len(hidden_state))
    bots = [bot['bot']() for bot in config]
    for i, bot in enumerate(bots):
        bot.reset(state, i, hidden_state[i], beliefs[i])

    print "=============== Round 1 ================"
    while not state.is_terminal():

        moving_players = state.moving_players()
        moves = [
            bots[player].get_action(state,
                                    state.legal_actions(player, hidden_state))
            for player in moving_players
        ]
        if state.status == 'propose':
            player = moving_players[0]
            legal_actions = state.legal_actions(player, hidden_state)
            move_probs = bots[player].get_move_probabilities(
                state, legal_actions)
            move_prob = move_probs[legal_actions.index(moves[0])]
            print "Proposal #{}. {} proposes ({:0.2f}):".format(
                state.propose_count + 1, bot_names[moving_players[0]],
                move_prob)
            for player in moves[0].proposal:
                print " - {}".format(bot_names[player])
        elif state.status == 'vote':
            for player, move in zip(moving_players, moves):
                legal_actions = state.legal_actions(player, hidden_state)
                move_probs = bots[player].get_move_probabilities(
                    state, legal_actions)
                move_prob = move_probs[legal_actions.index(move)]
                print "{: >24} votes {: <4} ({:0.2f})".format(
                    bot_names[player], 'UP' if move.up else 'DOWN', move_prob)
        elif state.status == 'run':
            print "--- Mission results ---"
            for player, move in zip(moving_players, moves):
                legal_actions = state.legal_actions(player, hidden_state)
                move_probs = bots[player].get_move_probabilities(
                    state, legal_actions)
                move_prob = move_probs[legal_actions.index(move)]
                print "{: >24}: {} ({:0.2f})".format(
                    bot_names[player], 'FAIL' if move.fail else 'SUCCEED',
                    move_prob)
        elif state.status == 'merlin':
            print "===== Final chance: pick merlin! ====="
            assassin = hidden_state.index('assassin')
            legal_actions = state.legal_actions(assassin, hidden_state)
            move_probs = bots[assassin].get_move_probabilities(
                state, legal_actions)
            move_prob = move_probs[legal_actions.index(moves[0])]
            assassin_pick = moves[assassin].merlin
            print '{} picked {} - {}! ({:0.2f})'.format(
                bot_names[assassin], bot_names[assassin_pick], 'CORRECT'
                if assassin_pick == hidden_state.index('merlin') else 'WRONG',
                move_prob)

        new_state, _, observation = state.transition(moves, hidden_state)
        for player, bot in enumerate(bots):
            if player in moving_players:
                move = moves[moving_players.index(player)]
            else:
                move = None
            bot.handle_transition(state, new_state, observation, move=move)

        if state.status == 'run' and new_state.status == 'propose':
            print "=============== Round {} ================".format(
                new_state.succeeds + new_state.fails + 1)

        state = new_state

    print state.game_end
示例#17
0
def replay_game(game):
    roles = game['game_info']['roles']
    roles = roles[:1] + roles[1:][::-1]
    hidden_state = [PRO_TO_HS[r] for r in roles]
    players = game['session_info']['players']

    proposer = [
        'VHleader' in game['game_info']['voteHistory'][player][0][0]
        for player in players
    ].index(True)

    state = AvalonState(
        proposer=proposer,
        propose_count=0,
        succeeds=0,
        fails=0,
        status='propose',
        proposal=None,
        game_end=None,
        num_players=5
    )

    yield None, state, hidden_state

    while not state.is_terminal():
        rnd = state.succeeds + state.fails
        if state.status != 'merlin':
            proposer = [
                'VHleader' in game['game_info']['voteHistory'][player][rnd][state.propose_count]
                for player in players
            ].index(True)
            assert proposer == state.proposer, "{} != {}".format(proposer, state.proposer)
        if state.status == 'propose':
            proposal = tuple(sorted([
                players.index(player)
                for player in players
                if 'VHpicked' in game['game_info']['voteHistory'][player][rnd][state.propose_count]
            ]))
            actions = [ProposeAction(proposal=proposal)]
        elif state.status == 'vote':
            actions = [
                VoteAction(up=(
                    'VHapprove' in game['game_info']['voteHistory'][player][rnd][state.propose_count]
                ))
                for player in players
            ]
        elif state.status == 'run':
            observed_fails = game['game_info']['numFailsHistory'][rnd]
            actions = []
            for player in state.moving_players():
                if hidden_state[player] in set(['merlin', 'servant']):
                    actions.append(MissionAction(fail=False))
                elif observed_fails == 0:
                    actions.append(MissionAction(fail=False))
                else:
                    actions.append(MissionAction(fail=True))
                    observed_fails -= 1
            assert observed_fails == 0
        elif state.status == 'merlin':
            shot_player = players.index(game['game_info']['publicData']['roles']['assassinShotUsername'])
            actions = [PickMerlinAction(merlin=shot_player) for _ in range(5)]

        assert len(actions) == len(state.moving_players())

        new_state, _, obs = state.transition(actions, hidden_state)
        yield state, new_state, obs
        state = new_state