Ejemplo n.º 1
0
def play_game_from_file(pgn_path):
    game = Game()
    with open(pgn_path) as game_file:
        pgn = chess.pgn.read_game(game_file)
        for move in pgn.mainline_moves():
            game.apply(move.uci())

            children = {}
            for idx in range(game.NUM_ACTIONS):
                child = Node(None)
                child.visit_count = 1 if idx == game.get_num_turn() - 1 else 0
                children[idx] = child
            root = Node(None)
            root.children = children
            game.store_search_statistics(root)
    return game
Ejemplo n.º 2
0
def play(location, option):

    model: tf.keras.Model = tf.keras.models.load_model(location)
    minimax = Minimax(model)

    logo.show()
    print('\n\n')

    side = None
    while side not in ['W', 'B']:
        side = input('Play as:\nWhite (W) | Black (B) | Random (R) > ')
        if side == 'R':
            side = 'W' if np.random.uniform() < 0.5 else 'B'
    side = side == 'W'

    szr = serializer.Serializer(None)
    if option == 'P':
        pgn = chess.pgn.read_game(io.StringIO(input('Paste PGN:\n> ')))
        for move in pgn.mainline_moves():
            szr.board.push(move)

    while not szr.board.is_game_over():
        logo.show()
        print('\n\n')

        display_board(szr.board, side)
        score = model.predict(np.expand_dims(szr.serialize(), 0))
        print(f'ch0ss evaluation: {score}')

        if szr.board.turn == side:
            uci = None
            while not szr.board.is_legal(uci):
                if uci is not None:
                    print('Illegal move')
                try:
                    uci = chess.Move.from_uci(input('Type your move:\n > '))
                except ValueError:
                    print('Invalid move')
                    uci = None
            if szr.board.is_legal(uci):
                szr.board.push(uci)
            else:
                print('Illegal move.')
        else:
            print('ch0ss is thinking...')
            move = minimax.search(szr.board, 3, side)
            szr.board.push(move[1])
Ejemplo n.º 3
0
def process_game(args):
    #print("Process Game")
    game_number = args['game_number']
    progress_queue = args['progress_queue']
    db_lock = args['db_lock']
    gid = args['gid']
    pgn = args['pgn']
    moves = list(pgn.mainline_moves())
    # Get the game DB object and the PGN moves
    with db_lock:
        game_obj, _ = Game.get_or_create(id=gid)

        white, _ = Player.get_or_create(username=pgn.headers['White'].lower())
        black, _ = Player.get_or_create(username=pgn.headers['Black'].lower())
        GamePlayer.get_or_create(game=game_obj, color='w', defaults={'player':white})
        GamePlayer.get_or_create(game=game_obj, color='b', defaults={'player':black})

    # Set up the engine
    engine_config = load_engine_config()
    engine = init_engine(engine_config)

    # Set up the board
    board = pgn.board()
    for m in moves:
        board.push(m)

    # Process each move in the game in reverse order
    moves_processed = 0
    for played_move in reversed(moves):
        board.pop()
        moves_processed += 1
        color = 'w' if board.turn == chess.WHITE else 'b'
        # Skip already-processed moves
        try:
            with db_lock:
                move = Move.get(game=game_obj, color=color, number=board.fullmove_number)
            continue
        except DoesNotExist:
            pass
        progress_queue.put([game_number, gid, moves_processed, len(moves)])

        while True:
            try:
                # Run the engine for the top 5 moves
                info = engine.analyse(board, chess.engine.Limit(nodes=engine_config['nodes']), multipv=5, options=engine_config['options'])
                # Get the engine results
                pvs = {i+1: info['pv'][0] for (i, info) in enumerate(info)}
                evals = {i+1: score_to_cp(info['score']) for (i, info) in enumerate(info)}
                played_index = None
                for i, move in pvs.items():
                    if move == played_move:
                        played_index = i
                if not played_index:
                    # The played move was not in the top 5, so we need to analyze it separately
                    board.push(played_move)
                    if board.is_checkmate():
                        played_eval = 29999 if board.turn == chess.BLACK else -29999
                    else:
                        one_move_info = engine.analyse(board, chess.engine.Limit(nodes=engine_config['nodes']), multipv=1, options=engine_config['options'])
                        played_eval = -score_to_cp(one_move_info[0]['score'])
                    board.pop()
                else:
                    # The played move was in the top 5, so we can copy the corresponding eval to save time
                    played_eval = evals[played_index]

                # Store the evaluations in the DB
                with db_lock:
                    move = Move.create(game=game_obj, color=color, number=board.fullmove_number, \
                                    pv1_eval=evals.get(1), pv2_eval=evals.get(2), pv3_eval=evals.get(3), \
                                    pv4_eval=evals.get(4), pv5_eval=evals.get(5), \
                                    played_rank=played_index, played_eval=played_eval, \
                                    nodes=info[0].get('nodes'), masterdb_matches=masterdb_matches(board, move))
                break
            except TypeError:
                # If we get a bad engine output, score_to_cp will throw a TypeError. We can just retry
                continue

    with db_lock:
        game_obj.is_analyzed = True
        game_obj.save()
    engine.quit()
