def eval_population_worker(queue: mp.Queue, games_per_chromosome, task_counter_queue: mp.Queue, Opponent): while True: population_path = queue.get() folder_path = os.path.dirname(population_path) folder_name = os.path.basename(folder_path) player_name = folder_name.split("_")[0] Player = get_ga_player(player_name) population = np.load(population_path) N = min(len(population), 20) population_idx = np.random.choice(np.arange(len(population)), N, replace=False) population = population[population_idx] save_matrix = np.empty((2, N), np.float) save_matrix[0] = population_idx scores = save_matrix[1] for i, chromosome in enumerate(population): players = [Player(chromosome)] + [Opponent() for _ in range(3)] win_count = 0 for k in range(games_per_chromosome): random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] if isinstance(winner, Player): win_count += 1 scores[i] = win_count / games_per_chromosome generation_str = os.path.basename(population_path).split(".")[0] scores_path = get_score_file_path(folder_path, generation_str, Opponent.name) assert not os.path.exists(scores_path), "Scores already exists: {}".format(scores_path) np.save(scores_path, save_matrix) task_counter_queue.put(('finished', population_path))
def tournament(_players): """Holds a tournament for the players Arguments: _players {list} -- list of players game_count {int} -- number of games to play Returns: int -- win rates of each player """ assert len(_players) == 4, f'Not enough players for ludo - found: {len(_players)}' players = [player for player in _players] tournament_player_ids = {} for i, player in enumerate(players): tournament_player_ids[player] = i win_rates = np.zeros(4) for i in range(args.game_count): random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] win_rates[tournament_player_ids[winner]] += 1 return win_rates / args.game_count
def eval_player(player): player_args = get_player_args(player) for gen in range(args.gen_count): player.step() population = player.get_flat_pop() winner_pop = reduce_pop(args.Player, population, args.games_per_tournament) players = [args.Player(winner_pop)] while len(players) < 4: players.append(LudoPlayerRandom) tournament_player_ids = {} for i, player in enumerate(players): tournament_player_ids[player] = i win_rates = np.zeros(4) game_count = 100 for i in range(game_count): np.random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] win_rates[tournament_player_ids[winner]] += 1 win_rate = win_rates[0] / game_count return [win_rate, player_args, winner_pop]
def tournament(chromosomes): """Tournament Arguments: chromosomes {np.array} -- chromosomes player {ga_player} -- GA player (simple, advanced or ANN) game_count {int} -- game count Returns: int -- id of the winner """ players = [args.player(chromosome) for chromosome in chromosomes] while len(players) < 4: players.append(LudoPlayerRandom) tournament_player_ids = {} for i, player in enumerate(players): tournament_player_ids[player] = i win_rates = np.zeros(4) for i in range(args.games_per_tournament): random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] win_rates[tournament_player_ids[winner]] += 1 ranked_player_ids = np.argsort(-win_rates) for id in ranked_player_ids: if id < len(chromosomes): return id
def play_tournament(self, chromosome_ids, game_count: int): """Play tournament Arguments: chromosome_ids {np.array} -- ids of the chromosomes to play game_count {int} -- number of games """ flat_pop = self.get_flat_pop() chromosomes = flat_pop[chromosome_ids] players = [self.Player(chromosome) for chromosome in chromosomes] tournament_player_ids = {} for i, player in enumerate(players): tournament_player_ids[player] = i win_rates = np.zeros(4) # bar = tqdm(range(game_count)) # for _ in bar: for _ in range(game_count): random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] win_rates[tournament_player_ids[winner]] += 1 # bar.set_description(f'Win rates {np.around(win_rates/np.sum(win_rates)*100, decimals=2)}') ranked_chromosome_ids = chromosome_ids[np.argsort(-win_rates)] children = self.recombine(*flat_pop[ranked_chromosome_ids[:2]]) children = [self.mutate(child) for child in children] children = [self.Player.normalize(child) for child in children] flat_pop[ranked_chromosome_ids[2:]] = children self.total_game_count += game_count self.cur_tournament_count += 1
def tournament(chromosomes, player, game_count=10): players = [player(chromosome) for chromosome in chromosomes] while len(players) < 4: players.append(LudoPlayerRandom) tournament_player_ids = {} for i, player in enumerate(players): tournament_player_ids[player] = i win_rates = np.zeros(4) for i in range(game_count): np.random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] win_rates[tournament_player_ids[winner]] += 1 ranked_player_ids = np.argsort(-win_rates) for id in ranked_player_ids: if id < len(chromosomes): return id
tournament_player_ids = {} for i, player in enumerate(players): tournament_player_ids[player] = i print(f'{player.name} with id {i}') f.write(f'{player.name} with id {i}\n') pred_times_sim = [] pred_times_adv = [] pred_times_full = [] win_rates = np.zeros(4) bar = tqdm(range(game_count)) for i in bar: random.shuffle(players) game = LudoGame(players) winner = players[game.play_full_game()] win_rates[tournament_player_ids[winner]] += 1 bar.set_description( f'Win rates {np.around(win_rates/np.sum(win_rates)*100, decimals=2)}' ) win_rates = win_rates / game_count print( f'Win rates {np.around(win_rates/np.sum(win_rates)*100, decimals=4)}') f.write( f'Win rates {np.around(win_rates/np.sum(win_rates)*100, decimals=4)}\n' ) for player in tournament_player_ids: if player.name == 'random':
if __name__ == '__main__': import random import time from tqdm import tqdm from pyludo.StandardLudoPlayers import LudoPlayerRandom, SmartPlayer # players = [MathiasPlayer()] + [LudoPlayerRandom() for _ in range(3)] players = [MathiasPlayer()] + [SmartPlayer() for _ in range(3)] for i, player in enumerate(players): player.id = i win_rates = np.zeros(4) n = 1000 start_time = time.time() bar = tqdm(range(n)) for i in bar: random.shuffle(players) ludoGame = LudoGame(players) winner = ludoGame.play_full_game() win_rates[players[winner].id] += 1 bar.set_description( f'Win rate {np.around(win_rates/np.sum(win_rates)*100, decimals=2)}' ) duration = time.time() - start_time print( f'win distribution {np.around(win_rates/np.sum(win_rates)*100, decimals=2)}' ) print(f'games per second {n / duration:.4f}')