Exemple #1
0
 def test_chinese_handicap_handling(self):
     intermediate_board = utils_test.load_board('''
   .........
   .........
   ......X..
   .........
   .........
   .........
   .........
   .........
   .........
 ''')
     intermediate_position = go.Position(
         utils_test.BOARD_SIZE,
         intermediate_board,
         n=1,
         komi=5.5,
         caps=(0, 0),
         recent=(go.PlayerMove(go.BLACK, coords.from_kgs(
             utils_test.BOARD_SIZE, 'G7')),),
         to_play=go.BLACK,
     )
     final_board = utils_test.load_board('''
   ....OX...
   .O.OOX...
   O.O.X.X..
   .OXXX....
   OX...XX..
   .X.XXO...
   X.XOOXXX.
   XXXO.OOX.
   .XOOX.O..
 ''')
     final_position = go.Position(
         utils_test.BOARD_SIZE,
         final_board,
         n=50,
         komi=5.5,
         caps=(7, 2),
         ko=None,
         recent=(
             go.PlayerMove(
                 go.WHITE, coords.from_kgs(utils_test.BOARD_SIZE, 'E9')),
             go.PlayerMove(
                 go.BLACK, coords.from_kgs(utils_test.BOARD_SIZE, 'F9')),),
         to_play=go.WHITE
     )
     positions_w_context = list(replay_sgf(
         utils_test.BOARD_SIZE, CHINESE_HANDICAP_SGF))
     self.assertEqualPositions(
         intermediate_position, positions_w_context[1].position)
     self.assertEqual(
         positions_w_context[1].next_move, coords.from_kgs(
             utils_test.BOARD_SIZE, 'C3'))
     final_replayed_position = positions_w_context[-1].position.play_move(
         positions_w_context[-1].next_move)
     self.assertEqualPositions(final_position, final_replayed_position)
Exemple #2
0
 def test_japanese_handicap_handling(self):
     intermediate_board = utils_test.load_board('''
   .........
   .........
   ......X..
   .........
   ....O....
   .........
   ..X......
   .........
   .........
 ''')
     intermediate_position = go.Position(
         utils_test.BOARD_SIZE,
         intermediate_board,
         n=1,
         komi=5.5,
         caps=(0, 0),
         recent=(go.PlayerMove(go.WHITE, coords.from_kgs(
             utils_test.BOARD_SIZE, 'E5')),),
         to_play=go.BLACK,
     )
     final_board = utils_test.load_board('''
   .........
   .........
   ......X..
   .........
   ....O....
   .........
   ..XX.....
   .........
   .........
 ''')
     final_position = go.Position(
         utils_test.BOARD_SIZE,
         final_board,
         n=2,
         komi=5.5,
         caps=(0, 0),
         recent=(
             go.PlayerMove(go.WHITE, coords.from_kgs(
                 utils_test.BOARD_SIZE, 'E5')),
             go.PlayerMove(go.BLACK, coords.from_kgs(
                 utils_test.BOARD_SIZE, 'D3')),),
         to_play=go.WHITE,
     )
     positions_w_context = list(replay_sgf(
         utils_test.BOARD_SIZE, JAPANESE_HANDICAP_SGF))
     self.assertEqualPositions(
         intermediate_position, positions_w_context[1].position)
     final_replayed_position = positions_w_context[-1].position.play_move(
         positions_w_context[-1].next_move)
     self.assertEqualPositions(final_position, final_replayed_position)
Exemple #3
0
    def test_inference(self):
        with tempfile.TemporaryDirectory() as working_dir, \
                tempfile.TemporaryDirectory() as export_dir:
            dualnet.bootstrap(working_dir, model_params.DummyMiniGoParams())
            exported_model = os.path.join(export_dir, 'bootstrap-model')
            dualnet.export_model(working_dir, exported_model)

            n1 = dualnet.DualNetRunner(
                exported_model, model_params.DummyMiniGoParams())
            n1.run(go.Position(utils_test.BOARD_SIZE))

            n2 = dualnet.DualNetRunner(
                exported_model, model_params.DummyMiniGoParams())
            n2.run(go.Position(utils_test.BOARD_SIZE))
Exemple #4
0
 def test_add_child(self):
     root = MCTSNode(utils_test.BOARD_SIZE,
                     go.Position(utils_test.BOARD_SIZE))
     child = root.maybe_add_child(17)
     self.assertIn(17, root.children)
     self.assertEqual(child.parent, root)
     self.assertEqual(child.fmove, 17)
Exemple #5
0
    def test_only_check_game_end_once(self):
        # When presented with a situation where the last move was a pass,
        # and we have to decide whether to pass, it should be the first thing
        # we check, but not more than that.

        white_passed_pos = go.Position(utils_test.BOARD_SIZE, ).play_move(
            (3, 3)  # b plays
        ).play_move(
            (3, 4)  # w plays
        ).play_move(
            (4, 3)  # b plays
        ).pass_move()  # w passes - if B passes too, B would lose by komi.

        player = MCTSPlayerMixin(utils_test.BOARD_SIZE, DummyNet())
        player.initialize_game(white_passed_pos)
        # initialize the root
        player.tree_search()
        # explore a child - should be a pass move.
        player.tree_search()
        pass_move = utils_test.BOARD_SIZE * utils_test.BOARD_SIZE
        self.assertEqual(player.root.children[pass_move].N, 1)
        self.assertEqual(player.root.child_N[pass_move], 1)
        player.tree_search()
        # check that we didn't visit the pass node any more times.
        self.assertEqual(player.root.child_N[pass_move], 1)
Exemple #6
0
 def test_is_game_over(self):
     root = go.Position(utils_test.BOARD_SIZE)
     self.assertFalse(root.is_game_over())
     first_pass = root.play_move(None)
     self.assertFalse(first_pass.is_game_over())
     second_pass = first_pass.play_move(None)
     self.assertTrue(second_pass.is_game_over())
Exemple #7
0
 def test_add_child_idempotency(self):
     root = MCTSNode(utils_test.BOARD_SIZE,
                     go.Position(utils_test.BOARD_SIZE))
     child = root.maybe_add_child(17)
     current_children = copy.copy(root.children)
     child2 = root.maybe_add_child(17)
     self.assertEqual(child, child2)
     self.assertEqual(current_children, root.children)
Exemple #8
0
 def initialize_game(self, position=None):
     if position is None:
         position = go.Position(self.board_size)
     self.root = MCTSNode(self.board_size, position)
     self.result = 0
     self.result_string = None
     self.comments = []
     self.searches_pi = []
     self.qs = []
Exemple #9
0
 def test_action_flipping(self):
     np.random.seed(1)
     probs = np.array([.02] *
                      (utils_test.BOARD_SIZE * utils_test.BOARD_SIZE + 1))
     probs += np.random.random(
         [utils_test.BOARD_SIZE * utils_test.BOARD_SIZE + 1]) * 0.001
     black_root = MCTSNode(utils_test.BOARD_SIZE,
                           go.Position(utils_test.BOARD_SIZE))
     white_root = MCTSNode(
         utils_test.BOARD_SIZE,
         go.Position(utils_test.BOARD_SIZE, to_play=go.WHITE))
     black_root.select_leaf().incorporate_results(probs, 0, black_root)
     white_root.select_leaf().incorporate_results(probs, 0, white_root)
     # No matter who is to play, when we know nothing else, the priors
     # should be respected, and the same move should be picked
     black_leaf = black_root.select_leaf()
     white_leaf = white_root.select_leaf()
     self.assertEqual(black_leaf.fmove, white_leaf.fmove)
     self.assertEqualNPArray(black_root.child_action_score,
                             white_root.child_action_score)
Exemple #10
0
 def test_tree_search_failsafe(self):
     # Test that the failsafe works correctly. It can trigger if the MCTS
     # repeatedly visits a finished game state.
     probs = np.array([.001] *
                      (utils_test.BOARD_SIZE * utils_test.BOARD_SIZE + 1))
     probs[-1] = 1  # Make the dummy net always want to pass
     player = MCTSPlayerMixin(utils_test.BOARD_SIZE,
                              DummyNet(fake_priors=probs))
     pass_position = go.Position(utils_test.BOARD_SIZE).pass_move()
     player.initialize_game(pass_position)
     player.tree_search(num_parallel=1)
     self.assertNoPendingVirtualLosses(player.root)
