def play_game(players): mprint("BEGINING GAME", 2) mprint(lvl=2) for p in players: p.reset() affections = [0 for _ in players] winner = None while max(affections) < AFFECTION_GOAL: winner = play_round(players, affections, winner) affections[winner] += 1 mprint("END OF GAME", 2) mprint("Final affection scores:", 2) mprint(affections, 2) return affections.index(AFFECTION_GOAL)
def eliminate_player(self, player_idx, reason=None): mprint("Eliminating player %d" % player_idx, 4) if reason: mprint("Reason: %s" % reason, 4) mprint(lvl=4) self.turn_record['eliminated_player'] = player_idx player_state = self.player_states[player_idx] player_state.is_alive = False player_state.graveyard.extend(player_state.hand) player_state.hand = []
def play_tournament(games_per_match): player_match_wins = { cls_idx: 0 for cls_idx, _ in enumerate(PLAYER_CLASSES) } for player_arrangement in permutations(range(len(PLAYER_CLASSES)), 4): players = [ PLAYER_CLASSES[cls_idx](position) for position, cls_idx in enumerate(player_arrangement) ] match_results = play_match(players, games_per_match) mprint("END OF MATCH", 1) mprint("Games won:", 1) mprint(match_results, 1) for match_idx, wins in enumerate(match_results): player_match_wins[player_arrangement[match_idx]] += wins return player_match_wins
def play_round(players, affections, starting_player=None): if starting_player is None: starting_player = randint(0, len(players) - 1) starting_player -= 1 # it's gonna be incremented anyway mprint("BEGINNING ROUND", 4) mprint(lvl=4) game_state = GameState(players, affections) for player_idx, _ in enumerate(players): game_state.deal_card(player_idx) winner = None # play a round while winner is None: # whose turn is it? game_state.advance_current_player() current_player_idx = game_state.current_player_idx current_player = players[current_player_idx] current_player_state = game_state.player_states[current_player_idx] # every turn housekeeping current_player_state.handmaided = False game_state.turn_record = {} game_state.deal_card(current_player_idx) public_game_state = PublicGameState(game_state) mprint(game_state, 4) player_action = current_player.play_turn(current_player_state.hand, public_game_state) player_action = game_state.sanitize_action(player_action) mprint(describe_action(player_action, current_player_idx), 5) mprint(lvl=5) action_error = game_state.get_action_error(player_action) if action_error is not None: game_state.eliminate_player(current_player_idx, action_error) game_state.turn_record = { 'player_idx': current_player_idx, 'action': { 'card': SUICIDE }, 'eliminated_player': current_player_idx } else: # valid move, carry on played_card = player_action['card'] target = player_action.get('target_player') guess = player_action.get('guess') target_player_state = game_state.player_states[ target] if target is not None else None game_state.turn_record = { 'player_idx': current_player_idx, 'action': player_action, 'eliminated_player': None } current_player_state.hand.remove(played_card) current_player_state.graveyard.append(played_card) if played_card == GUARD: if target is not None: if guess in target_player_state.hand: game_state.eliminate_player(target, "guessed by guard") elif played_card == PRIEST: if target is not None: current_player.learn(target, target_player_state.hand, len(game_state.history)) elif played_card == BARON: if target is not None: my_card = current_player_state.hand[0] their_card = target_player_state.hand[0] if my_card != their_card: loser = target if my_card > their_card else current_player_idx game_state.eliminate_player(loser, "outranked in baron-off") elif played_card == HANDMAID: current_player_state.handmaided = True elif played_card == PRINCE: discarded = target_player_state.hand.pop(0) target_player_state.graveyard.append(discarded) if discarded == PRINCESS: game_state.eliminate_player(target, "discarded princess") else: game_state.deal_card(target) elif played_card == KING: if target is not None: my_card = current_player_state.hand.pop() current_player_state.hand.append( target_player_state.hand.pop()) target_player_state.hand.append(my_card) elif played_card == COUNTESS: pass elif played_card == PRINCESS: game_state.eliminate_player(current_player_idx, "played princess") # update history game_state.history.append(game_state.turn_record) # check for winner winner = game_state.get_winner() mprint("Round over. Winner: Player %d" % winner, 3) mprint(lvl=3) return winner
def play_tournament(games_per_match): player_match_wins = { cls_idx: 0 for cls_idx, _ in enumerate(PLAYER_CLASSES) } for player_arrangement in permutations(range(len(PLAYER_CLASSES)), 4): players = [ PLAYER_CLASSES[cls_idx](position) for position, cls_idx in enumerate(player_arrangement) ] match_results = play_match(players, games_per_match) mprint("END OF MATCH", 1) mprint("Games won:", 1) mprint(match_results, 1) for match_idx, wins in enumerate(match_results): player_match_wins[player_arrangement[match_idx]] += wins return player_match_wins PLAYER_CLASSES = [IdiotBot, IdiotBot, IdiotBot, IdiotBot] tourney_results = play_tournament(games_per_match=5) mprint("END OF TOURNAMENT", 1) mprint("Results:", 1) mprint(tourney_results, 1)