Ejemplo n.º 4
0
    def test_game_white_checkmate(self):
        with open(WHITE_CHECKMATE_PGN_PATH) as game_file:
            pgn = chess.pgn.read_game(game_file)
            game = Game()
            for move in pgn.mainline_moves():
                game.apply(move.uci())

                children = {}
                for idx in range(game.NUM_ACTIONS):
                    child = Node(None)
                    child.visit_count = 1 if idx == game.get_num_turn(
                    ) - 1 else 0
                    children[idx] = child
                root = Node(None)
                root.children = children
                game.store_search_statistics(root)

            # ========= CHECK ENDING ==============
            self.assertTrue(game.terminal())
            self.assertEqual(game.terminal_value(0), 1)
            self.assertEqual(game.terminal_value(1), -1)
            self.assertEqual(game.to_play(), int(not game.board.turn))

            # ========= CHECK TARGET ==============
            terminal_value, pi_t = game.make_target(0)
            self.assertEqual(terminal_value, 1)
            self.assertEqual(pi_t[0], 1)

            terminal_value, pi_t = game.make_target(5)
            self.assertEqual(terminal_value, -1)
            self.assertEqual(pi_t[5], 1)

            terminal_value, pi_t = game.make_target(23)
            self.assertEqual(terminal_value, -1)
            self.assertEqual(pi_t[23], 1)

            terminal_value, pi_t = game.make_target(44)
            self.assertEqual(terminal_value, 1)
            self.assertEqual(pi_t[44], 1)

            # ========= CHECK IMAGE ==============
            state_index = 5  # black to play
            planes = game.make_image(state_index)
            self.assertEqual(planes.shape, (119, 8, 8))

            # check current board positioning
            expected_num_pieces = [1, 1, 2, 2, 2, 8, 1, 1, 2, 2, 2, 8]
            self.assert_correct_num_pieces(planes[0:14, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 4)], [(7, 3)], [(7, 0), (7, 7)],
                                  [(7, 5), (7, 2)], [(5, 2), (7, 6)], None,
                                  [(0, 4)], [(0, 3)], [(0, 0), (0, 7)],
                                  [(3, 2), (0, 2)], [(0, 1), (2, 5)], None]
            self.assert_correct_pieces(planes[0:14, :, :], expected_positions)

            # check current board - 2 positioning
            expected_num_pieces = [1, 1, 2, 2, 2, 8, 1, 1, 2, 2, 2, 8]
            self.assert_correct_num_pieces(planes[28:42, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 4)], [(7, 3)], [(7, 0), (7, 7)],
                                  [(7, 5), (7, 2)], [(7, 1), (7, 6)], None,
                                  [(0, 4)], [(0, 3)], [(0, 0), (0, 7)],
                                  [(0, 5), (0, 2)], [(0, 1), (2, 5)], None]
            self.assert_correct_pieces(planes[28:42, :, :], expected_positions)

            # check last two boards are empty
            self.assertTrue((planes[84:112, :, :] == np.zeros(
                (28, 8, 8))).all())

            # check auxiliaries
            self.assertEqual(planes[112, :, :][0][0], 1)
            self.assertEqual(planes[113, :, :][0][0], 3)
            self.assertEqual(planes[114, :, :][0][0], 3)
            self.assertEqual(planes[115, :, :][0][0], 1)
            self.assertEqual(planes[116, :, :][0][0], 1)
            self.assertEqual(planes[117, :, :][0][0], 1)
            self.assertEqual(planes[118, :, :][0][0], 1)

            state_index = 44  # white to play
            planes = game.make_image(state_index)
            self.assertEqual(planes.shape, (119, 8, 8))

            # check current board positioning
            expected_num_pieces = [1, 0, 1, 2, 0, 6, 1, 1, 2, 2, 1, 4]
            self.assert_correct_num_pieces(planes[0:14, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 6)], None, [(7, 3)],
                                  [(5, 0), (3, 5)], None, None, [(0, 4)],
                                  [(5, 5)], [(0, 1), (0, 6)], [(1, 1), (2, 1)],
                                  [(1, 4)], None]
            self.assert_correct_pieces(planes[0:14, :, :], expected_positions)

            # check current board - 2 positioning
            expected_num_pieces = [1, 0, 1, 2, 0, 6, 1, 1, 2, 2, 1, 4]
            self.assert_correct_num_pieces(planes[28:42, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 6)], None, [(7, 3)],
                                  [(5, 0), (5, 3)], None, None, [(1, 3)],
                                  [(5, 5)], [(0, 1), (0, 6)], [(1, 1), (2, 1)],
                                  [(1, 4)], None]
            self.assert_correct_pieces(planes[28:42, :, :], expected_positions)

            # check auxiliaries
            self.assertEqual(planes[112, :, :][0][0], 0)
            self.assertEqual(planes[113, :, :][0][0], 23)
            self.assertEqual(planes[114, :, :][0][0], 2)
            self.assertEqual(planes[115, :, :][0][0], 0)
            self.assertEqual(planes[116, :, :][0][0], 0)
            self.assertEqual(planes[117, :, :][0][0], 0)
            self.assertEqual(planes[118, :, :][0][0], 0)