Exemple #11
0
 def clear(self):
     if self.position and len(self.position.recent) > 1:
         try:
             sgf = self.to_sgf()
             with open(datetime.datetime.now().strftime(
                     '%Y-%m-%d-%H:%M.sgf'), 'w') as f:
                 f.write(sgf)
         except NotImplementedError:
             pass
         except:
             print('Error saving sgf', file=sys.stderr, flush=True)
     self.position = go.Position(komi=self.komi)
     self.initialize_game(self.position)
Exemple #12
0
 def test_dont_pick_unexpanded_child(self):
     probs = np.array([0.001] *
                      (utils_test.BOARD_SIZE * utils_test.BOARD_SIZE + 1))
     # make one move really likely so that tree search goes down that path twice
     # even with a virtual loss
     probs[17] = 0.999
     root = MCTSNode(utils_test.BOARD_SIZE,
                     go.Position(utils_test.BOARD_SIZE))
     root.incorporate_results(probs, 0, root)
     leaf1 = root.select_leaf()
     self.assertEqual(leaf1.fmove, 17)
     leaf1.add_virtual_loss(up_to=root)
     # the second select_leaf pick should return the same thing, since the child
     # hasn't yet been sent to neural net for eval + result incorporation
     leaf2 = root.select_leaf()
     self.assertIs(leaf1, leaf2)
Exemple #13
0
 def test_do_not_explore_past_finish(self):
     probs = np.array([0.02] *
                      (utils_test.BOARD_SIZE * utils_test.BOARD_SIZE + 1),
                      dtype=np.float32)
     root = MCTSNode(utils_test.BOARD_SIZE,
                     go.Position(utils_test.BOARD_SIZE))
     root.select_leaf().incorporate_results(probs, 0, root)
     first_pass = root.maybe_add_child(
         coords.to_flat(utils_test.BOARD_SIZE, None))
     first_pass.incorporate_results(probs, 0, root)
     second_pass = first_pass.maybe_add_child(
         coords.to_flat(utils_test.BOARD_SIZE, None))
     with self.assertRaises(AssertionError):
         second_pass.incorporate_results(probs, 0, root)
     node_to_explore = second_pass.select_leaf()
     # should just stop exploring at the end position.
     self.assertEqual(node_to_explore, second_pass)
Exemple #14
0
    def test_long_game_tree_search(self):
        player = MCTSPlayerMixin(utils_test.BOARD_SIZE, DummyNet())
        endgame = go.Position(utils_test.BOARD_SIZE,
                              board=TT_FTW_BOARD,
                              n=MAX_DEPTH - 2,
                              komi=2.5,
                              ko=None,
                              recent=(go.PlayerMove(go.BLACK, (0, 1)),
                                      go.PlayerMove(go.WHITE, (0, 8))),
                              to_play=go.BLACK)
        player.initialize_game(endgame)

        # Test that an almost complete game
        for i in range(10):
            player.tree_search(num_parallel=8)
        self.assertNoPendingVirtualLosses(player.root)
        self.assertGreater(player.root.Q, 0)
Exemple #15
0
    def test_replay_position(self):
        sgf_positions = list(sgf_wrapper.replay_sgf(
            utils_test.BOARD_SIZE, NO_HANDICAP_SGF))
        initial = sgf_positions[0]
        self.assertEqual(initial.result, go.WHITE)

        final = sgf_positions[-1].position.play_move(
            sgf_positions[-1].next_move)

        # sanity check to ensure we're working with the right position
        final_board = utils_test.load_board('''
        .OXX.....
        O.OX.X...
        .OOX.....
        OOOOXXXXX
        XOXXOXOOO
        XOOXOO.O.
        XOXXXOOXO
        XXX.XOXXO
        X..XOO.O.
      ''')
        expected_final_position = go.Position(
            utils_test.BOARD_SIZE,
            final_board,
            n=62,
            komi=6.5,
            caps=(3, 2),
            ko=None,
            recent=tuple(),
            to_play=go.BLACK
        )
        self.assertEqualPositions(expected_final_position, final)
        self.assertEqual(final.n, len(final.recent))

        replayed_positions = list(go.replay_position(
            utils_test.BOARD_SIZE, final, 1))
        for sgf_pos, replay_pos in zip(sgf_positions, replayed_positions):
            self.assertEqualPositions(sgf_pos.position, replay_pos.position)
