Exemplo n.º 1
0
def parse(boardstr):
    '''Parses a board into a gamestate, and returns the location of any moves
    marked with anything other than 'B', 'X', '#', 'W', 'O', or '.'

    Rows are separated by '|', spaces are ignored.

    '''

    boardstr = boardstr.replace(' ', '')
    board_size = max(boardstr.index('|'), boardstr.count('|'))

    st = GameState(size=board_size)
    moves = {}

    for row, rowstr in enumerate(boardstr.split('|')):
        for col, c in enumerate(rowstr):
            if c == '.':
                continue  # ignore empty spaces
            elif c in 'BX#':
                st.do_move((row, col), color=BLACK)
            elif c in 'WO':
                st.do_move((row, col), color=WHITE)
            else:
                # move reference
                assert c not in moves, "{} already used as a move marker".format(c)
                moves[c] = (row, col)

    return st, moves
Exemplo n.º 2
0
def capture_board():
    gs = GameState(size=7)

    # another small board, this one with imminent captures
    #
    #         X
    #   0 1 2 3 4 5 6
    #   . . B B . . . 0
    #   . B W W B . . 1
    #   . B W . . . . 2
    # Y . . B . . . . 3
    #   . . . . W B . 4
    #   . . . W . W B 5
    #   . . . . W B . 6
    #
    # current_player = black

    black = [(2, 0), (3, 0), (1, 1), (4, 1), (1, 2), (2, 3), (5, 4), (6, 5), (5, 6)]
    white = [(2, 1), (3, 1), (2, 2), (4, 4), (3, 5), (5, 5), (4, 6)]

    for B in black:
        gs.do_move(B, go.BLACK)
    for W in white:
        gs.do_move(W, go.WHITE)
    gs.set_current_player(go.BLACK)

    return gs
Exemplo n.º 3
0
class play_match(object):
    """Interface to handle play between two players."""
    def __init__(self, player1, player2, save_dir=None, size=19):
        # super(ClassName, self).__init__()
        self.player1 = player1
        self.player2 = player2
        self.state = GameState(size=size)
        # I Propose that GameState should take a top-level save directory,
        # then automatically generate the specific file name

    def _play(self, player):
        move = player.get_move(self.state)
        # TODO: Fix is_eye?
        self.state.do_move(move)  # Return max prob sensible legal move
        # self.state.write_to_disk()
        if len(self.state.history) > 1:
            if self.state.history[-1] is None and self.state.history[-2] is None \
             and self.state.current_player == -1:
                end_of_game = True
            else:
                end_of_game = False
        else:
            end_of_game = False
        return end_of_game

    def play(self):
        """Play one turn, update game state, save to disk"""
        end_of_game = self._play(self.player1)
        # This is incorrect.
        return end_of_game
Exemplo n.º 4
0
class play_match(object):
    """Interface to handle play between two players."""

    def __init__(self, player1, player2, save_dir=None, size=19):
        # super(ClassName, self).__init__()
        self.player1 = player1
        self.player2 = player2
        self.state = GameState(size=size)
        # I Propose that GameState should take a top-level save directory,
        # then automatically generate the specific file name

    def _play(self, player):
        move = player.get_move(self.state)
        # TODO: Fix is_eye?
        self.state.do_move(move)  # Return max prob sensible legal move
        # self.state.write_to_disk()
        if len(self.state.history) > 1:
            if self.state.history[-1] is None and self.state.history[-2] is None and self.state.current_player == -1:
                end_of_game = True
            else:
                end_of_game = False
        else:
            end_of_game = False
        return end_of_game

    def play(self):
        """Play one turn, update game state, save to disk"""
        end_of_game = self._play(self.player1)
        # This is incorrect.
        return end_of_game
Exemplo n.º 5
0
class GTPGameConnector(object):
    """A class implementing the functions of a 'game' object required by the GTP
    Engine by wrapping a GameState and Player instance
    """
    def __init__(self, player):
        self._state = GameState(enforce_superko=True)
        self._player = player
        self._komi = 0

    def clear(self):
        self._state = GameState()

    def make_move(self, color, vertex):
        # vertex in GTP language is 1-indexed, whereas GameState's are zero-indexed
        if color == gtp.BLACK:
            color = go.BLACK
        else:
            color = go.WHITE
        try:
            if vertex == gtp.PASS:
                self._state.do_move(go.PASS)
            else:
                (x, y) = vertex
                self._state.do_move((x - 1, y - 1), color)
            return True
        except go.IllegalMove:
            return False

    def set_size(self, n):
        self._state = GameState(size=n, enforce_superko=True)

    def set_komi(self, k):
        self._komi = k

    def get_move(self, color):
        if color == gtp.BLACK:
            color = go.BLACK
        else:
            color = go.WHITE
        self._state.set_current_player(color)
        move = self._player.get_move(self._state)
        if move == go.PASS:
            return gtp.PASS
        else:
            (x, y) = move
            return (x + 1, y + 1)

    def get_current_state_as_sgf(self):
        from tempfile import NamedTemporaryFile
        temp_file = NamedTemporaryFile(delete=False)
        save_gamestate_to_sgf(self._state, '', temp_file.name)
        return temp_file.name

    def place_handicaps(self, vertices):
        actions = []
        for vertex in vertices:
            (x, y) = vertex
            actions.append((x - 1, y - 1))
        self._state.place_handicaps(actions)
