def monte_carlo_ai_random_playouts(game_state: GameState, possible_actions: List[Action]) -> Action: """ Uses a Monte Carlo Tree Search with random playouts at the simulation step to determine the best next move :param game_state: Current GameState :param possible_actions: Possible actions to take :return: Next action to take """ # Do not monte carlo search if there is only one potential action if len(possible_actions) == 1: return possible_actions[0] NUM_SIMS = 200 Qsa = {} Nsa = {} Ns = {} visited = set() # Simulate playouts for num_playout in range(NUM_SIMS): mcts_search(game_state, game_state.player_turn, game_state.calculate_worm_count().get(game_state.player_turn), Qsa, Nsa, Ns, visited) s = str(game_state) sorted_actions = sorted(possible_actions, key=lambda a: Nsa.get((s, str(a)), float("-inf"))) return sorted_actions.pop()
def get_change_worm_count(game_state: GameState, player: int, orig_num_worms: int) -> int: """ Returns the difference between the original worm count and the worm count in the current game state for a given player :param game_state: Game state to get current worm counts from :param player: Player number to calculate change in worm count for :param orig_num_worms: Original worm count to calculate against :return: Difference in worm count for player between the current worm count in game_state and orig_num_worms """ worm_counts = game_state.calculate_worm_count() return worm_counts[player] - orig_num_worms