def test_pick_moves(self): player = initialize_basic_player() root = player.root root.child_N[coords.flatten_coords((2, 0))] = 10 root.child_N[coords.flatten_coords((1, 0))] = 5 root.child_N[coords.flatten_coords((3, 0))] = 1 root.position.n = go.N ** 2 # move 81, or 361, or... Endgame. # Assert we're picking deterministically self.assertTrue(root.position.n > player.temp_threshold) move = player.pick_move() self.assertEqual(move, (2, 0)) # But if we're in the early part of the game, pick randomly root.position.n = 3 self.assertFalse(player.root.position.n > player.temp_threshold) with mock.patch('random.random', lambda: .5): move = player.pick_move() self.assertEqual(move, (2, 0)) with mock.patch('random.random', lambda: .99): move = player.pick_move() self.assertEqual(move, (3, 0))
def test_flatten(self): self.assertEqual(coords.flatten_coords((0, 0)), 0) self.assertEqual(coords.flatten_coords((0, 3)), 3) self.assertEqual(coords.flatten_coords((3, 0)), 27) self.assertEqual(coords.unflatten_coords(27), (3, 0)) self.assertEqual(coords.unflatten_coords(10), (1, 1)) self.assertEqual(coords.unflatten_coords(80), (8, 8)) self.assertEqual(coords.flatten_coords(coords.unflatten_coords(10)), 10) self.assertEqual( coords.unflatten_coords(coords.flatten_coords((5, 4))), (5, 4))
def test_do_not_explore_past_finish(self): probs = np.array([0.02] * (go.N * go.N + 1), dtype=np.float32) root = MCTSNode(go.Position()) root.select_leaf().incorporate_results(probs, 0, root) first_pass = root.maybe_add_child(coords.flatten_coords(None)) first_pass.incorporate_results(probs, 0, root) second_pass = first_pass.maybe_add_child(coords.flatten_coords(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)
def test_pass(self): self.assertEqual(coords.parse_sgf_coords(''), None) self.assertEqual(coords.unflatten_coords(81), None) self.assertEqual(coords.parse_kgs_coords('pass'), None) self.assertEqual(coords.parse_pygtp_coords((0, 0)), None) self.assertEqual(coords.unparse_sgf_coords(None), '') self.assertEqual(coords.flatten_coords(None), 81) self.assertEqual(coords.to_human_coord(None), 'pass') self.assertEqual(coords.unparse_pygtp_coords(None), (0, 0))
def test_topleft(self): self.assertEqual(coords.parse_sgf_coords('ia'), (0, 8)) self.assertEqual(coords.unflatten_coords(8), (0, 8)) self.assertEqual(coords.parse_kgs_coords('J9'), (0, 8)) self.assertEqual(coords.parse_pygtp_coords((9, 9)), (0, 8)) self.assertEqual(coords.unparse_sgf_coords((0, 8)), 'ia') self.assertEqual(coords.flatten_coords((0, 8)), 8) self.assertEqual(coords.to_human_coord((0, 8)), 'J9') self.assertEqual(coords.unparse_pygtp_coords((0, 8)), (9, 9))
def test_upperleft(self): self.assertEqual(coords.parse_sgf_coords('aa'), (0, 0)) self.assertEqual(coords.unflatten_coords(0), (0, 0)) self.assertEqual(coords.parse_kgs_coords('A9'), (0, 0)) self.assertEqual(coords.parse_pygtp_coords((1, 9)), (0, 0)) self.assertEqual(coords.unparse_sgf_coords((0, 0)), 'aa') self.assertEqual(coords.flatten_coords((0, 0)), 0) self.assertEqual(coords.to_human_coord((0, 0)), 'A9') self.assertEqual(coords.unparse_pygtp_coords((0, 0)), (1, 9))
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(sgf_file.name, record_file.name) recovered_data = self.extract_data(record_file.name) start_pos = go.Position() first_move = coords.parse_sgf_coords('fd') next_pos = start_pos.play_move(first_move) second_move = coords.parse_sgf_coords('cf') expected_data = [ (features.extract_features(start_pos), preprocessing._one_hot(coords.flatten_coords(first_move)), -1), (features.extract_features(next_pos), preprocessing._one_hot(coords.flatten_coords(second_move)), -1) ] self.assertEqualData(expected_data, recovered_data)
def play_move(self, c): ''' Notable side effects: - finalizes the probability distribution according to this roots visit counts into the class' running tally, `searches` - Makes the node associated with this move the root, for future `inject_noise` calls. ''' if not self.two_player_mode: self.searches_pi.append( self.root.children_as_pi(self.root.position.n > self.temp_threshold)) self.qs.append(self.root.Q) # Save our resulting Q. self.comments.append(self.root.describe()) self.root = self.root.maybe_add_child(coords.flatten_coords(c)) self.position = self.root.position # for showboard del self.root.parent.children return True # GTP requires positive result.
def play_move(self, c): ''' Notable side effects: - finalizes the probability distribution according to this roots visit counts into the class' running tally, `searches_pi` - Makes the node associated with this move the root, for future `inject_noise` calls. ''' if not self.two_player_mode: self.searches_pi.append( self.root.children_as_pi(self.root.position.n < self.temp_threshold)) self.qs.append(self.root.Q) # Save our resulting Q. self.comments.append(self.root.describe()) self.root = self.root.maybe_add_child(coords.flatten_coords(c)) self.position = self.root.position # for showboard del self.root.parent.children return True # GTP requires positive result.
def _make_tf_example_from_pwc(position_w_context): features = features_lib.extract_features(position_w_context.position) pi = _one_hot(coords.flatten_coords(position_w_context.next_move)) value = position_w_context.result return make_tf_example(features, pi, value)