Exemplo n.º 6
0
	def test_probabilistic_player(self):
		gs = GameState()
		policy = CNNPolicy(["board", "ones", "turns_since"])
		player = ProbabilisticPolicyPlayer(policy)
		for i in range(20):
			move = player.get_move(gs)
			self.assertIsNotNone(move)
			gs.do_move(move)
Exemplo n.º 7
0
 def test_probabilistic_player(self):
     gs = GameState()
     policy = CNNPolicy(["board", "ones", "turns_since"])
     player = ProbabilisticPolicyPlayer(policy)
     for i in range(20):
         move = player.get_move(gs)
         self.assertIsNotNone(move)
         gs.do_move(move)
Exemplo n.º 8
0
    def test_greedy_player(self):

        gs = GameState()
        policy = CNNPolicy(["board", "ones", "turns_since"])
        player = GreedyPolicyPlayer(policy)
        for _ in range(20):
            move = player.get_move(gs)
            self.assertNotEqual(move, go.PASS)
            gs.do_move(move)
Exemplo n.º 9
0
 def test_eye_recursion(self):
     # a checkerboard pattern of black is 'technically' all true eyes
     # mutually supporting each other
     gs = GameState(7)
     for x in range(gs.size):
         for y in range(gs.size):
             if (x + y) % 2 == 1:
                 gs.do_move((x, y), go.BLACK)
     self.assertTrue(gs.is_eye((0, 0), go.BLACK))
Exemplo n.º 10
0
	def test_eye_recursion(self):
		# a checkerboard pattern of black is 'technically' all true eyes
		# mutually supporting each other
		gs = GameState(7)
		for x in range(gs.size):
			for y in range(gs.size):
				if (x + y) % 2 == 1:
					gs.do_move((x, y), go.BLACK)
		self.assertTrue(gs.is_eye((0, 0), go.BLACK))
Exemplo n.º 11
0
    def test_probabilistic_player(self):

        gs = GameState(size=9)

        value = CNNValue(["board", "ones", "turns_since"], board=9)
        player = ValuePlayer(value)
        for i in range(10):
            move = player.get_move(gs)
            self.assertNotEqual(move, go.PASS)
            gs.do_move(move)
Exemplo n.º 12
0
	def test_sensible_greedy(self):
		gs = GameState()
		policy = CNNPolicy(["board", "ones", "turns_since"])
		player = GreedyPolicyPlayer(policy)
		empty = (10, 10)
		for x in range(19):
			for y in range(19):
				if (x, y) != empty:
					gs.do_move((x, y), go.BLACK)
		gs.current_player = go.BLACK
		self.assertIsNone(player.get_move(gs))
Exemplo n.º 13
0
 def test_sensible_greedy(self):
     gs = GameState()
     policy = CNNPolicy(["board", "ones", "turns_since"])
     player = GreedyPolicyPlayer(policy)
     empty = (10, 10)
     for x in range(19):
         for y in range(19):
             if (x, y) != empty:
                 gs.do_move((x, y), go.BLACK)
     gs.current_player = go.BLACK
     self.assertIsNone(player.get_move(gs))
Exemplo n.º 14
0
    def test_sensible_probabilistic(self):

        gs = GameState()
        policy = CNNPolicy(["board", "ones", "turns_since"])
        player = ProbabilisticPolicyPlayer(policy)
        empty = (10, 10)
        for x in range(19):
            for y in range(19):
                if (x, y) != empty:
                    gs.do_move((x, y), go.BLACK)
        gs.set_current_player(go.BLACK)
        self.assertEqual(player.get_move(gs), go.PASS)
    def test_copy_maintains_shared_sets(self):
        gs = GameState(7)
        gs.do_move((4, 4), go.BLACK)
        gs.do_move((4, 5), go.BLACK)

        # assert that gs has *the same object* referenced by group/liberty sets
        self.assertTrue(gs.group_sets[4][5] is gs.group_sets[4][4])
        self.assertTrue(gs.liberty_sets[4][5] is gs.liberty_sets[4][4])

        gs_copy = gs.copy()
        self.assertTrue(gs_copy.group_sets[4][5] is gs_copy.group_sets[4][4])
        self.assertTrue(
            gs_copy.liberty_sets[4][5] is gs_copy.liberty_sets[4][4])
Exemplo n.º 16
0
    def test_sensible_greedy(self):

        gs = GameState()

        value = CNNValue(["board", "ones", "turns_since"])
        player = ValuePlayer(value, greedy_start=0)
        empty = (10, 10)
        for x in range(19):
            for y in range(19):
                if (x, y) != empty:
                    gs.do_move((x, y), go.BLACK)
        gs.set_current_player(go.BLACK)
        self.assertEqual(player.get_move(gs), go.PASS)
