def test_selects_winning_tictactoe_move(self): ___ = None one_move_from_winning = TicTacToeGame.State( board=['O', 'O', ___, 'X', ___, 'X', ___, 'X', ___], current_player='O', winner=None) result = (MCTS(TicTacToeGame, one_move_from_winning).get_simulation_result(100)) self.assertEqual(result.move, 2) one_move_from_winning = TicTacToeGame.State( board=['O', ___, ___, 'O', 'X', 'X', ___, 'X', ___], current_player='O', winner=None) result = (MCTS(TicTacToeGame, one_move_from_winning).get_simulation_result(100)) self.assertEqual(result.move, 6)
def test_with_mcts(self): state = EuchreGame.initial_state(['0d', '0h', 'as', 'ac', 'ah'], 'jd') result = MCTS(EuchreGame, state).get_simulation_result(100) self.assertEqual(result.max_depth, 20) # there is no longer option now so all players playing will always # result in 20 cards being played self.assertEqual(result.avg_depth, 20)
def test_tictactoe_tie(self): ___ = None one_move_from_winning = TicTacToeGame.State( board=['O', 'X', ___, 'X', 'O', 'O', 'O', 'X', 'X'], current_player='X', winner=None) result = (MCTS(TicTacToeGame, one_move_from_winning).get_simulation_result(100)) self.assertEqual(result.move, 2) self.assertEqual(result.root.children[0].winner, Draw)
def test_random_moves_selected_randomly(self): with patch('mittmcts.choice') as mock_choice: # always choose the first item in random choices # (lowest die rolls in our silly game) mock_choice.side_effect = lambda items: items[0] result = MCTS(SimpleDiceRollingGame).get_simulation_result(100) # because the player chooes to roll no dice it always loses self.assertEqual(result.root.children[0].wins_by_player[1], 0) self.assertEqual(result.root.children[1].wins_by_player[1], 0) self.assertEqual(result.root.children[2].wins_by_player[1], 0) self.assertEqual(result.root.misc_by_player[1]['min_score'], 0) self.assertEqual(result.root.misc_by_player[1]['max_score'], 2) self.assertEqual( result.root.children[1].misc_by_player[1]['min_score'], 1) self.assertEqual( result.root.children[1].misc_by_player[1]['max_score'], 1) self.assertEqual( result.root.children[2].misc_by_player[1]['min_score'], 2) self.assertEqual( result.root.children[2].misc_by_player[1]['max_score'], 2) self.assertEqual(result.root.wins_by_player[1], 0) with patch('mittmcts.choice') as mock_choice: mock_choice.side_effect = lambda items: items[-1] result = MCTS(SimpleDiceRollingGame).get_simulation_result(100) # 100 simulations should be enough time for UCB1 to converge on # the always winning choice given our loaded dice self.assertEqual(result.move, 2) # because the player chooses the highest die roll the player wins # every time it rolls two dice self.assertEqual(result.root.children[2].wins_by_player[1], result.root.children[2].visits) self.assertEqual( result.root.children[2].misc_by_player[1]['min_score'], 12) self.assertEqual( result.root.children[2].misc_by_player[1]['max_score'], 12) self.assertEqual( result.root.children[2].misc_by_player[1]['avg_score'], 12)
def test_with_mcts(self): _ = None board = [[_, _, _, _, _, _, _], [_, _, _, _, _, _, _], [_, _, _, _, _, _, _], [_, _, _, _, _, _, _], [_, _, 1, 1, 1, _, _], [_, _, 0, 0, 0, _, _]] state = ConnectFourGame.State(board=board, current_player=0, bitboards=get_bitboards(board), winner=None) start_time = time() result = (MCTS(ConnectFourGame, state).get_simulation_result(max_seconds=1)) self.assertGreater(time() - start_time, 1) self.assertIn(result.move, [1, 5])
def test_game_with_two_possible_moves(self): result = MCTS(GameWithTwoMoves).get_simulation_result(100) self.assertEqual(result.root.children[0].move, 0) self.assertEqual(result.root.children[0].wins_by_player[1], 0) self.assertIsNone(result.root.children[0].winner) self.assertEqual(result.root.children[0].children[0].winner, 2) self.assertEqual(result.root.children[0].children[0].wins_by_player, {2: result.root.children[0].children[0].visits}) self.assertEqual(result.root.children[1].move, 1) self.assertEqual(result.root.children[1].winner, 1) self.assertEqual(result.root.children[1].wins_by_player, {1: result.root.children[1].visits}) self.assertEqual(result.move, 1) self.assertEqual(result.max_depth, 2) self.assertEqual(result.avg_depth, 1.06)
def test_this_hand_should_win_every_time(self): state = EuchreGame.State( cards_played_by_player=[None, None, None, None], current_player=0, lead_card=None, trump_card='0d', trump='d', winning_team=None, hands=[['jd', 'jh', 'ad', 'kd', 'qd'], [], [], []], tricks_won_by_team=[0, 0], cards_played=['0d'], voids_by_player=[set([]), set([]), set([]), set([])]) result = (MCTS(EuchreGame, state).get_simulation_result(100, get_leaf_nodes=True)) for node in result.leaf_nodes: self.assertGreaterEqual(node.state.tricks_won_by_team[0], 5)
def main(): state = EuchreGame.initial_state() hands = EuchreGame.determine(state).hands table = [None] * 4 while True: winner = EuchreGame.get_winner(state) if winner is not None: dump_state(state, hands) break state_hands = [ player == state.current_player and hand[:] or [] for player, hand in enumerate(hands) ] state = state._replace(hands=state_hands) actual_options = playable_cards(state.trump, suit(state.trump, state.lead_card), hands[state.current_player]) legal_moves = EuchreGame.get_moves(state)[1] result = (MCTS(EuchreGame, state).get_simulation_result(1000, actual_options)) move = result.move dump_state(state, hands, result.root.children, move, table) if state.current_player == 0: while True: try: move = input('') assert move in legal_moves hands[0].remove(move) table[state.current_player] = move state = EuchreGame.apply_move(state, move) break except (AssertionError, ValueError): print(dumps({'error': 'That is not a legal move'})) else: hands[state.current_player].remove(move) table[state.current_player] = move state = EuchreGame.apply_move(state, move) if len(filter(None, table)) == 4: dump_state(state, hands, result.root.children, move, table) table = [None] * 4 sleep(4) # wait for the player to see the table before clearing it
def main(): state = TicTacToeGame.initial_state() while True: if state.winner: TicTacToeGame.print_board(state) if state.winner is Draw: print('Draw!') elif state.winner: print(state.winner + ' wins') break if state.current_player == 'O': while True: TicTacToeGame.print_board(state) try: move = int(input('Move:')) state = TicTacToeGame.apply_move(state, move) break except ValueError: print('That is not a legal move') else: result = (MCTS(TicTacToeGame, state).get_simulation_result(100)) state = TicTacToeGame.apply_move(state, result.move)
def main(): state = QuixoGame.initial_state() number_of_turns = 0 while True: number_of_turns += 1 if state.winner: QuixoGame.print_board(state) print('Number of turns {}'.format(number_of_turns)) if state.winner is Draw: print('Draw!') elif state.winner: print(state.winner + ' wins') break if state.current_player > 0: _, moves = QuixoGame.get_moves(state) index = randint(0, len(moves) - 1) move = moves[index] else: result = (MCTS(QuixoGame, state).get_simulation_result(100)) move = result.move state = QuixoGame.apply_move(state, move)
def main(): state = ConnectFourGame.initial_state() while True: winner = ConnectFourGame.get_winner(state) if winner is not None: dump_state(state) break legal_moves = ConnectFourGame.get_moves(state)[1] result = ( MCTS(ConnectFourGame, state) .get_simulation_result(1000)) move = result.move dump_state(state, result.root.children, move) if state.current_player == 0: while True: try: move = int(input('')) assert move in legal_moves state = ConnectFourGame.apply_move(state, move) break except (AssertionError, ValueError): print(dumps({'error': 'That is not a legal move'})) else: state = ConnectFourGame.apply_move(state, move)
def main(): result = (MCTS(ConnectFourGame).get_simulation_result(1000, get_leaf_nodes=True)) flamegraph(result)
def main(): result = (MCTS(TicTacToeGame).get_simulation_result(1000, get_leaf_nodes=True)) flamegraph(result)
def decide(self, game, state, available_moves, opponent_moves, stdin, result): result = MCTS(game, state).get_simulation_result(1000) move = result.move return move
def test_game_with_one_move(self): result = MCTS(GameWithOneMove).get_simulation_result(100) self.assertEqual(result.move, 'win') self.assertEqual(result.root.children[0].wins_by_player[1], 100) self.assertEqual(result.max_depth, 1)
def main(): state = EuchreGame.initial_state(['ad', '0d', 'kd', '0s', '9s'], trump='d') result = (MCTS(EuchreGame, state) .get_simulation_result(1000, get_leaf_nodes=True)) flamegraph(result)
def test_only_determined_moves_are_followed(self): result = (MCTS( GameWithManyMovesOnlyOneDetermined).get_simulation_result(100)) self.assertEqual(result.root.children[0].move, 1) self.assertEqual(result.root.children[0].visits, 100)