Ejemplo n.º 5
0
    def test_game_draw_threefold(self):
        with open(DRAW_THREE_FOLD_PGN_PATH) as game_file:
            pgn = chess.pgn.read_game(game_file)
            game = Game()
            for move in pgn.mainline_moves():
                game.apply(move.uci())

                children = {}
                for idx in range(game.NUM_ACTIONS):
                    child = Node(None)
                    child.visit_count = 1 if idx == game.get_num_turn(
                    ) - 1 else 0
                    children[idx] = child
                root = Node(None)
                root.children = children
                game.store_search_statistics(root)

            self.assertTrue(game.terminal())
            self.assertEqual(game.terminal_value(0), 0)
            self.assertEqual(game.terminal_value(1), 0)
            self.assertEqual(game.to_play(), int(not game.board.turn))

            # ========= CHECK TARGET ==============
            terminal_value, pi_t = game.make_target(0)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[0], 1)

            terminal_value, pi_t = game.make_target(10)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[10], 1)

            terminal_value, pi_t = game.make_target(11)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[11], 1)

            terminal_value, pi_t = game.make_target(12)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[12], 1)

            # ========= CHECK IMAGE ==============
            state_index = 67  # black to play
            planes = game.make_image(state_index)
            self.assertEqual(planes.shape, (119, 8, 8))

            # check current board positioning
            expected_num_pieces = [1, 1, 1, 0, 0, 5, 1, 1, 1, 0, 0, 5]
            self.assert_correct_num_pieces(planes[0:14, :, :],
                                           expected_num_pieces)

            expected_positions = [[(6, 7)], [(5, 5)], [(4, 3)], None, None,
                                  None, [(0, 7)], [(1, 4)], [(3, 5)], None,
                                  None, None]
            self.assert_correct_pieces(planes[0:14, :, :], expected_positions)
            self.assertEqual(planes[12, :, :][0][0], 1)  # board repeated once
            self.assertEqual(planes[13, :, :][0][0], 1)  # board repeated twice

            # # check current board - 2 positioning
            expected_num_pieces = [1, 1, 1, 0, 0, 5, 1, 1, 1, 0, 0, 5]
            self.assert_correct_num_pieces(planes[28:42, :, :],
                                           expected_num_pieces)

            expected_positions = [[(6, 7)], [(5, 5)], [(4, 4)], None, None,
                                  None, [(0, 7)], [(2, 3)], [(3, 5)], None,
                                  None, None]
            self.assert_correct_pieces(planes[28:42, :, :], expected_positions)

            # check auxiliaries
            self.assertEqual(planes[112, :, :][0][0], 1)
            self.assertEqual(planes[113, :, :][0][0], 34)
            self.assertEqual(planes[114, :, :][0][0], 10)
            self.assertEqual(planes[115, :, :][0][0], 0)
            self.assertEqual(planes[116, :, :][0][0], 0)
            self.assertEqual(planes[117, :, :][0][0], 0)
            self.assertEqual(planes[118, :, :][0][0], 0)

            state_index = 4  # white to play
            planes = game.make_image(state_index)
            self.assertEqual(planes.shape, (119, 8, 8))

            # check current board positioning
            expected_num_pieces = [1, 1, 2, 2, 2, 8, 1, 1, 2, 2, 2, 8]
            self.assert_correct_num_pieces(planes[0:14, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 4)], [(7, 3)], [(7, 0), (7, 7)],
                                  [(7, 5), (7, 2)], [(7, 1), (7, 6)],
                                  [(6, 0), (6, 1), (6, 2), (4, 3), (4, 4),
                                   (6, 5), (6, 6), (6, 7)], [(0, 4)], [(0, 3)],
                                  [(0, 0), (0, 7)], [(0, 2), (0, 5)],
                                  [(0, 1), (0, 6)],
                                  [(1, 0), (1, 1), (1, 2), (3, 3), (2, 4),
                                   (1, 5), (1, 6), (1, 7)]]
            self.assert_correct_pieces(planes[0:14, :, :], expected_positions)

            expected_num_pieces = [1, 1, 2, 2, 2, 8, 1, 1, 2, 2, 2, 8]
            self.assert_correct_num_pieces(planes[28:42, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 4)], [(7, 3)], [(7, 0), (7, 7)],
                                  [(7, 5), (7, 2)], [(7, 1), (7, 6)],
                                  [(6, 0), (6, 1), (6, 2), (6, 3), (4, 4),
                                   (6, 5), (6, 6), (6, 7)], [(0, 4)], [(0, 3)],
                                  [(0, 0), (0, 7)], [(0, 2), (0, 5)],
                                  [(0, 1), (0, 6)],
                                  [(1, 0), (1, 1), (1, 2), (1, 3), (2, 4),
                                   (1, 5), (1, 6), (1, 7)]]
            self.assert_correct_pieces(planes[28:42, :, :], expected_positions)

            # check last two boards are empty
            self.assertTrue((planes[84:112, :, :] == np.zeros(
                (28, 8, 8))).all())

            # check auxiliaries
            self.assertEqual(planes[112, :, :][0][0], 0)
            self.assertEqual(planes[113, :, :][0][0], 3)
            self.assertEqual(planes[114, :, :][0][0], 0)
            self.assertEqual(planes[115, :, :][0][0], 1)
            self.assertEqual(planes[116, :, :][0][0], 1)
            self.assertEqual(planes[117, :, :][0][0], 1)
            self.assertEqual(planes[118, :, :][0][0], 1)