Exemplo n.º 17
0
    def test_simple_eye(self):

        # create a black eye in top left (1,1), white in bottom right (5,5)

        gs = GameState(size=7)
        gs.do_move((1, 0))  # B
        gs.do_move((5, 4))  # W
        gs.do_move((2, 1))  # B
        gs.do_move((6, 5))  # W
        gs.do_move((1, 2))  # B
        gs.do_move((5, 6))  # W
        gs.do_move((0, 1))  # B
        gs.do_move((4, 5))  # W

        # test black eye top left
        self.assertTrue(gs.is_eye((1, 1), go.BLACK))
        self.assertFalse(gs.is_eye((1, 1), go.WHITE))

        # test white eye bottom right
        self.assertTrue(gs.is_eye((5, 5), go.WHITE))
        self.assertFalse(gs.is_eye((5, 5), go.BLACK))

        # test no eye in other random positions
        self.assertFalse(gs.is_eye((1, 0), go.BLACK))
        self.assertFalse(gs.is_eye((1, 0), go.WHITE))
        self.assertFalse(gs.is_eye((2, 2), go.BLACK))
        self.assertFalse(gs.is_eye((2, 2), go.WHITE))
Exemplo n.º 18
0
class TestLiberties(unittest.TestCase):

	def setUp(self):
		self.s = GameState()
		self.s.do_move((4,5))
		self.s.do_move((5,5))
		self.s.do_move((5,6))
		self.s.do_move((10,10))
		self.s.do_move((4,6))

		self.syms = self.s.symmetries()

	def test_lib_count(self):
		self.assertEqual(self.s.liberty_count(5,5), 2)
		print("liberty_count checked")

	def test_lib_pos(self):
		self.assertEqual(self.s.liberty_pos(5,5), ((6,5), (5,4)))
		print("liberty_pos checked")

	def test_curr_liberties(self):
		self.assertEqual(self.s.update_current_liberties()[5][5], 2)
		self.assertEqual(self.s.update_current_liberties()[4][5], 6)
		self.assertEqual(self.s.update_current_liberties()[5][6], 6)

		print("curr_liberties checked")

	def test_future_liberties(self):

		self.assertEqual(self.s.update_future_liberties((6,5))[6][5], 4)
		self.assertEqual(self.s.update_future_liberties((5,4))[5][4], 4)
		self.assertEqual(self.s.update_future_liberties((6,6))[5][6], 5)

		print("future_liberties checked")
Exemplo n.º 19
0
	def test_simple_eye(self):

		# create a black eye in top left (1,1), white in bottom right (5,5)

		gs = GameState(size=7)
		gs.do_move((1, 0))  # B
		gs.do_move((5, 4))  # W
		gs.do_move((2, 1))  # B
		gs.do_move((6, 5))  # W
		gs.do_move((1, 2))  # B
		gs.do_move((5, 6))  # W
		gs.do_move((0, 1))  # B
		gs.do_move((4, 5))  # W

		# test black eye top left
		self.assertTrue(gs.is_eye((1, 1), go.BLACK))
		self.assertFalse(gs.is_eye((1, 1), go.WHITE))

		# test white eye bottom right
		self.assertTrue(gs.is_eye((5, 5), go.WHITE))
		self.assertFalse(gs.is_eye((5, 5), go.BLACK))

		# test no eye in other random positions
		self.assertFalse(gs.is_eye((1, 0), go.BLACK))
		self.assertFalse(gs.is_eye((1, 0), go.WHITE))
		self.assertFalse(gs.is_eye((2, 2), go.BLACK))
		self.assertFalse(gs.is_eye((2, 2), go.WHITE))
    def test_positional_superko(self):
        move_list = [(0, 3), (0, 4), (1, 3), (1, 4), (2, 3), (2, 4), (2, 2),
                     (3, 4), (2, 1), (3, 3), (3, 1), (3, 2), (3, 0), (4, 2),
                     (1, 1), (4, 1), (8, 0), (4, 0), (8, 1), (0, 2), (8, 2),
                     (0, 1), (8, 3), (1, 0), (8, 4), (2, 0), (0, 0)]

        gs = GameState(size=9)
        for move in move_list:
            gs.do_move(move)
        self.assertTrue(gs.is_legal((1, 0)))

        gs = GameState(size=9, enforce_superko=True)
        for move in move_list:
            gs.do_move(move)
        self.assertFalse(gs.is_legal((1, 0)))
Exemplo n.º 21
0
 def test_snapback_is_not_ko(self):
     gs = GameState(size=5)
     # B o W B .
     # W W B . .
     # . . . . .
     # . . . . .
     # . . . . .
     # here, imagine black plays at 'o' capturing
     # the white stone at (2,0). White may play
     # again at (2,0) to capture the black stones
     # at (0,0), (1,0). this is 'snapback' not 'ko'
     # since it doesn't return the game to a
     # previous position
     B = [(0, 0), (2, 1), (3, 0)]
     W = [(0, 1), (1, 1), (2, 0)]
     for (b, w) in zip(B, W):
         gs.do_move(b)
         gs.do_move(w)
     # do the capture of the single white stone
     gs.do_move((1, 0))
     # there should be no ko
     self.assertIsNone(gs.ko)
     self.assertTrue(gs.is_legal((2, 0)))
     # now play the snapback
     gs.do_move((2, 0))
     # check that the numbers worked out
     self.assertEqual(gs.num_black_prisoners, 2)
     self.assertEqual(gs.num_white_prisoners, 1)