Exemple #16
0
 def test_make_dataset_from_sgf(self):
     with tempfile.NamedTemporaryFile() as sgf_file, \
             tempfile.NamedTemporaryFile() as record_file:
         sgf_file.write(TEST_SGF.encode('utf8'))
         sgf_file.seek(0)
         preprocessing.make_dataset_from_sgf(utils_test.BOARD_SIZE,
                                             sgf_file.name,
                                             record_file.name)
         recovered_data = self.extract_data(record_file.name)
     start_pos = go.Position(utils_test.BOARD_SIZE)
     first_move = coords.from_sgf('fd')
     next_pos = start_pos.play_move(first_move)
     second_move = coords.from_sgf('cf')
     expected_data = [
         (features.extract_features(utils_test.BOARD_SIZE, start_pos),
          preprocessing._one_hot(
              utils_test.BOARD_SIZE,
              coords.to_flat(utils_test.BOARD_SIZE, first_move)), -1),
         (features.extract_features(utils_test.BOARD_SIZE, next_pos),
          preprocessing._one_hot(
              utils_test.BOARD_SIZE,
              coords.to_flat(utils_test.BOARD_SIZE, second_move)), -1)
     ]
     self.assertEqualData(expected_data, recovered_data)
Exemple #17
0
tf.logging.set_verbosity(tf.logging.ERROR)

EMPTY_ROW = '.' * utils_test.BOARD_SIZE + '\n'
TEST_BOARD = utils_test.load_board('''
.X.....OO
X........
XXXXXXXXX
''' + EMPTY_ROW * 6)

TEST_POSITION = go.Position(
    utils_test.BOARD_SIZE,
    board=TEST_BOARD,
    n=3,
    komi=6.5,
    caps=(1, 2),
    ko=None,
    recent=(go.PlayerMove(go.BLACK, (0, 1)), go.PlayerMove(go.WHITE, (0, 8)),
            go.PlayerMove(go.BLACK, (1, 0))),
    to_play=go.BLACK,
)

TEST_BOARD2 = utils_test.load_board('''
.XOXXOO..
XO.OXOX..
XXO..X...
''' + EMPTY_ROW * 6)

TEST_POSITION2 = go.Position(
    utils_test.BOARD_SIZE,
    board=TEST_BOARD2,
Exemple #18
0
  .XXOOOOOO
  X.XOO...O
  .XXOO...O
  X.XOO...O
  .XXOO..OO
  X.XOOOOOO
  .XXOOOOOO
  X.XXXXXXX
  XXXXXXXXX
  ''')

SEND_TWO_RETURN_ONE = go.Position(utils_test.BOARD_SIZE,
                                  board=ALMOST_DONE_BOARD,
                                  n=70,
                                  komi=2.5,
                                  caps=(1, 4),
                                  ko=None,
                                  recent=(go.PlayerMove(go.BLACK, (0, 1)),
                                          go.PlayerMove(go.WHITE, (0, 8))),
                                  to_play=go.BLACK)

# 505 moves for 19x19, 113 for 9x9
MAX_DEPTH = (utils_test.BOARD_SIZE**2) * 1.4


class DummyNet():
    def __init__(self, fake_priors=None, fake_value=0):
        if fake_priors is None:
            fake_priors = np.ones((utils_test.BOARD_SIZE**2) +
                                  1) / (utils_test.BOARD_SIZE**2 + 1)
        self.fake_priors = fake_priors