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
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
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
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()
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()