Exemplo n.º 22
0
	def test_snapback_is_not_ko(self):
		gs = GameState(size=5)
		# B o W B .
		# W W B . .
		# . . . . .
		# . . . . .
		# . . . . .
		# here, imagine black plays at 'o' capturing
		# the white stone at (2,0). White may play
		# again at (2,0) to capture the black stones
		# at (0,0), (1,0). this is 'snapback' not 'ko'
		# since it doesn't return the game to a
		# previous position
		B = [(0, 0), (2, 1), (3, 0)]
		W = [(0, 1), (1, 1), (2, 0)]
		for (b, w) in zip(B, W):
			gs.do_move(b)
			gs.do_move(w)
		# do the capture of the single white stone
		gs.do_move((1, 0))
		# there should be no ko
		self.assertIsNone(gs.ko)
		self.assertTrue(gs.is_legal((2, 0)))
		# now play the snapback
		gs.do_move((2, 0))
		# check that the numbers worked out
		self.assertEqual(gs.num_black_prisoners, 2)
		self.assertEqual(gs.num_white_prisoners, 1)
Exemplo n.º 23
0
    def test_hash_update_matches_actual_hash(self):
        gs = GameState(size=7)
        gs, moves = parseboard.parse("a x b . . . .|"
                                     "z c d . . . .|"
                                     ". . . . . . .|"
                                     ". . . y . . .|"
                                     ". . . . . . .|"
                                     ". . . . . . .|"
                                     ". . . . . . .|")

        # a,b,c,d are black, x,y,z,x are white
        move_order = ['a', 'x', 'b', 'y', 'c', 'z', 'd', 'x']
        for m in move_order:
            move_1d = flatten_idx(moves[m], gs.get_size())

            # 'Try' move and get hash
            with gs.try_stone(move_1d):
                hash1 = gs.get_hash()

            # Actually do move and get hash
            gs.do_move(moves[m])
            hash2 = gs.get_hash()

            self.assertEqual(hash1, hash2)
Exemplo n.º 24
0
	def test_neighbors_edge_cases(self):

		st = GameState()
		st.do_move((0, 0))  # B B . . . . .
		st.do_move((5, 5))  # B W . . . . .
		st.do_move((0, 1))  # . . . . . . .
		st.do_move((6, 6))  # . . . . . . .
		st.do_move((1, 0))  # . . . . . W .
		st.do_move((1, 1))  # . . . . . . W

		# get_group in the corner
		self.assertEqual(len(st.get_group((0, 0))), 3, "group size in corner")

		# get_group of an empty space
		self.assertEqual(len(st.get_group((4, 4))), 0, "group size of empty space")

		# get_group of a single piece
		self.assertEqual(len(st.get_group((5, 5))), 1, "group size of single piece")
Exemplo n.º 25
0
	def test_true_eye(self):
		gs = GameState(size=7)
		gs.do_move((1, 0), go.BLACK)
		gs.do_move((0, 1), go.BLACK)

		# false eye at 0,0
		self.assertTrue(gs.is_eyeish((0, 0), go.BLACK))
		self.assertFalse(gs.is_eye((0, 0), go.BLACK))

		# make it a true eye by turning the corner (1,1) into an eye itself
		gs.do_move((1, 2), go.BLACK)
		gs.do_move((2, 1), go.BLACK)
		gs.do_move((2, 2), go.BLACK)
		gs.do_move((0, 2), go.BLACK)

		self.assertTrue(gs.is_eyeish((0, 0), go.BLACK))
		self.assertTrue(gs.is_eye((0, 0), go.BLACK))
		self.assertTrue(gs.is_eye((1, 1), go.BLACK))
Exemplo n.º 26
0
    def test_neighbors_edge_cases(self):

        st = GameState()
        st.do_move((0, 0))  # B B . . . . .
        st.do_move((5, 5))  # B W . . . . .
        st.do_move((0, 1))  # . . . . . . .
        st.do_move((6, 6))  # . . . . . . .
        st.do_move((1, 0))  # . . . . . W .
        st.do_move((1, 1))  # . . . . . . W

        # get_group in the corner
        self.assertEqual(len(st.get_group((0, 0))), 3, "group size in corner")

        # get_group of an empty space
        self.assertEqual(len(st.get_group((4, 4))), 0, "group size of empty space")

        # get_group of a single piece
        self.assertEqual(len(st.get_group((5, 5))), 1, "group size of single piece")
Exemplo n.º 27
0
    def test_true_eye(self):
        gs = GameState(size=7)
        gs.do_move((1, 0), go.BLACK)
        gs.do_move((0, 1), go.BLACK)

        # false eye at 0, 0
        self.assertTrue(gs.is_eyeish((0, 0), go.BLACK))
        self.assertFalse(gs.is_eye((0, 0), go.BLACK))

        # make it a true eye by turning the corner (1, 1) into an eye itself
        gs.do_move((1, 2), go.BLACK)
        gs.do_move((2, 1), go.BLACK)
        gs.do_move((2, 2), go.BLACK)
        gs.do_move((0, 2), go.BLACK)

        self.assertTrue(gs.is_eyeish((0, 0), go.BLACK))
        self.assertTrue(gs.is_eye((0, 0), go.BLACK))
        self.assertTrue(gs.is_eye((1, 1), go.BLACK))
