示例#1
0
def prepare_chess_data(filename):
    mate_in_1_positions = []
    mate_in_1_solutions = []
    engine = chess.engine.SimpleEngine.popen_uci("chess_data/stockfish_20011801_x64.exe")
    pgn = open(filename)
    game = chess.pgn.read_game(pgn)
    game_number = 1
    while game is not None:
    #for i in range(10):
        board = game.board()
        info = engine.analyse(board, chess.engine.Limit(depth=25, time=50), info=ce.INFO_ALL)
        if info['score'] != ce.PovScore(ce.Mate(2), chess.WHITE):
            print(game)
            game = chess.pgn.read_game(pgn)
            continue
        first_move = info['pv'][0]
        board.push(first_move)
        for opponent_move in board.legal_moves:
            board.push(opponent_move)
            info2 = engine.analyse(board, chess.engine.Limit(depth=25, time=50), info=ce.INFO_ALL)
            if info2['score'] == ce.PovScore(ce.Mate(1), chess.WHITE):
                mate_in_1_positions.append(board.fen())
                board.push(info2['pv'][0])
                mate_in_1_solutions.append(board.fen())
                board.pop()
            board.pop()
        if game_number%100==0:
            print("{}. games processed. {} puzzles obtained so far!".format(game_number,len(mate_in_1_positions)))
        try:
            game = chess.pgn.read_game(pgn)
        except UnicodeDecodeError:
            print(game_number+1)
        game_number = game_number + 1
    engine.quit()
    return mate_in_1_positions, mate_in_1_solutions
示例#2
0
def get_solutions(board, engine):
    # Solution Search
    solutions = []
    infos = engine.analyse(board, chess.engine.Limit(depth=5, time=20), info=ce.INFO_ALL, multipv=5)
    for info in infos:
        if info['score'] == ce.PovScore(ce.Mate(1), chess.WHITE):
            move = info['pv'][0]
            solutions.append((move.from_square,move.to_square))
    return solutions
示例#3
0
def create_one_move_solutions(fen_file):
    engine = chess.engine.SimpleEngine.popen_uci("chess_data/stockfish_20011801_x64.exe")
    with open(fen_file, 'rb') as fp:
        problem_set = pickle.load(fp)
    n = 1
    encoded_ambiguous_problems = []
    encoded_ambiguous_solutions = []

    encoded_single_solution_problems = []
    encoded_single_solution_solutions = []
    
    solution_number_dict = {1:0,2:0}
    for problem in problem_set:
        board = chess.Board(problem)

        # Problem Encoding
        nn_pos = np.zeros((64,1), dtype=int)
        for sq_num in range(64):
            piece = board.piece_map().get(sq_num)
            if piece is not None:
                nn_pos[sq_num][0] = PIECE_TO_NUM_MAP[(piece.color,piece.piece_type)]
        nn_pos = np.reshape(nn_pos, (8,8))

        # Solution Search
        info = engine.analyse(board, chess.engine.Limit(depth=5, time=20), info=ce.INFO_ALL, multipv=2)
        first_move = info[0]['pv'][0]
        #print(board)
        #for move in info:
        #    print(move)
        # Solution Encoding
        nn_sol = np.zeros((64, 1), dtype=int)
        nn_sol[first_move.from_square] = FROM_SQUARE
        nn_sol[first_move.to_square] = TO_SQUARE
        nn_sol = np.reshape(nn_sol, (8, 8))

        # now - determine if the second solution is also Mate in 1 !!
        if len(info)>1 and info[1]['score']==ce.PovScore(ce.Mate(1), chess.WHITE):
            encoded_ambiguous_problems.append(nn_pos)
            encoded_ambiguous_solutions.append(nn_sol)
            sol_count = 2
            for sol in info[2:]:
                if sol['score'] == ce.PovScore(ce.Mate(1), chess.WHITE):
                    sol_count = sol_count + 1
                else:
                    break
            solution_number_dict[sol_count] = solution_number_dict[sol_count] + 1
            #print("More than one solution!")
        else:
            if len(info)==1:
                print(board)
            encoded_single_solution_problems.append(nn_pos)
            encoded_single_solution_solutions.append(nn_sol)
            solution_number_dict[1] = solution_number_dict[1] + 1
            #print("One solution!")

        if n%1000==0:
            print("{} positions encoded".format(n))
            for k, v in solution_number_dict.items():
                print("{}:{}".format(k,v))
        n = n + 1
    print("ambigous: {} / single: {}".format(len(encoded_ambiguous_problems),len(encoded_single_solution_problems)))
    engine.quit()
    return encoded_single_solution_problems, encoded_single_solution_solutions, encoded_ambiguous_problems, encoded_ambiguous_solutions