Ejemplo n.º 6
0
    def test_game_draw_stalemate(self):
        with open(DRAW_STALEMATE_PGN_PATH) as game_file:
            pgn = chess.pgn.read_game(game_file)
            game = Game()
            for move in pgn.mainline_moves():
                game.apply(move.uci())

                children = {}
                for idx in range(game.NUM_ACTIONS):
                    child = Node(None)
                    child.visit_count = 1 if idx == game.get_num_turn(
                    ) - 1 else 0
                    children[idx] = child
                root = Node(None)
                root.children = children
                game.store_search_statistics(root)

            self.assertTrue(game.terminal())
            self.assertEqual(game.terminal_value(0), 0)
            self.assertEqual(game.terminal_value(1), 0)
            self.assertEqual(game.to_play(), int(not game.board.turn))

            # ========= CHECK TARGET ==============
            terminal_value, pi_t = game.make_target(0)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[0], 1)

            terminal_value, pi_t = game.make_target(9)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[9], 1)

            terminal_value, pi_t = game.make_target(21)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[21], 1)

            terminal_value, pi_t = game.make_target(36)
            self.assertEqual(terminal_value, 0)
            self.assertEqual(pi_t[36], 1)

            # ========= CHECK IMAGE ==============
            state_index = 106  # white to play
            planes = game.make_image(state_index)
            self.assertEqual(len(game.legal_actions()), 0)
            self.assertEqual(planes.shape, (119, 8, 8))

            # check current board positioning
            expected_num_pieces = [1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 2]
            self.assert_correct_num_pieces(planes[0:14, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 7)], None, None, None, None, [(6, 7)],
                                  [(0, 6)], None, None, [(1, 0)], None,
                                  [(4, 5), (5, 7)]]
            self.assert_correct_pieces(planes[0:14, :, :], expected_positions)

            # check current board - 2 positioning
            expected_num_pieces = [1, 0, 0, 0, 0, 2, 1, 0, 0, 1, 0, 2]
            self.assert_correct_num_pieces(planes[28:42, :, :],
                                           expected_num_pieces)

            expected_positions = [[(7, 7)], None, None, None, None,
                                  [(2, 0), (6, 7)], [(0, 6)], None, None,
                                  [(0, 1)], None, [(4, 5), (5, 7)]]
            self.assert_correct_pieces(planes[28:42, :, :], expected_positions)

            # check auxiliaries
            self.assertEqual(planes[112, :, :][0][0], 0)
            self.assertEqual(planes[113, :, :][0][0], 54)
            self.assertEqual(planes[114, :, :][0][0], 0)
            self.assertEqual(planes[115, :, :][0][0], 0)
            self.assertEqual(planes[116, :, :][0][0], 0)
            self.assertEqual(planes[117, :, :][0][0], 0)
            self.assertEqual(planes[118, :, :][0][0], 0)

            state_index = 75  # black to play
            planes = game.make_image(state_index)
            self.assertEqual(planes.shape, (119, 8, 8))

            # check current board positioning
            expected_num_pieces = [1, 0, 2, 1, 0, 2, 1, 1, 0, 1, 0, 4]
            self.assert_correct_num_pieces(planes[0:14, :, :],
                                           expected_num_pieces)

            expected_positions = [[(5, 6)], None, [(4, 2), (7, 2)],
                                  [(3, 3)], None, [(2, 7), (5, 5)], [(0, 6)],
                                  [(0, 1)], None, [(4, 5)], None,
                                  [(3, 0), (1, 5), (2, 6), (1, 7)]]
            self.assert_correct_pieces(planes[0:14, :, :], expected_positions)

            # check current board - 2 positioning
            expected_num_pieces = [1, 0, 2, 1, 0, 3, 1, 1, 0, 1, 0, 4]
            self.assert_correct_num_pieces(planes[28:42, :, :],
                                           expected_num_pieces)

            expected_positions = [[(5, 6)], None, [(4, 2), (7, 7)], [(3, 3)],
                                  None, [(2, 7), (4, 5), (5, 5)], [(0, 6)],
                                  [(0, 1)], None, [(1, 2)], None,
                                  [(3, 0), (1, 5), (2, 6), (1, 7)]]
            self.assert_correct_pieces(planes[28:42, :, :], expected_positions)

            # check auxiliaries
            self.assertEqual(planes[112, :, :][0][0], 1)
            self.assertEqual(planes[113, :, :][0][0], 38)
            self.assertEqual(planes[114, :, :][0][0], 0)
            self.assertEqual(planes[115, :, :][0][0], 0)
            self.assertEqual(planes[116, :, :][0][0], 0)
            self.assertEqual(planes[117, :, :][0][0], 0)
            self.assertEqual(planes[118, :, :][0][0], 0)