Exemplo n.º 28
0
class TestLiberties(unittest.TestCase):

    def setUp(self):
        self.s = GameState()
        self.s.do_move((4, 5))
        self.s.do_move((5, 5))
        self.s.do_move((5, 6))
        self.s.do_move((10, 10))
        self.s.do_move((4, 6))
        self.s.do_move((10, 11))
        self.s.do_move((6, 6))
        self.s.do_move((9, 10))

    def test_curr_liberties(self):
        self.assertEqual(self.s.liberty_counts[5][5], 2)
        self.assertEqual(self.s.liberty_counts[4][5], 8)
        self.assertEqual(self.s.liberty_counts[5][6], 8)

    def test_neighbors_edge_cases(self):

        st = GameState()
        st.do_move((0, 0))  # B B . . . . .
        st.do_move((5, 5))  # B W . . . . .
        st.do_move((0, 1))  # . . . . . . .
        st.do_move((6, 6))  # . . . . . . .
        st.do_move((1, 0))  # . . . . . W .
        st.do_move((1, 1))  # . . . . . . W

        # get_group in the corner
        self.assertEqual(len(st.get_group((0, 0))), 3, "group size in corner")

        # get_group of an empty space
        self.assertEqual(len(st.get_group((4, 4))), 0, "group size of empty space")

        # get_group of a single piece
        self.assertEqual(len(st.get_group((5, 5))), 1, "group size of single piece")
Exemplo n.º 29
0
class TestSymmetries(unittest.TestCase):
    def setUp(self):
        self.s = GameState()
        self.s.do_move((4, 5))
        self.s.do_move((5, 5))
        self.s.do_move((5, 6))

        self.syms = self.s.symmetries()

    def test_num_syms(self):
        # make sure we got exactly 8 back
        self.assertEqual(len(self.syms), 8)

    def test_copy_fields(self):
        # make sure each copy has the correct non-board fields
        for copy in self.syms:
            self.assertEqual(self.s.size, copy.size)
            self.assertEqual(self.s.turns_played, copy.turns_played)
            self.assertEqual(self.s.current_player, copy.current_player)

    def test_sym_boards(self):
        # construct by hand the 8 boards we expect to see
        expectations = [GameState() for i in range(8)]

        descriptions = [
            "noop", "rot90", "rot180", "rot270", "mirror LR", "mirror UD",
            "mirror \\", "mirror /"
        ]

        # copy of self.s
        expectations[0].do_move((4, 5))
        expectations[0].do_move((5, 5))
        expectations[0].do_move((5, 6))

        # rotate 90 CCW
        expectations[1].do_move((13, 4))
        expectations[1].do_move((13, 5))
        expectations[1].do_move((12, 5))

        # rotate 180
        expectations[2].do_move((14, 13))
        expectations[2].do_move((13, 13))
        expectations[2].do_move((13, 12))

        # rotate CCW 270
        expectations[3].do_move((5, 14))
        expectations[3].do_move((5, 13))
        expectations[3].do_move((6, 13))

        # mirror left-right
        expectations[4].do_move((4, 13))
        expectations[4].do_move((5, 13))
        expectations[4].do_move((5, 12))

        # mirror up-down
        expectations[5].do_move((14, 5))
        expectations[5].do_move((13, 5))
        expectations[5].do_move((13, 6))

        # mirror \ diagonal
        expectations[6].do_move((5, 4))
        expectations[6].do_move((5, 5))
        expectations[6].do_move((6, 5))

        # mirror / diagonal (equivalently: rotate 90 CCW then flip LR)
        expectations[7].do_move((13, 14))
        expectations[7].do_move((13, 13))
        expectations[7].do_move((12, 13))

        for i in range(8):
            self.assertTrue(
                np.array_equal(expectations[i].board, self.syms[i].board),
                descriptions[i])
Exemplo n.º 30
0
class TestMCTS(unittest.TestCase):
    def setUp(self):
        self.gs = GameState()
        self.mcts = MCTS(dummy_value, dummy_policy, dummy_rollout, n_playout=2)

    def _count_expansions(self):
        """Helper function to count the number of expansions past the root using the dummy policy
        """
        node = self.mcts._root
        expansions = 0
        # Loop over actions in decreasing probability.
        for action, _ in sorted(dummy_policy(self.gs),
                                key=itemgetter(1),
                                reverse=True):
            if action in node._children:
                expansions += 1
                node = node._children[action]
            else:
                break
        return expansions

    def test_playout(self):
        self.mcts._playout(self.gs.copy(), 8)
        # Assert that the most likely child was visited (according to the dummy policy below).
        self.assertEqual(1, self.mcts._root._children[(18, 18)]._n_visits)
        # Assert that the search depth expanded nodes 8 times.
        self.assertEqual(8, self._count_expansions())

    def test_playout_with_pass(self):
        # Test that playout handles the end of the game (i.e. passing/no moves). Mock this by
        # creating a policy that returns nothing after 4 moves.
        def stop_early_policy(state):
            if len(state.history) <= 4:
                return dummy_policy(state)
            else:
                return []

        self.mcts = MCTS(dummy_value,
                         stop_early_policy,
                         stop_early_policy,
                         n_playout=2)
        self.mcts._playout(self.gs.copy(), 8)
        # Assert that (18, 18) and (18, 17) are still only visited once.
        self.assertEqual(1, self.mcts._root._children[(18, 18)]._n_visits)
        # Assert that no expansions happened after reaching the "end" in 4 moves.
        self.assertEqual(5, self._count_expansions())

    def test_get_move(self):
        move = self.mcts.get_move(self.gs)
        self.mcts.update_with_move(move)
        # success if no errors

    def test_update_with_move(self):
        move = self.mcts.get_move(self.gs)
        self.gs.do_move(move)
        self.mcts.update_with_move(move)
        # Assert that the new root still has children.
        self.assertTrue(len(self.mcts._root._children) > 0)
        # Assert that the new root has no parent (the rest of the tree will be garbage collected).
        self.assertIsNone(self.mcts._root._parent)
        # Assert that the next best move according to the root is (18, 17), according to the
        # dummy policy below.
        self.assertEqual((18, 17), self.mcts._root.select()[0])
