Пример #1
0
 def test_noughts_and_crosses_instances_have_correct_size(
         self, size, mocker):
     mock_game = mocker.MagicMock()
     rows, columns = size
     NoughtsAndCrosses.__init__(mock_game, *size)
     assert mock_game.rows == rows
     assert mock_game.columns == columns
Пример #2
0
    def test_display_function_outputs_correct_string_for_3x3(
            self, state, expected_output, capsys, mocker):
        mock_game = mocker.MagicMock(
            rows=3, columns=3, _actions_to_binary=actions_to_binary_list[0])
        NoughtsAndCrosses.display(mock_game, state)

        output = capsys.readouterr().out
        assert output == expected_output
Пример #3
0
 def test_legal_actions_raises_exception_on_terminal_input_state(
         self, mocker):
     mock_game = mocker.MagicMock()
     mock_game.is_terminal = mocker.MagicMock(return_value=True)
     mock_state = mocker.MagicMock()
     with pytest.raises(ValueError) as exception_info:
         NoughtsAndCrosses.legal_actions(mock_game, mock_state)
     assert str(
         exception_info.value) == ("Legal actions can not be computed"
                                   " for a terminal state.")
Пример #4
0
 def test_utility_raises_exception_on_non_terminal_input_state(
         self, size, state, mocker):
     rows, columns = size
     mock_is_terminal = mocker.MagicMock(return_value=False)
     mock_game = mocker.MagicMock(rows=rows,
                                  columns=columns,
                                  is_terminal=mock_is_terminal)
     with pytest.raises(ValueError) as exception_info:
         NoughtsAndCrosses.utility(mock_game, state)
     assert str(exception_info.value) == ("Utility can not be calculated "
                                          "for a non-terminal state.")
     mock_is_terminal.assert_called_once_with(state)
Пример #5
0
def test_random_noughts_and_crosses_player_gives_equal_action_probabilities():
    nac = NoughtsAndCrosses()
    player = RandomPlayer(game=nac)
    action, action_probs = player.choose_action(nac.initial_state,
                                                return_probabilities=True)

    next_states = nac.legal_actions(nac.initial_state)
    expected_action_probs = {
        action: 1 / len(next_states)
        for action in next_states.keys()
    }

    for action in expected_action_probs.keys():
        np.testing.assert_almost_equal(action_probs[action],
                                       expected_action_probs[action])
Пример #6
0
 def test_is_terminal_returns_false_for_non_terminal_states(
         self, size, actions_to_binary, win_bitmasks, state, mocker):
     rows, columns = size
     mock_game = mocker.MagicMock(rows=rows,
                                  columns=columns,
                                  _actions_to_binary=actions_to_binary,
                                  _win_bitmasks=win_bitmasks)
     assert NoughtsAndCrosses.is_terminal(mock_game, state) is False
Пример #7
0
    def test_utility_function_returns_correct_outcomes(self, size,
                                                       win_bitmasks, state,
                                                       outcome, mocker):
        rows, columns = size
        mock_game = mocker.MagicMock(rows=rows,
                                     columns=columns,
                                     _win_bitmasks=win_bitmasks)

        assert NoughtsAndCrosses.utility(mock_game, state) == outcome
Пример #8
0
 def test_calculating_row_win_bitmasks(self, size, actions_to_binary,
                                       win_bitmasks, mocker):
     rows, columns = size
     mock_game = mocker.MagicMock(rows=rows,
                                  columns=columns,
                                  _actions_to_binary=actions_to_binary)
     row_win_bitmasks = NoughtsAndCrosses._calculate_row_bitmasks(mock_game)
     print([(bin(x), bin(y))
            for x, y in zip(row_win_bitmasks, win_bitmasks["row"])])
     assert row_win_bitmasks == win_bitmasks["row"]
Пример #9
0
 def test_generating_a_dict_of_all_possible_next_states(
         self, size, actions_to_binary, state, player, expected_states,
         mocker):
     # TODO: need to split this into two tests: one testing the _next_state function and one testing legal actions
     rows, columns = size
     mock_game = mocker.MagicMock(rows=rows,
                                  columns=columns,
                                  _actions_to_binary=actions_to_binary)
     mock_game.is_terminal = mocker.MagicMock(return_value=False)
     mock_game.current_player = mocker.MagicMock(return_value=player)
     assert NoughtsAndCrosses.legal_actions(mock_game,
                                            state) == expected_states
Пример #10
0
def test_mcts_noughts_and_crosses_player_gives_optimal_moves(
        state, optimal_actions):
    # seed the random number generator.
    np.random.seed(0)

    nac = NoughtsAndCrosses()
    estimator = create_trivial_estimator(nac)
    player = MCTSPlayer(game=nac,
                        estimator=estimator,
                        mcts_iters=100,
                        c_puct=0.5,
                        tau=1)
    action, action_probs = player.choose_action(state,
                                                return_probabilities=True)
    print(action_probs)

    assert max(action_probs, key=action_probs.get) in optimal_actions
Пример #11
0
 def test_action_to_binary_is_correct(self, size, actions_to_binary,
                                      mocker):
     mock_game = mocker.MagicMock()
     NoughtsAndCrosses.__init__(mock_game, *size)
     assert mock_game._actions_to_binary == actions_to_binary
Пример #12
0
 def test_initial_state_is_correct(self, size, mocker):
     mock_game = mocker.MagicMock()
     NoughtsAndCrosses.__init__(mock_game, *size)
     assert mock_game.initial_state == (0, 0, 1)
Пример #13
0
 def test_current_player_returns_correct_player(self, player, state,
                                                mocker):
     mock_game = mocker.MagicMock()
     assert NoughtsAndCrosses.current_player(mock_game, state) == player
Пример #14
0
"""This program plays noughts and crosses using Monte Carlo Tree Search and a
trivial evaluator. For nonterminal states, the evaluator returns the uniform
probability distribution over available actions and a value of 0. In a terminal
state, we back up the utility returned by the game.
"""
import numpy as np

from alphago.games.noughts_and_crosses import NoughtsAndCrosses
from alphago.estimator import create_trivial_estimator
from alphago.player import MCTSPlayer
if __name__ == "__main__":

    nac = NoughtsAndCrosses()
    evaluator = create_trivial_estimator(nac.legal_actions)

    state = nac.INITIAL_STATE
    computer_player_no = np.random.choice([1, 2])
    computer_player = MCTSPlayer(nac,
                                 evaluator,
                                 mcts_iters=2000,
                                 c_puct=0.5,
                                 tau=0.01)
    human_player_no = 1 if computer_player_no == 2 else 2
    print("You are player: {}".format(human_player_no))
    while not nac.is_terminal(state):
        player_no = nac.current_player(state)
        next_states = nac.legal_actions(state)
        if player_no == computer_player_no:
            action = computer_player.choose_action(state)
            computer_player.update(action)
            print("Taking action: {}".format(action))