示例#4
0
def evaluate_chess_data(filename):

    with open(file) as f:
        positions = f.read().splitlines()

    with open(evaluation_file, 'w') as f:
        for position in positions:
            evaluation = 0
            board = chess.Board(position)
            board = remove_extra_pieces(board)
            f.write(board.fen())
            f.write('\n')
            print(board)

            white_material = board_material_evaluation(board, chess.WHITE)
            black_material = board_material_evaluation(board, chess.BLACK)

            board_material = (black_material - white_material * 100) / 45.2
            evaluation += board_material
            f.write("board material: " + str(board_material))
            f.write('\n')
            info = engine.analyse(board,
                                  chess.engine.Limit(time=0.5),
                                  info=ce.INFO_ALL,
                                  multipv=2)
            time.sleep(0.5)
            if info[0]['score'] == ce.PovScore(ce.Mate(2), chess.WHITE):
                first_move = info[0]['pv'][0]
                second_move = info[0]['pv'][1]
                third_move = info[0]['pv'][2]
                from_square = first_move.from_square
                moved_piece = board.piece_at(from_square)

                moved_piece_eval = evaluate_moved_piece(board, from_square)
                evaluation += moved_piece_eval

                f.write("evaluate moved piece: " + str(moved_piece_eval))
                f.write('\n')

                # print("info pv: ", info[0]['pv'])

                board.push(first_move)

                pinned_pieces = evaluate_pinned_pieces(board)
                double_attack = evaluate_double_attack(board)

                f.write("pinned pieces: " + str(pinned_pieces))
                f.write('\n')
                f.write("double attack: " + str(double_attack))
                f.write('\n')

                evaluation += pinned_pieces
                evaluation += double_attack

                board.push(second_move)

                from_square2 = third_move.from_square
                moved_piece_eval2 = evaluate_moved_piece(board, from_square2)
                evaluation += moved_piece_eval2

                board.push(third_move)

                f.write("evaluate moved piece2: " + str(moved_piece_eval2))
                f.write('\n')

                white_material2 = board_material_evaluation(board, chess.WHITE)

                if white_material > white_material2:
                    f.write("white sacrifice material: 20")
                    f.write('\n')
                    evaluation += 20

                print(evaluation)
            if len(info) > 1:
                if info[1]['score'] == ce.PovScore(ce.Mate(2), chess.WHITE):
                    evaluation -= 10
                    # f.write("extra mate: -10")
                    # f.write('\n')
                    print("another Mate in 2 found")

            f.write('total: ' + str(evaluation))
            f.write('\n')

    engine.quit()
示例#5
0
def remove_extra_pieces(board):
    print(board)
    curr_board = board
    result = board
    info = engine.analyse(curr_board,
                          chess.engine.Limit(time=0.5),
                          info=ce.INFO_ALL,
                          multipv=2)
    time.sleep(0.5)
    move_list = info[0]['pv']
    squares = chess.SquareSet(chess.BB_ALL)
    squares.discard(curr_board.king(chess.WHITE))
    squares.discard(curr_board.king(chess.BLACK))
    for move in move_list:
        squares.discard(move.from_square)
        squares.discard(move.to_square)

    try:
        for square in squares:
            removed_piece = curr_board.remove_piece_at(square)
            if removed_piece is None:
                continue

            info = engine.analyse(curr_board,
                                  chess.engine.Limit(0.5),
                                  info=ce.INFO_ALL,
                                  multipv=2)
            time.sleep(0.5)

            if move_list != info[0]['pv']:
                if removed_piece.piece_type != chess.PAWN:
                    curr_board.set_piece_at(square=square, piece=removed_piece)
                    result = curr_board
                    continue
                if curr_board.piece_at(square + 8).piece_type == chess.PAWN:
                    extra_removed_piece = curr_board.remove_piece_at(square +
                                                                     8)
                    info2 = engine.analyse(curr_board,
                                           chess.engine.Limit(time=0.5),
                                           info=ce.INFO_ALL,
                                           multipv=2)
                    time.sleep(0.5)
                    if move_list != info2[0]['pv']:
                        curr_board.set_piece_at(square=square,
                                                piece=extra_removed_piece)
                        result = curr_board
                        continue
                    if len(info2) > 1:
                        if info2[1]['score'] == ce.PovScore(
                                ce.Mate(2), chess.WHITE):
                            curr_board.set_piece_at(square=square,
                                                    piece=removed_piece)
                            result = curr_board
                            continue
            if len(info) > 1:
                if info[1]['score'] == ce.PovScore(ce.Mate(2), chess.WHITE):
                    if removed_piece.piece_type != chess.PAWN:
                        curr_board.set_piece_at(square=square,
                                                piece=removed_piece)
                        result = curr_board
                        continue
                    if curr_board.piece_at(square +
                                           8).piece_type == chess.PAWN:
                        extra_removed_piece = curr_board.remove_piece_at(
                            square + 8)
                        info2 = engine.analyse(curr_board,
                                               chess.engine.Limit(time=0.5),
                                               info=ce.INFO_ALL,
                                               multipv=2)
                        time.sleep(0.5)
                        if move_list != info2[0]['pv']:
                            curr_board.set_piece_at(square=square,
                                                    piece=extra_removed_piece)
                            result = curr_board
                            continue
                        if len(info) > 1:
                            if info2[1]['score'] == ce.PovScore(
                                    ce.Mate(2), chess.WHITE):
                                curr_board.set_piece_at(square=square,
                                                        piece=removed_piece)
                                result = curr_board
                                continue
        return result
    except:
        print("failed to remove pieces from the board")
    finally:
        print("returning back the original board")
        return board
pgn = open(file)
game = chess.pgn.read_game(pgn)
game_number = 1
with open('chess_data/generated_positions_2.pgn', 'w') as f:
    while game is not None:
        board = game.board()
        calculation_start = int(game.headers["PlyCount"]) - 6
        move_counter = 1
        for move in game.mainline_moves():
            board.push(move)
            if move_counter >= calculation_start:
                print("analyzing..")
                info = engine.analyse(board,
                                      chess.engine.Limit(time=1),
                                      info=ce.INFO_ALL)
                time.sleep(1)
                if info['score'] == ce.PovScore(ce.Mate(2), chess.WHITE):
                    f.write(board.fen())
                    f.write('\n')
                    print(board.fen())
                    break
            move_counter += 1
        print("next game...")
        game = chess.pgn.read_game(pgn)
        game_number += 1
        if game_number % 10 == 0:
            print("went through ", game_number, " games")

engine.quit()