Exemplo n.º 31
0
	def test_liberties_after_capture(self):
		# creates 3x3 black group in the middle, that is then all captured
		# ...then an assertion is made that the resulting liberties after
		# capture are the same as if the group had never been there
		gs_capture = GameState(7)
		gs_reference = GameState(7)
		# add in 3x3 black stones
		for x in range(2, 5):
			for y in range(2, 5):
				gs_capture.do_move((x, y), go.BLACK)
		# surround the black group with white stones
		# and set the same white stones in gs_reference
		for x in range(2, 5):
			gs_capture.do_move((x, 1), go.WHITE)
			gs_capture.do_move((x, 5), go.WHITE)
			gs_reference.do_move((x, 1), go.WHITE)
			gs_reference.do_move((x, 5), go.WHITE)
		gs_capture.do_move((1, 1), go.WHITE)
		gs_reference.do_move((1, 1), go.WHITE)
		for y in range(2, 5):
			gs_capture.do_move((1, y), go.WHITE)
			gs_capture.do_move((5, y), go.WHITE)
			gs_reference.do_move((1, y), go.WHITE)
			gs_reference.do_move((5, y), go.WHITE)

		# board configuration and liberties of gs_capture and of gs_reference should be identical
		self.assertTrue(np.all(gs_reference.board == gs_capture.board))
		self.assertTrue(np.all(gs_reference.liberty_counts == gs_capture.liberty_counts))
Exemplo n.º 32
0
    def test_liberties_after_capture(self):
        # creates 3x3 black group in the middle, that is then all captured
        # ...then an assertion is made that the resulting liberties after
        # capture are the same as if the group had never been there
        gs_capture = GameState(7)
        gs_reference = GameState(7)
        # add in 3x3 black stones
        for x in range(2, 5):
            for y in range(2, 5):
                gs_capture.do_move((x, y), go.BLACK)
        # surround the black group with white stones
        # and set the same white stones in gs_reference
        for x in range(2, 5):
            gs_capture.do_move((x, 1), go.WHITE)
            gs_capture.do_move((x, 5), go.WHITE)
            gs_reference.do_move((x, 1), go.WHITE)
            gs_reference.do_move((x, 5), go.WHITE)
        gs_capture.do_move((1, 1), go.WHITE)
        gs_reference.do_move((1, 1), go.WHITE)
        for y in range(2, 5):
            gs_capture.do_move((1, y), go.WHITE)
            gs_capture.do_move((5, y), go.WHITE)
            gs_reference.do_move((1, y), go.WHITE)
            gs_reference.do_move((5, y), go.WHITE)

        # board configuration and liberties of gs_capture and of gs_reference should be identical
        self.assertTrue(np.all(gs_reference.board == gs_capture.board))
        self.assertTrue(
            np.all(gs_reference.liberty_counts == gs_capture.liberty_counts))
Exemplo n.º 33
0
class TestLiberties(unittest.TestCase):

	def setUp(self):
		self.s = GameState()
		self.s.do_move((4,5))
		self.s.do_move((5,5))
		self.s.do_move((5,6))
		self.s.do_move((10,10))
		self.s.do_move((4,6))
		self.s.do_move((10,11))
		self.s.do_move((6,6))
		self.s.do_move((9, 10))

		self.syms = self.s.symmetries()

	def test_lib_count(self):
		self.assertEqual(self.s.liberty_count((5,5)), 2)
		print("liberty_count checked")

	def test_lib_pos(self):
		self.assertEqual(self.s.liberty_pos((5,5)), [(6,5), (5,4)])
		print("liberty_pos checked")

	def test_curr_liberties(self):
		self.assertEqual(self.s.update_current_liberties()[5][5], 2)
		self.assertEqual(self.s.update_current_liberties()[4][5], 8)
		self.assertEqual(self.s.update_current_liberties()[5][6], 8)

		print("curr_liberties checked")

	def test_future_liberties(self):
		print(self.s.update_future_liberties((4,4)))
		self.assertEqual(self.s.update_future_liberties((6,5))[6][5], 9)
		self.assertEqual(self.s.update_future_liberties((5,4))[5][4], 3)
		self.assertEqual(self.s.update_future_liberties((4,4))[4][4], 10)

		print("future_liberties checked")

	def test_neighbors_edge_cases(self):

		st = GameState()
		st.do_move((0,0)) #  B B . . . . . 
		st.do_move((5,5)) #  B W . . . . . 
		st.do_move((0,1)) #  . . . . . . . 
		st.do_move((6,6)) #  . . . . . . . 
		st.do_move((1,0)) #  . . . . . W . 
		st.do_move((1,1)) #  . . . . . . W

		# visit_neighbor in the corner
		self.assertEqual(len(st.visit_neighbor((0,0))), 3, "group size in corner")

		# visit_neighbor of an empty space
		self.assertEqual(len(st.visit_neighbor((4,4))), 0, "group size of empty space")

		# visit_neighbor of a single piece
		self.assertEqual(len(st.visit_neighbor((5,5))), 1, "group size of single piece")
