def test_board_equivalence(self): size = 9 cache = BitBoardCache("../cache/9-magics", size=9, win_chain_length=5, force_build_win_checks=False) bitboard = BitBoard(cache, size=9, win_chain_length=5) normal_board = Board(size=9, win_chain_length=5) fboard_1 = FeatureBoard_v1_1(bitboard) fboard_2 = FeatureBoard_v1_1(normal_board) for i in range(1000): if np.random.rand() < 0.5: normal_board.make_random_move() bitboard.move(normal_board.get_last_move()) if normal_board.game_over(): break fboard_1.move(normal_board.get_last_move()) fboard_2.move(normal_board.get_last_move()) elif normal_board.get_last_move(): normal_board.unmove() bitboard.unmove() fboard_1.unmove() fboard_2.unmove() self.verify_sync(normal_board, fboard_2) self.verify_sync(bitboard, fboard_1)
def test_mass_play(self): for i in range(1000): board = Board(size=7, win_chain_length=4) board.make_random_move() if board.game_over(): self.assertTrue(board.game_won() or board.game_assume_drawn()) if board.game_assume_drawn(): self.assertTrue(board.game_over())
def test_thoughtboard_consistency(self): board = Board(size=9, win_chain_length=5) fb = FeatureBoard_v1_1(board) tb = ThoughtBoard(board, FeatureBoard_v1_1) fb.move(15) movelist = MoveList((), []).append(15) self.assertTrue( np.equal(fb.get_p_features(), tb.get_p_features_after(movelist)).all()) movelist_2 = movelist.append(32) fb.move(32) self.assertTrue( np.equal(fb.get_p_features(), tb.get_p_features_after(movelist_2)).all()) fb.unmove() self.assertTrue( np.equal(fb.get_p_features(), tb.get_p_features_after(movelist)).all()) fb.move(32) self.assertTrue( np.equal(fb.get_p_features(), tb.get_p_features_after(movelist_2)).all()) tb.make_move(15) tb.make_move(32) self.assertTrue( np.equal(fb.get_p_features(), tb.get_q_features()).all())
def replay(self): board = Board.load(self.initial_state) print(board.pprint()) for i, move in enumerate(self.moves): print('Q', self.q_assessments[i]) board.move(move) print(board.pprint())
def test_thoughtboard_root_win(self): trivial_board = Board(size=9, win_chain_length=5) trivial_board.set_to_one_move_from_win() tb = ThoughtBoard(trivial_board, FeatureBoard_v1_1) trivial_board.move(36) print(trivial_board.pprint()) move_list = MoveList((), []).append(36) self.assertTrue(trivial_board.game_won()) self.assertTrue(tb.game_over_after(move_list))
def test_move_available_vector(self): board = Board(size=9, win_chain_length=5) fb = FeatureBoard_v1_1(board) tb = ThoughtBoard(board, FeatureBoard_v1_1) self.assertEqual(np.sum(tb.get_available_move_vector_after([34, 45])), 79) fb.move(15) self.assertEqual(np.sum(fb.get_init_available_move_vector()), 81) self.assertEqual(np.sum(tb.get_available_move_vector_after([18, 25])), 79)
def test_export_parse(self): board = Board(size=9, win_chain_length=5) for i in range(10): board.make_random_move() parsed_board = Board.load(board.export()) self.assertEqual(board.pprint(lastmove_highlight=False), parsed_board.pprint(lastmove_highlight=False)) self.assertFalse(parsed_board.game_over()) self.assertFalse(parsed_board.game_won()) self.assertTrue(np.equal(parsed_board._matrix, board._matrix).all())
def iterate_on(self, record): board = Board.load(record.get_initial_state()) q_assessments = record.get_q_assessments() for i, move in enumerate(record.get_moves()): if record.get_winning_player() == board.get_player_to_move(): self.make_feature_tensors(board, move, q_assessments[i][0], q_assessments[i][1]) # learn drawn positions elif record.get_winning_player() == Player.NONE: self.make_feature_tensors(board, move, q_assessments[i][0], q_assessments[i][1]) board.move(move)
def test_parse(self): board = Board(size=9) board.move_coord(5, 5) record = GameRecord.create(board) record.add_move(35, 0, 0) record.set_winner(1) with self.assertRaises(ValueError): record.add_move(45, 0, 0) board = Board(size=9) record2 = GameRecord.create(board) record2.add_move(45, 0, 0) record2.add_move(35, 0, 0) record2.set_winner(1)
def test_even_search(self): mind = PExpMind_v3(size=9, init=False, search_params=None) mind.load_net('../../models/voldmaster_' + str(0)) board = Board(size=9, win_chain_length=5) searcher = PEvenSearch(board, mind.policy_est, mind.value_est, max_iterations=2, p_batch_size=1024, verbose=True, validations=True) searcher.p_expand() self.assertGreater(len(searcher.expandable_nodes), 0) for node in searcher.expandable_nodes: self.assertEqual(list(node.get_parents())[0], searcher.root_node) self.assertLess(node.log_total_p, 0) searcher.q_eval() self.assertNotEqual(searcher.root_node.get_principal_variation(), None)
def test_rotator(self): rot = BoardTransform(size=9) for i in range(9 * 9): x, y = rot.index_to_coordinate(i) # print(x, y, i) self.assertEqual(i, rot.coordinate_to_index(x, y)) board = Board(size=9, win_chain_length=5) moves = [(0, 0), (2, 1), (5, 5), (4, 4)] for i, move in enumerate(moves): board.move_coord(move[0], move[1]) print(board.pprint()) index = rot.coordinate_to_index(move[0], move[1]) rotated_matrices = rot.get_rotated_matrices(board._matrix.reshape((board.get_size(), board.get_size(), 1))) self.assertFalse(np.equal(rotated_matrices[0], rotated_matrices[2]).all()) for point, mat in zip(rot.get_rotated_points(index), rotated_matrices): x, y = rot.index_to_coordinate(point) self.assertEqual(mat[x][y][0], board.get_player_last_move().value)
def test_deepcopy(self): board = Board(size=7, win_chain_length=4) import copy copied_board = copy.deepcopy(board) board.move(22) self.assertNotEqual(board.get_spot(22), copied_board.get_spot(22))
def test_double_serialize(self): board = Board(size=9, win_chain_length=5) json.loads(json.dumps(board.export()))
def test_odd_board_bug(self): board = Board(size=9, win_chain_length=5) board.move_coord(4, 0) board.move_coord(4, 1) board.move_coord(3, 0) board.move_coord(3, 1) board.move_coord(2, 0) board.move_coord(2, 1) board.move_coord(1, 0) board.move_coord(1, 1) board.move_coord(0, 0) self.assertTrue(board.game_won())
def test_precomputed_checklengths(self): board = Board(size=9, win_chain_length=5) self.assertEqual(board._check_locations[(0, -1, 0)], ()) self.assertEqual(board._check_locations[(0, 1, 0)], (1, 2, 3, 4)) self.assertEqual(board._check_locations[(0, 0, 1)], (9, 18, 27, 36))
def run(): mind = pexp_mind.PExpMind(size=SIZE, init=False, channels=4) mind.load_net('../models/9_4_4') rs = RandomState(42) for i in range(50): board = Board(size=SIZE, win_chain_length=5, draw_point=50) print('Game', i) # randomize the board a bit for j in range(rs.randint(0, 10)): board.make_random_move() # board.move(2, 2) # board.move(0, 1) # board.move(2, 3) # board.move(2, 1) # board.move(2, 4) # board.move(3, 1) # board.move(4, 3) # board.move(3, 4) # board.move(6, 6) # board.move(4, 1) # board.move(0, 0) # board.move(1, 0) # board.move(0, 4) # board.move(2, 2) # board.move(0, 7) # board.move(3, 0) # board.move(1, 2) # board.move(3, 7) # board.move(1, 6) # board.move(4, 4) # board.move(1, 8) # board.move(4, 5) # board.move(2, 0) # board.move(4, 6) # board.move(2, 4) # board.move(4, 8) # board.move(2, 8) # board.move(5, 0) # board.move(3, 1) # board.move(5, 4) # board.move(3, 6) # board.move(5, 8) # board.move(4, 0) # board.move(6, 3) # board.move(4, 3) # board.move(7, 2) # board.move(4, 7) # board.move(7, 6) # board.move(6, 6) # board.move(8, 0) # board.move(8, 1) # board.move(8, 8) # board.move(8, 7) print(board) current_player = board.get_player_to_move() def expanding_p(depth, p): return np.logical_or.reduce([ np.logical_and(depth < 2, p > -6), np.logical_and(depth < 4, p > -4), np.logical_and(depth < 6, p > -4), np.logical_and(depth < np.inf, p > -3) ]) def permissive_expansion(depth): if depth < 2: return np.inf if depth < 8: return 5 return 3 mind.define_policies(expanding_p, permissive_expansion, convergence_count=5, alpha=0.2, q_exp_batch_size=SIZE**2, p_exp_batch_size=SIZE**3, required_depth=6, max_iters=20) while True: result = mind.make_move(board, as_player=current_player, epsilon=0.1, consistency_check=False, verbose=True) print(board.pprint()) if current_player == Board.FIRST_PLAYER: current_player = Board.SECOND_PLAYER else: current_player = Board.FIRST_PLAYER if result: break print('done')
def test_chain_length(self): board = Board(size=9, win_chain_length=4) self.assertEqual(board.get_spot_coord(0, 0), Player.NONE) board.move_coord(0, 0) self.assertEqual(board.get_spot_coord(0, 0), Player.FIRST) self.assertFalse(board.is_move_available(0)) board.move_coord(0, 1) board.move_coord(1, 1) self.assertEqual(board.get_spot_coord(1, 1), Player.FIRST) index00 = board._transformer.coordinate_to_index(0, 0) index11 = board._transformer.coordinate_to_index(1, 1) assert (board.chain_length(index11, -1, 0) == 1) assert (board.chain_length(index11, -1, -1) == 2) assert (board.chain_length(index00, 1, 1) == 2) board.move_coord(1, 0) board.move_coord(2, 2) board.move_coord(2, 3) board.move_coord(3, 3) board.unmove() board.move_coord(3, 3) index33 = board._transformer.coordinate_to_index(3, 3) self.assertEqual(board.chain_length(index33, 1, 1), 1) self.assertEqual(board.get_spot_coord(2, 2), Player.FIRST) assert (board.game_won())
if depth < 2: return np.inf if depth < 8: return 5 return 3 mind.define_policies(expanding_p, permissive_expansion, convergence_count=5, alpha=0.2, q_exp_batch_size=SIZE**2, p_exp_batch_size=SIZE**3, required_depth=6, max_iters=25) board = Board(size=SIZE, win_chain_length=5) # randomize the board a bit for j in range(random.randint(0, int(SIZE * 2.5))): board.make_random_move() print(board.guide_print()) while True: if board.get_player_to_move() == Board.FIRST_PLAYER: inp = input("Input your move (i.e. \"3 5\"): ") if len(inp.split(' ')) != 2: print('Incorrect number of coordinates, please try again!') continue x, y = inp.split(' ') try: