def test_seed_different(self): s = State.generate() s1 = State.generate() if s.get_deck().get_card_states() == s1.get_deck().get_card_states(): raise RuntimeError("The decks are shuffled in the same way.") print s.get_deck().get_card_states() print s1.get_deck().get_card_states()
def test_seed_same(self): for i in range(1,1000): id = i s = State.generate(id) s1 = State.generate(id) if s.get_deck().get_card_states() != s1.get_deck().get_card_states() or s.whose_turn() != s.whose_turn(): raise RuntimeError("The decks are not shuffled in the same way.") print s.get_deck().get_card_states() print s1.get_deck().get_card_states()
def test_trump_jack_non_leading(self): state = State.generate(6) me = state.whose_turn() s1 = state.clone(signature=me) trump_suit = state.get_trump_suit() jacks = [ move for move in s1.moves() if (move[0] == 4 or move[0] == 9 or move[0] == 14 or move[0] == 19) ] trump_jacks = [ move for move in jacks if util.get_suit(move[0]) == trump_suit ] self.assertEqual(len(s1.moves()), 5 + len(trump_jacks)) state = state.next(random.choice(state.moves())) s1 = state.clone(me) jacks = [ move for move in state.moves() if (move[0] == 4 or move[0] == 9 or move[0] == 14 or move[0] == 19) ] trump_jacks = [ move for move in jacks if util.get_suit(move[0]) == trump_suit ] self.assertGreater(len(trump_jacks), 0) self.assertEqual(len(state.moves()), 5)
def create_dataset(path, player=ml_ml_rdeep.Bot(), games=2000, phase=1): data = [] target = [] # For progress bar bar_length = 30 start = time.time() for g in range(games - 1): # For progress bar if g % 10 == 0: percent = 100.0 * g / games sys.stdout.write('\r') sys.stdout.write("Generating dataset: [{:{}}] {:>3}%".format( '=' * int(percent / (100.0 / bar_length)), bar_length, int(percent))) sys.stdout.flush() # Randomly generate a state object starting in specified phase. state = State.generate(phase=phase) state_vectors = [] while not state.finished(): # Give the state a signature if in phase 1, obscuring information that a player shouldn't see. given_state = state.clone(signature=state.whose_turn() ) if state.get_phase() == 1 else state # Add the features representation of a state to the state_vectors array state_vectors.append(features(given_state)) # Advance to the next state move = player.get_move(given_state) state = state.next(move) winner, score = state.winner() for state_vector in state_vectors: data.append(state_vector) if winner == 1: result = 'won' elif winner == 2: result = 'lost' target.append(result) with open(path, 'wb') as output: pickle.dump((data, target), output, pickle.HIGHEST_PROTOCOL) # For printing newline after progress bar print( "\nDone. Time to generate dataset: {:.2f} seconds".format(time.time() - start)) return data, target
def test_game10(self): state = State.generate(0) for i in range(10): if not state.finished(): moves = state.moves() state = state.next(moves[0])
def test_game15(self): state = State.generate(0) for i in range(15): if not state.finished(): # print state moves = state.moves() state = state.next(moves[0])
def run_tournament(options): botnames = options.players.split(",") bots = [] for botname in botnames: bots.append(util.load_player(botname)) n = len(bots) wins = [0] * len(bots) matches = [(p1, p2) for p1 in range(n) for p2 in range(n) if p1 < p2] totalgames = (n * n - n) / 2 * options.repeats playedgames = 0 wins_player1 = 0 wins_player2 = 0 seed = 7453876 print('Playing {} games:'.format(int(totalgames))) for a, b in matches: for r in range(options.repeats): if random.choice([True, False]): p = [a, b] else: p = [b, a] # Generate a state with a random seed state = State.generate(id=seed, phase=int(options.phase)) winner, score = engine.play(bots[p[0]], bots[p[1]], state, options.max_time * 1000, verbose=options.verbose, fast=options.fast) if winner is not None: winner = p[winner - 1] wins[winner] += score if winner == 0: wins_player1 += 1 elif winner == 1: wins_player2 += 1 seed += 1 playedgames += 1 print('Played {} out of {:.0f} games ({:.0f}%): {} \r'.format( playedgames, totalgames, playedgames / float(totalgames) * 100, wins)) print('Results:') for i in range(len(bots)): print(' bot {}: {} points'.format(bots[i], wins[i])) print('Player 1 won %d games. Player 2 won %d games.' % (wins_player1, wins_player2))
def execute(params): ids, (player1, player2), (map_size, seed) = params start, _ = State.generate(map_size, seed, symmetric=not args.asym) winner = engine.play(player1[1], player2[1], start, verbose=(args.verbose > 2), outfile=None, max_time=args.max_time * 1000, max_turns=args.max_turns) if winner is not None: winner = (player1[0], player2[0])[winner-1] return ids, winner, (player1[0], player2[0]), (map_size, seed)
def test_exchange_move(self): s = State.generate(11) moves = s.moves() s1 = s.next(moves[5]) if s.moves() == s1.moves(): raise RuntimeError("The available moves should have changed.") if s.whose_turn() is not s1.whose_turn(): raise RuntimeError("The turns shifted. This should not be the case.") if len(s.moves()) <= len(s1.moves()): raise RuntimeError("The number of available moves should have decreased.")
def test_mariage_visible(self): # for i in range(1,200): # s = State.generate(i) # moves = s.moves() # # if # print moves s = State.generate(2) moves = s.moves() # if print moves
def run_tournament(options): botnames = options.players.split(",") bots = [] for botname in botnames: bots.append(util.load_player(botname)) n = len(bots) wins = [0] * len(bots) ranks = [0] * len(bots) matches = [(p1, p2) for p1 in range(n) for p2 in range(n) if p1 < p2] totalgames = (n * n - n) / 2 * options.repeats playedgames = 0 totalpoints = 0 print('Playing {} games:'.format(int(totalgames))) for a, b in matches: for r in range(options.repeats): p = [a, b] if random.choice([True, False]) else [ b, a ] # randomly chooses who starting_state applies to #p = [a, b] # starting state applied to second player #p = [b, a] # starting state applied to first player # add starting_state argument here, most of them apply to second player starting_state = None # None, one_marriage, two marriage, all_jacks, all_aces, same_suit, all_ace_jack state = State.generate(phase=int(options.phase), starting_state=starting_state) winner, score = engine.play(bots[p[0]], bots[p[1]], state, options.max_time * 1000, verbose=False, fast=options.fast) if winner is not None: winner = p[winner - 1] wins[winner] += score ranks[winner] += 1 totalpoints += score playedgames += 1 #print('Played {} out of {:.0f} games ({:.0f}%): {} \r'.format(playedgames, totalgames, playedgames/float(totalgames) * 100, wins)) for i in range(len(bots)): ranks[i] = wins[i] / (totalpoints) #ranks[i] = ranks[i]/(totalgames) # i think points are more important than just games won print(' bot {}: {} points, {:04.2f} rank'.format( bots[i], wins[i], ranks[i]))
def test_few_moves(self): state = State.generate(50) self.assertEqual(state.get_perspective(), [ 'P1H', 'P1H', 'S', 'S', 'P2H', 'P2H', 'S', 'P2H', 'P1H', 'P2H', 'S', 'P2H', 'S', 'S', 'P1H', 'S', 'P1H', 'S', 'S', 'S' ]) s1 = state.clone(1) self.assertEqual(s1.get_perspective(), [ 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'P1H', 'U', 'S', 'U', 'U', 'U', 'P1H', 'U', 'P1H', 'U', 'U', 'U' ])
def test_marriage_deterministic(self): state = State.generate(38) self.assertEqual(state.get_deck().get_card_states(), [ 'S', 'P2H', 'P1H', 'S', 'P1H', 'P1H', 'S', 'S', 'P2H', 'S', 'S', 'P2H', 'P2H', 'P2H', 'S', 'S', 'S', 'S', 'P1H', 'P1H' ]) self.assertEqual(state.get_perspective(1), [ 'U', 'U', 'P1H', 'U', 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'S', 'U', 'U', 'U', 'P1H', 'P1H' ]) self.assertEqual(state.get_perspective(2), [ 'U', 'P2H', 'U', 'U', 'U', 'U', 'U', 'U', 'P2H', 'U', 'U', 'P2H', 'P2H', 'P2H', 'S', 'U', 'U', 'U', 'U', 'U' ])
def test_trump_jack_non_leading(self): state = State.generate(6) trump_suit = state.get_trump_suit() jacks = [move for move in state.moves() if (move[0] == 4 or move[0] == 9 or move[0] == 14 or move[0] == 19)] trump_jacks = [move for move in jacks if util.get_suit(move[0]) == trump_suit] self.assertEqual(len(state.moves()), 5 + len(trump_jacks)) self.assertEqual(len(jacks), 0) state = state.next(random.choice(state.moves())) jacks = [move for move in state.moves() if (move[0] == 4 or move[0] == 9 or move[0] == 14 or move[0] == 19)] trump_jacks = [move for move in jacks if util.get_suit(move[0]) == trump_suit]
def execute(params): ids, bot, (map_size, seed, max_turns, asym) = params state, _ = State.generate(map_size, seed, symmetric=not asym) state_vectors = [] i = 0 while not state.finished() and i <= max_turns: state_vectors.append(features(state)) move = bot.get_move(state) state = state.next(move) i += 1 winner = state.winner() return ids, winner, state_vectors, (map_size, seed)
def test_game_full(self): wins = 0 for i in range(10000): state = State.generate() while not state.finished(): moves = state.moves() # print state.get_deck().get_card_states() # print "p1 score: {}".format(state.get_points(1)) # print "p2 score: {}".format(state.get_points(2)) # print moves state = state.next(moves[0]) winner, points = state.winner() if winner == 1: wins +=1 print wins
def run_tournament(options): botnames = options.players.split(",") bots = [] for botname in botnames: bots.append(util.load_player(botname)) n = len(bots) wins = [0] * len(bots) points = [0] * len(bots) matches = [(p1, p2) for p1 in range(n) for p2 in range(n) if p1 < p2] totalgames = (n * n - n) / 2 * options.repeats playedgames = 0 print('Playing {} games:'.format(totalgames)) for a, b in matches: for r in range(options.repeats): if random.choice([True, False]): p = [a, b] else: p = [b, a] # Generate a state with a random seed start = State.generate(phase=int(options.phase)) winner = engine.play(bots[p[0]], bots[p[1]], start, verbose=False) #TODO: ALSO IMPLEMENT POINTS FOR WINNING if winner is not None: _, temp_points = winner winner = p[winner[0] - 1] wins[winner] += 1 points[winner] += temp_points playedgames += 1 print('Played {} out of {:.0f} games ({:.0f}%): {} \r'.format( playedgames, totalgames, playedgames / float(totalgames) * 100, wins)) print('Results:') for i in range(len(bots)): print(' bot {}: {} wins, {} points'.format(bots[i], wins[i], points[i]))
def test_marriage_deterministic(self): state = State.generate(38) self.assertEqual(state.get_deck().get_card_states(), ['S', 'P2H', 'P1H', 'S', 'P1H', 'P1H', 'S', 'S', 'P2H', 'S', 'S', 'P2H', 'P2H', 'P2H', 'S', 'S', 'S', 'S', 'P1H', 'P1H']) self.assertEqual(state.get_perspective(1), ['U', 'U', 'P1H', 'U', 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'S', 'U', 'U', 'U', 'P1H', 'P1H']) self.assertEqual(state.get_perspective(2), ['U', 'P2H', 'U', 'U', 'U', 'U', 'U', 'U', 'P2H', 'U', 'U', 'P2H', 'P2H', 'P2H', 'S', 'U', 'U', 'U', 'U', 'U']) state = state.next((12, 13)) self.assertEqual(state.get_deck().get_card_states(), ['S', 'P2H', 'P1H', 'S', 'P1H', 'P1H', 'S', 'S', 'P2H', 'S', 'S', 'P2H', 'P2H', 'P2H', 'S', 'S', 'S', 'S', 'P1H', 'P1H']) self.assertEqual(state.get_perspective(1), ['U', 'U', 'P1H', 'U', 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'P2H', 'P2H', 'S', 'U', 'U', 'U', 'P1H', 'P1H']) self.assertEqual(state.get_perspective(2), ['U', 'P2H', 'U', 'U', 'U', 'U', 'U', 'U', 'P2H', 'U', 'U', 'P2H', 'P2H', 'P2H', 'S', 'U', 'U', 'U', 'U', 'U']) move = random.choice(state.moves()) index = move[0] scores = [11, 10, 4, 3, 2] score = 40 + scores[12%5] + scores[index%5] st = state.get_deck().get_stock() state = state.next(move) card_states = ['S', 'P2H', 'P1H', 'S', 'P1H', 'P1H', 'S', 'S', 'P2H', 'S', 'S', 'P2H', 'P2W', 'P2H', 'S', 'S', 'S', 'S', 'P1H', 'P1H'] st1 = st.pop() st2 = st.pop() card_states[index] = "P2W" card_states[st1] = "P2H" card_states[st2] = "P1H" p1 = ['U', 'U', 'P1H', 'U', 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'P2W', 'P2H', 'S', 'U', 'U', 'U', 'P1H', 'P1H'] p1[st2] = "P1H" p1[index] = "P2W" p2 = ['U', 'P2H', 'U', 'U', 'U', 'U', 'U', 'U', 'P2H', 'U', 'U', 'P2H', 'P2W', 'P2H', 'S', 'U', 'U', 'U', 'U', 'U'] p2[index] = "P2W" p2[st1] = "P2H" self.assertEqual(state.get_deck().get_card_states(), card_states) self.assertEqual(state.get_perspective(1), p1) self.assertEqual(state.get_perspective(2), p2) self.assertEqual(state.get_points(1), 0) self.assertEqual(state.get_points(2), score)
def test_trump_jack_exchange_deterministic(self): state = State.generate(50) self.assertEqual(state.get_deck().get_card_states(), [ 'P1H', 'P1H', 'S', 'S', 'P2H', 'P2H', 'S', 'P2H', 'P1H', 'P2H', 'S', 'P2H', 'S', 'S', 'P1H', 'S', 'P1H', 'S', 'S', 'S' ]) self.assertEqual(state.get_perspective(1), [ 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'P1H', 'U', 'S', 'U', 'U', 'U', 'P1H', 'U', 'P1H', 'U', 'U', 'U' ]) self.assertEqual(state.get_perspective(2), [ 'U', 'U', 'U', 'U', 'P2H', 'P2H', 'U', 'P2H', 'U', 'P2H', 'S', 'P2H', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ]) #Test trump jack exchange #Maybe needs to change if order of moves is altered self.assertEqual(state.whose_turn(), 1) self.assertEqual(state.get_points(1), 0) self.assertEqual(state.get_points(2), 0) self.assertEqual(state.get_pending_points(1), 0) self.assertEqual(state.get_pending_points(2), 0) state = state.next(state.moves().pop()) self.assertEqual(state.whose_turn(), 1) self.assertEqual(state.get_deck().get_card_states(), [ 'P1H', 'P1H', 'S', 'S', 'P2H', 'P2H', 'S', 'P2H', 'P1H', 'P2H', 'P1H', 'P2H', 'S', 'S', 'S', 'S', 'P1H', 'S', 'S', 'S' ]) self.assertEqual(state.get_perspective(1), [ 'P1H', 'P1H', 'U', 'U', 'U', 'U', 'U', 'U', 'P1H', 'U', 'P1H', 'U', 'U', 'U', 'S', 'U', 'P1H', 'U', 'U', 'U' ]) self.assertEqual(state.get_perspective(2), [ 'U', 'U', 'U', 'U', 'P2H', 'P2H', 'U', 'P2H', 'U', 'P2H', 'P1H', 'P2H', 'U', 'U', 'S', 'U', 'U', 'U', 'U', 'U' ]) self.assertEqual(state.get_points(1), 0) self.assertEqual(state.get_points(2), 0) self.assertEqual(state.get_pending_points(1), 0) self.assertEqual(state.get_pending_points(2), 0)
def train_bot(player): for g in range(GAMES): # Randomly generate a state object starting in specified phase. state = State.generate(phase=PHASE) state_vectors = [] while not state.finished(): # Give the state a signature if in phase 1, obscuring information that a player shouldn't see. given_state = state.clone(signature=state.whose_turn() ) if state.get_phase() == 1 else state # Add the features representation of a state to the state_vectors array state_vectors.append(features(given_state)) # Advance to the next state move = player.get_move(given_state) state = state.next(move) winner, score = state.winner() for state_vector in state_vectors: data.append(state_vector) if winner == 1: result = 'won' elif winner == 2: result = 'lost' target.append(result) sys.stdout.write(".") sys.stdout.flush() if g % (GAMES / 10) == 0: print("") print('game {} finished ({}%)'.format(g, (g / float(GAMES) * 100)))
def call_engine(options): # Create player 1 player1 = util.load_player(options.player1) # Create player 2 player2 = util.load_player(options.player2) # Generate or load the map state, id = State.generate(int(options.num_planets), symmetric=not options.asym) if not options.quiet: print('-- Using map with id {} '.format(id)) print(' Start state: ' + str(state)) # Play the game viz = (options.outputfile.lower() == 'none') outfile = options.outputfile # type: str if not outfile.endswith('.pdf'): outfile += '.pdf' engine.play(player1, player2, state=state, max_time=options.max_time*1000, verbose=(not options.quiet), outfile=outfile)
def call_engine(options): # Create player 1 player1 = util.load_player(options.player1) # Create player 2 player2 = util.load_player(options.player2) # Generate or load the map state = State.generate(phase=int(options.phase)) if not options.quiet: # print('-- Using map with id {} '.format(id)) print(' Start state: ' + str(state)) # Play the game engine.play(player1, player2, state=state, max_time=options.max_time * 1000, verbose=(not options.quiet))
def run_tournament(options): botnames = options.players.split(",") bots = [] for botname in botnames: bots.append(util.load_player(botname)) n = len(bots) wins = [0] * len(bots) matches = [(p1, p2) for p1 in range(n) for p2 in range(n) if p1 < p2] totalgames = (n*n - n)/2 * options.repeats playedgames = 0 print('Playing {} games:'.format(totalgames)) for a, b in matches: for r in range(options.repeats): if random.choice([True, False]): p = [a, b] else: p = [b, a] start, _ = State.generate(int(options.num_planets), symmetric=not options.asym) winner = engine.play(bots[p[0]], bots[p[1]], start, verbose=False, outfile=None) if winner is not None: winner = p[winner - 1] wins[winner] += 1 playedgames += 1 print('Played {} out of {:.0f} games ({:.0f}%): {} \r'.format(playedgames, totalgames, playedgames/float(totalgames) * 100, wins)) print('Results:') for i in range(len(bots)): print(' bot {}: {} wins'.format(bots[i], wins[i]))
def create_dataset(path, player=rand.Bot(), games=2000, phase=1): """Create a dataset that can be used for training the ML bot model. The dataset is created by having the player (bot) play games against itself. The games parameter indicates how many games will be started. Each game will be played and the game situations will be stored. Then, the game ends and it is recorded whether the game situations resulted in a win or loss for player 1. In other words, each game situation is stored with the corresponding class label (won/lost). Keyword arguments path -- the pathname where the dataset is to be stored player -- the player which will play against itself, default the rand Bot games -- the number of games to play, default 2000 phase -- wheter to start the games in phase 1, the default, or phase 2 """ data = [] target = [] # For progress bar bar_length = 30 start = time.time() for g in range(games - 1): # For progress bar if g % 10 == 0: percent = 100.0 * g / games sys.stdout.write('\r') sys.stdout.write("Generating dataset: [{:{}}] {:>3}%".format( '=' * int(percent / (100.0 / bar_length)), bar_length, int(percent))) sys.stdout.flush() # Randomly generate a state object starting in specified phase. state = State.generate(phase=phase) state_vectors = [] while not state.finished(): # Give the state a signature if in phase 1, obscuring information that a player shouldn't see. given_state = state.clone(signature=state.whose_turn() ) if state.get_phase() == 1 else state # Add the features representation of a state to the state_vectors array state_vectors.append(features(given_state)) # Advance to the next state move = player.get_move(given_state) state = state.next(move) winner, score = state.winner() for state_vector in state_vectors: data.append(state_vector) if winner == 1: result = 'won' elif winner == 2: result = 'lost' target.append(result) with open(path, 'wb') as output: pickle.dump((data, target), output, pickle.HIGHEST_PROTOCOL) # For printing newline after progress bar print( "\nDone. Time to generate dataset: {:.2f} seconds".format(time.time() - start)) return data, target
# Which phase the game starts in PHASE = 2 # The player we'll observe player = alphabeta.Bot() #player = rdeep.Bot() #player = ml_advanced.Bot() data = [] target = [] for g in range(GAMES): # Randomly generate a state object starting in specified phase. state = State.generate(phase=PHASE) state_vectors = [] while not state.finished(): # Give the state a signature if in phase 1, obscuring information that a player shouldn't see. given_state = state.clone(signature=state.whose_turn()) if state.get_phase() == 1 else state # Add the features representation of a state to the state_vectors array state_vectors.append(features(given_state)) # Advance to the next state move = player.get_move(given_state) state = state.next(move)
def generate(): global state # Use 3 for marriage, 50 for exchange state = State.generate(id=options.seed, phase=options.phase) return state.convert_to_json() #[:-1] + ', "seed": ' + str(id) + '}')
# combination of parameters won_by_1 = empty(STEPS) won_by_2 = empty(STEPS) # We will move through the parameters from 0 to 1 in STEPS steps, and play REPEATS games for each # combination. If at combination (i, j) player 1 winds a game, we increment won_by_1[i][j] for i in range(STEPS): for j in range(STEPS): for r in range(REPEATS): # Make the players player1 = Bot(inc * i) player2 = Bot(inc * j) state = State.generate() # play the game while not state.finished(): player = player1 if state.whose_turn() == 1 else player2 state = state.next(player.get_move(state)) #TODO Maybe add points for state.winner() if state.finished(): winner, points = state.winner() if winner == 1: won_by_1[i][j] += points else: won_by_2[i][j] += points print('finished {} vs {}'.format(inc * i, inc * j))
state_features + move_hot_form(m) for m in next_state.moves() ] Qtarget = Qnet_copy.predict(np.array(state_vectors)).max() target.append(reward + gamma * Qtarget) data = np.array(data) target = np.array(target) Qnet.fit(data, target, verbose=0) # Qnet.save('Qnet.h5') for _ in range(number_of_episodes): state = State.generate(phase=1) dqn_number = random.choice([1, 2]) n_epi += 1 while not state.finished(): given_state = state.clone( signature=state.whose_turn()) if state.get_phase() == 1 else state action = (None, None) n_steps += 1 if state.whose_turn() == dqn_number: #print('ai') action = e_greedy(given_state) state = state.next(action)
def test_exchange_visible(self): s = State.generate(11) moves = s.moves() print s.get_deck().get_card_states() print moves print s.get_deck().get_trump_suit()
def run_tournament(options): botnames = options.players.split(",") bots = [] for botname in botnames: bots.append(util.load_player(botname)) n = len(bots) wins = [0] * len(bots) matches = [(p1, p2) for p1 in range(n) for p2 in range(n) if p1 < p2] totalgames = (n * n - n) / 2 * options.repeats playedgames = 0 totalScores = [[ botnames[0], botnames[1], 'winner', 'points', f'{botnames[0]} phase1 score', f'{botnames[1]} phase1 score', 'seed' ]] # total scores to output to csv print('Playing {} games:'.format(int(totalgames))) for a, b in matches: for r in range(options.repeats): if random.choice([True, False]): p = [a, b] else: p = [b, a] # Generate a state with a random seed seed = random.randint(0, 100000) state = State.generate(id=seed, phase=int(options.phase)) (winner, score), (player1score, player2score), (player1phase1score, player2phase1score) = engine.play( bots[p[0]], bots[p[1]], state, options.max_time * 1000, verbose=options.verbose, fast=options.fast) if winner is not None: winner = p[winner - 1] wins[winner] += score scores = [0, 0, 0, 0, 0, 0, 0, 0, 0] # initial values for total scores scores[p[0]] = player1score scores[p[1]] = player2score scores[2] = botnames[winner] scores[3] = score scores[p[0] + 4] = player1phase1score scores[p[1] + 4] = player2phase1score scores[6] = seed totalScores.append(scores) playedgames += 1 print(f'Player {bots[p[0]]} scored: {player1score}') print(f'Player {bots[p[1]]} scored: {player2score}') print('Played {} out of {:.0f} games ({:.0f}%): {} \r'.format( playedgames, totalgames, playedgames / float(totalgames) * 100, wins)) print() print('Results:') for i in range(len(bots)): print(' bot {}: {} points'.format(bots[i], wins[i])) # output values to csv with open('scores.csv', 'w', newline='') as myfile: wr = csv.writer(myfile, quoting=csv.QUOTE_ALL) for totalScore in totalScores: wr.writerow(totalScore)