Exemplo n.º 34
0
    def test_standard_ko(self):
        gs = GameState(size=9)
        gs.do_move((1, 0))  # B
        gs.do_move((2, 0))  # W
        gs.do_move((0, 1))  # B
        gs.do_move((3, 1))  # W
        gs.do_move((1, 2))  # B
        gs.do_move((2, 2))  # W
        gs.do_move((2, 1))  # B

        gs.do_move((1, 1))  # W trigger capture and ko

        self.assertEqual(gs.num_black_prisoners, 1)
        self.assertEqual(gs.num_white_prisoners, 0)

        self.assertFalse(gs.is_legal((2, 1)))

        gs.do_move((5, 5))
        gs.do_move((5, 6))

        self.assertTrue(gs.is_legal((2, 1)))
Exemplo n.º 35
0
def self_atari_board():
    gs = GameState(size=7)

    # another tiny board for testing self-atari specifically.
    # positions marked with 'a' are self-atari for black
    #
    #         X
    #   0 1 2 3 4 5 6
    #   a W . . . W B 0
    #   . . . . . . . 1
    #   . . . . . . . 2
    # Y . . W . W . . 3
    #   . W B a B W . 4
    #   . . W W W . . 5
    #   . . . . . . . 6
    #
    # current_player = black

    gs.do_move((2, 4), go.BLACK)
    gs.do_move((4, 4), go.BLACK)
    gs.do_move((6, 0), go.BLACK)

    gs.do_move((1, 0), go.WHITE)
    gs.do_move((5, 0), go.WHITE)
    gs.do_move((2, 3), go.WHITE)
    gs.do_move((4, 3), go.WHITE)
    gs.do_move((1, 4), go.WHITE)
    gs.do_move((5, 4), go.WHITE)
    gs.do_move((2, 5), go.WHITE)
    gs.do_move((3, 5), go.WHITE)
    gs.do_move((4, 5), go.WHITE)

    return gs
Exemplo n.º 36
0
	def test_standard_ko(self):
		gs = GameState(size=9)
		gs.do_move((1, 0))  # B
		gs.do_move((2, 0))  # W
		gs.do_move((0, 1))  # B
		gs.do_move((3, 1))  # W
		gs.do_move((1, 2))  # B
		gs.do_move((2, 2))  # W
		gs.do_move((2, 1))  # B

		gs.do_move((1, 1))  # W trigger capture and ko

		self.assertEqual(gs.num_black_prisoners, 1)
		self.assertEqual(gs.num_white_prisoners, 0)

		self.assertFalse(gs.is_legal((2, 1)))

		gs.do_move((5, 5))
		gs.do_move((5, 6))

		self.assertTrue(gs.is_legal((2, 1)))
Exemplo n.º 37
0
def simple_board():
    gs = GameState(size=7)

    # make a tiny board for the sake of testing and hand-coding expected results
    #
    #         X
    #   0 1 2 3 4 5 6
    #   B W . . . . . 0
    #   B W . . . . . 1
    #   B . . . B . . 2
    # Y . . . B k B . 3
    #   . . . W B W . 4
    #   . . . . W . . 5
    #   . . . . . . . 6
    #
    # where k is a ko position (white was just captured)

    # ladder-looking thing in the top-left
    gs.do_move((0, 0))  # B
    gs.do_move((1, 0))  # W
    gs.do_move((0, 1))  # B
    gs.do_move((1, 1))  # W
    gs.do_move((0, 2))  # B

    # ko position in the middle
    gs.do_move((3, 4))  # W
    gs.do_move((3, 3))  # B
    gs.do_move((4, 5))  # W
    gs.do_move((4, 2))  # B
    gs.do_move((5, 4))  # W
    gs.do_move((5, 3))  # B
    gs.do_move((4, 3))  # W - the ko position
    gs.do_move((4, 4))  # B - does the capture

    return gs
Exemplo n.º 38
0
class TestLiberties(unittest.TestCase):

	def setUp(self):
		self.s = GameState()
		self.s.do_move((4, 5))
		self.s.do_move((5, 5))
		self.s.do_move((5, 6))
		self.s.do_move((10, 10))
		self.s.do_move((4, 6))
		self.s.do_move((10, 11))
		self.s.do_move((6, 6))
		self.s.do_move((9, 10))

	def test_curr_liberties(self):
		self.assertEqual(self.s.liberty_counts[5][5], 2)
		self.assertEqual(self.s.liberty_counts[4][5], 8)
		self.assertEqual(self.s.liberty_counts[5][6], 8)

	def test_neighbors_edge_cases(self):

		st = GameState()
		st.do_move((0, 0))  # B B . . . . .
		st.do_move((5, 5))  # B W . . . . .
		st.do_move((0, 1))  # . . . . . . .
		st.do_move((6, 6))  # . . . . . . .
		st.do_move((1, 0))  # . . . . . W .
		st.do_move((1, 1))  # . . . . . . W

		# get_group in the corner
		self.assertEqual(len(st.get_group((0, 0))), 3, "group size in corner")

		# get_group of an empty space
		self.assertEqual(len(st.get_group((4, 4))), 0, "group size of empty space")

		# get_group of a single piece
		self.assertEqual(len(st.get_group((5, 5))), 1, "group size of single piece")
Exemplo n.º 39
0
class TestLiberties(unittest.TestCase):
    def setUp(self):
        self.s = GameState()
        self.s.do_move((4, 5))
        self.s.do_move((5, 5))
        self.s.do_move((5, 6))
        self.s.do_move((10, 10))
        self.s.do_move((4, 6))
        self.s.do_move((10, 11))
        self.s.do_move((6, 6))
        self.s.do_move((9, 10))

        self.syms = self.s.symmetries()

    def test_lib_count(self):
        self.assertEqual(self.s.liberty_count((5, 5)), 2)
        print("liberty_count checked")

    def test_lib_pos(self):
        self.assertEqual(self.s.liberty_pos((5, 5)), [(6, 5), (5, 4)])
        print("liberty_pos checked")

    def test_curr_liberties(self):
        self.assertEqual(self.s.update_current_liberties()[5][5], 2)
        self.assertEqual(self.s.update_current_liberties()[4][5], 8)
        self.assertEqual(self.s.update_current_liberties()[5][6], 8)

        print("curr_liberties checked")

    def test_future_liberties(self):
        print(self.s.update_future_liberties((4, 4)))
        self.assertEqual(self.s.update_future_liberties((6, 5))[6][5], 9)
        self.assertEqual(self.s.update_future_liberties((5, 4))[5][4], 3)
        self.assertEqual(self.s.update_future_liberties((4, 4))[4][4], 10)

        print("future_liberties checked")

    def test_neighbors_edge_cases(self):

        st = GameState()
        st.do_move((0, 0))  #  B B . . . . .
        st.do_move((5, 5))  #  B W . . . . .
        st.do_move((0, 1))  #  . . . . . . .
        st.do_move((6, 6))  #  . . . . . . .
        st.do_move((1, 0))  #  . . . . . W .
        st.do_move((1, 1))  #  . . . . . . W

        # visit_neighbor in the corner
        self.assertEqual(len(st.visit_neighbor((0, 0))), 3,
                         "group size in corner")

        # visit_neighbor of an empty space
        self.assertEqual(len(st.visit_neighbor((4, 4))), 0,
                         "group size of empty space")

        # visit_neighbor of a single piece
        self.assertEqual(len(st.visit_neighbor((5, 5))), 1,
                         "group size of single piece")
Exemplo n.º 40
0
class TestSymmetries(unittest.TestCase):

	def setUp(self):
		self.s = GameState()
		self.s.do_move((4,5))
		self.s.do_move((5,5))
		self.s.do_move((5,6))

		self.syms = self.s.symmetries()

	def test_num_syms(self):
		# make sure we got exactly 8 back
		self.assertEqual(len(self.syms), 8)

	def test_copy_fields(self):
		# make sure each copy has the correct non-board fields
		for copy in self.syms:
			self.assertEqual(self.s.size, copy.size)
			self.assertEqual(self.s.turns_played, copy.turns_played)
			self.assertEqual(self.s.current_player, copy.current_player)

	def test_sym_boards(self):
		# construct by hand the 8 boards we expect to see
		expectations = [GameState() for i in range(8)]

		descriptions = ["noop", "rot90", "rot180", "rot270", "mirror LR", "mirror UD", "mirror \\", "mirror /"]

		# copy of self.s
		expectations[0].do_move((4,5))
		expectations[0].do_move((5,5))
		expectations[0].do_move((5,6))

		# rotate 90 CCW
		expectations[1].do_move((13,4))
		expectations[1].do_move((13,5))
		expectations[1].do_move((12,5))

		# rotate 180
		expectations[2].do_move((14,13))
		expectations[2].do_move((13,13))
		expectations[2].do_move((13,12))

		# rotate CCW 270
		expectations[3].do_move((5,14))
		expectations[3].do_move((5,13))
		expectations[3].do_move((6,13))

		# mirror left-right
		expectations[4].do_move((4,13))
		expectations[4].do_move((5,13))
		expectations[4].do_move((5,12))

		# mirror up-down
		expectations[5].do_move((14,5))
		expectations[5].do_move((13,5))
		expectations[5].do_move((13,6))

		# mirror \ diagonal
		expectations[6].do_move((5,4))
		expectations[6].do_move((5,5))
		expectations[6].do_move((6,5))

		# mirror / diagonal (equivalently: rotate 90 CCW then flip LR)
		expectations[7].do_move((13,14))
		expectations[7].do_move((13,13))
		expectations[7].do_move((12,13))

		for i in range(8):
			self.assertTrue(np.array_equal(expectations[i].board, self.syms[i].board), descriptions[i])