Beispiel #1
0
    def start(self, choise):
        try:
            self.model = load_model(
                os.path.join(self.config.resources.best_model_dir,
                             "best_model.h5"))
            self.value_model = load_model(
                os.path.join(self.config.resources.best_model_dir, "value.h5"))
            logger.info("Load best model successfully.")
        except OSError:
            logger.fatal("Model cannot find!")
            return

        self.board = chess.Board()
        self.choise = choise
        all_moves = get_all_possible_moves()
        self.move_hash = {move: i for (i, move) in enumerate(all_moves)}

        with open(self.config.playing.oppo_move_dir, "w") as f:
            f.write('')
        with open(self.config.playing.ai_move_dir, "w") as f:
            f.write('')

        pre_oppo_move = None
        if choise == 1:
            self.board = chess.Board(first_person_view_fen(
                self.board.fen(), 1))  #先让黑棋走
            print(self.board)
            while True:

                while True:
                    #ai move
                    with open(self.config.playing.oppo_move_dir, "r") as f:
                        opponent_move = f.read()
                    if opponent_move == pre_oppo_move or not opponent_move:
                        time.sleep(0.1)
                    else:
                        pre_oppo_move = opponent_move
                        break
                try:
                    convert_move = convert_black_uci(opponent_move)
                    convert_move = self.board.parse_san(convert_move).uci()
                    convert_move = self.board.parse_uci(convert_move)
                    break
                except ValueError:
                    logger.info("Opponent make a illegal move")
            logger.info("Your move: %s" % opponent_move)
            self.board.push(convert_move)  # other move.  update board

        while not self.board.is_game_over():
            start = time.time()
            my_move = self.play()  #get ai move
            end = time.time()

            with open(self.config.playing.ai_move_dir, "w") as f:
                if choise == 0:
                    f.write(my_move.uci())
                else:
                    out = self.board.san(my_move)
                    out = convert_black_uci(out)
                    f.write(out)
            self.used_time += end - start
            print("time: %.2f" % (end - start))
            #my_move = convert_black_uci(my_move)
            self.board.push(my_move)  # ai move. update board
            if choise == 1:
                logger.info("AI move: %s" % convert_black_uci(my_move.uci()))
            else:
                logger.info("AI move: %s" % my_move.uci())

            print(self.board)
            while True:
                while True:
                    #ai move
                    with open(self.config.playing.oppo_move_dir, "r") as f:
                        opponent_move = f.read()
                    if opponent_move == pre_oppo_move or not opponent_move:
                        time.sleep(0.1)
                    else:
                        pre_oppo_move = opponent_move
                        break

                if opponent_move == "undo":  #undo
                    self.board.pop()
                    self.board.pop()
                    logger.info("Undo done.")
                    self.moves_cnt -= 1
                    continue
                try:
                    if choise == 1:
                        convert_move = convert_black_uci(opponent_move)
                        convert_move = self.board.parse_san(convert_move).uci()
                    else:
                        convert_move = self.board.parse_san(
                            opponent_move).uci()
                    convert_move = self.board.parse_uci(convert_move)
                    break
                except ValueError:
                    logger.info("Opponent make a illegal move")
            logger.info("Your move: %s" % opponent_move)

            self.board.push(convert_move)  # other move.  update board
Beispiel #2
0
def main():
    pygame.init()

    screen = pygame.display.set_mode((848, 848))
    pygame.display.set_caption("Chess")
    #Size of squares
    size = 106

    white  = (255, 255, 255)
    black = (161, 96, 43)

    board = chess.Board()
    board_squares = chess.SquareSet()
    squares = []
    # method for drawing chess board obtained from stack overflow, link lost somewhere in history
    count = 0
    # this fen has no slashes, you must remove slashes for any fen to work, you also must remove the ending material that says "3 - 0" or something
    startingFen = 'rnbkqbnrpppppppp8888PPPPPPPPRNBKQBNR'
    fenCount = len(startingFen)- 1
    for i in range(8):
        for j in range(8):
            if count % 2 == 0:
                # rectangle = pygame.rect.Rect(size*j,size*i,size,size)
                rectangle = pygame.draw.rect(screen, white, (size*j,size*i,size,size))
                if startingFen[fenCount].isdigit() and int(startingFen[fenCount]) > 0:
                    squares.append(Squares.Squares(chr((j + 97)) + str(int(8 - i)), "", rectangle, False))
                    f = str(int(startingFen[fenCount]) - 1)
                    startingFen = startingFen[:fenCount] + f + startingFen[fenCount + 1:]
                    if int(startingFen[fenCount]) == 0:
                        fenCount -= 1
                else:
                    squares.append(Squares.Squares(chr((j + 97)) + str(int(8 - i)), startingFen[fenCount], rectangle, False))
                    pieceImg = squares[len(squares) - 1].image
                    screen.blit(pieceImg, (size*j, size*i))
                    fenCount -= 1
            else:
                rectangle = pygame.draw.rect(screen, white, (size*j,size*i,size,size))
                # rectangle = pygame.rect.Rect(size*j,size*i,size,size)
                if startingFen[fenCount].isdigit() and int(startingFen[fenCount]) > 0:
                    squares.append(Squares.Squares(chr((j + 97)) + str(int(8 - i)), "", rectangle, False))
                    f = str(int(startingFen[fenCount]) - 1)
                    startingFen = startingFen[:fenCount] + f + startingFen[fenCount + 1:]
                    if int(startingFen[fenCount]) == 0:
                        fenCount -= 1
                else:
                    squares.append(Squares.Squares(chr((j + 97)) + str(int(8 - i)), startingFen[fenCount], rectangle, False))
                    pieceImg = squares[len(squares) - 1].image
                    screen.blit(pieceImg, (size*j, size*i))
                    fenCount -= 1
            count +=1
        count-=1

    movedThing = None
    x, y = 0, 0
    while True:
        screen = drawBoard(screen, squares)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    for i in squares:
                        if i.rectangle.collidepoint(event.pos) and i.image != None:
                            i.dragging = True
                            mouse_x, mouse_y = event.pos
                            offset_x = i.posx - mouse_x
                            offset_y = i.posy - mouse_y
                            x, y = event.pos[0], event.pos[1]


            elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                for i in range(len(squares)):
                    if squares[i].dragging:
                        squares[i].dragging = False
                        print(event.pos)
                        for x in range(len(squares)):
                            if squares[x].rectangle.collidepoint(event.pos) and squares[x] != squares[i]:

                                # We use a try except because it will raise ValueError on illegal move or on Game Over
                                try:

                                    print(squares[i].pos + squares[x].pos)

                                    playHumanMove(board, squares, i, x)

                                    playAIMove(board, squares)

                                except (ValueError, TypeError, NameError) as e:
                                    if board.is_game_over() or board.is_stalemate():
                                        print("Game Over!")
                                    else:
                                        print("Invalid Move. \n{0}".format(e))

            elif event.type == pygame.MOUSEMOTION:
                for i in squares:
                    if i.image == None:
                        continue
                    if i.dragging:
                        mouse_x, mouse_y = event.pos
                        x = mouse_x + offset_x
                        y = mouse_y + offset_y
                        screen.blit(i.image, (x, y))

        # place the piece that is currently being moved.
        for i in squares:
            if i.dragging:
                screen.blit(i.image, (x, y))
        # loop through squares and place each piece accordingly each update.
        pygame.display.update()
Beispiel #3
0
def play(args):
    def recommend_move():
        """
        Recommend move using by looking up polyglot opening book. If not in book then use stockfish engine.
        """
        try:
            with polyglot.open_reader(
                    "./data/polyglot/performance.bin") as reader:
                main_entry = reader.find(board)
            recom_move = main_entry.move()
        except IndexError:
            engine = uci.popen_engine("./Stockfish/src/stockfish")
            engine.uci()
            engine.position(board)
            # Gets tuple of bestmove and ponder move.
            best_move = engine.go(movetime=ENGINE_MOVETIME)
            recom_move = best_move[0]
            engine.quit()
        return recom_move

    def display_image_window(name, img, x, y):
        cv2.namedWindow(name, cv2.WINDOW_NORMAL)
        cv2.imshow(name, img)
        cv2.resizeWindow(name, UI_WINDOW_WIDTH, UI_WINDOW_HEIGHT)
        cv2.moveWindow(name, int(x), int(y))
        return True

    # initialise chessbaord
    board = chess.Board()

    test_img_index = 1
    prev_board_img = None
    recom_move = None

    while True:
        print(board, board.fen())
        sq_pc = get_piece_colours(None, board=board, meth='board')

        # get image
        if args.camera == -1:
            img = cv2.imread('./images/gen_{0}.jpg'.format(test_img_index))
            test_img_index += 1
        else:
            img = get_single_image()

        # crop image to board
        curr_board_img = project_board(img, corners)
        if prev_board_img is None:
            prev_board_img = curr_board_img

        # detect move
        curr_sq_pc = get_piece_colours(curr_board_img)
        curr_move = detect_move(sq_pc, curr_sq_pc, board=board)
        curr_move2 = detect_move(curr_board_img,
                                 prev_board_img,
                                 meth='image diff',
                                 board=board)
        print(sq_pc, 'prev')
        print(curr_sq_pc, 'curr')
        print(format_squares_piece_text(curr_sq_pc))
        print(curr_move, curr_move2)

        if curr_move is None:
            pass
        else:
            board_move = chess.Move(curr_move[0], curr_move[1])
            if board_move in board.legal_moves:
                board.push(board_move)
                recom_move = recommend_move()
                stat_img = message_img(board, board_move.uci(), recom_move)
            else:
                raise Exception('illegal move')

        # display UI
        display_image_window(
            'Current Board',
            label_squares(curr_board_img, recom_move=recom_move),
            0 * UI_WINDOW_WIDTH, 0 * UI_WINDOW_HEIGHT)
        try:
            display_image_window('Status', stat_img, 1 * UI_WINDOW_WIDTH,
                                 0 * UI_WINDOW_HEIGHT)
        except:
            pass
        display_image_window('Raw Feed', img, 2 * UI_WINDOW_WIDTH,
                             0 * UI_WINDOW_HEIGHT)
        #display_image_window('Diff Board', cv2.cvtColor(curr_board_img, cv2.COLOR_BGR2GRAY) - cv2.cvtColor(prev_board_img, cv2.COLOR_BGR2GRAY), 3 * UI_WINDOW_WIDTH, 0 * UI_WINDOW_HEIGHT)

        prev_board_img = curr_board_img
        recom_move = None
        cv2.waitKey(0)

    cv2.destroyAllWindows()
 def __init__(self,board=None):
     if board is None: 
         self.board = chess.Board()
     else:
         self.board = board
Beispiel #5
0
def evaluate(board, depth=0):
    sequence, evaluation = internal_evaluate(board, 2 * depth)

    print(board.variation_san(sequence))

    internal_board = board.copy()

    for m in sequence:
        internal_board.push(m)

    print(internal_board.result() if internal_board.is_game_over() else evaluation)

if __name__ == "__main__":
    # Initialise structures
    board = chess.Board()

    # Push some moves
    board.push_san("e4")
    board.push_san("e5")
    board.push_san("Bc4")
    board.push_san("a6")
    board.push_san("Qh5")
    board.push_san("Nf6")
    #board.push_san("Qf7")

    # Initialise board
    # board.set_board_fen("r5rk/5p1p/5R2/4B3/8/8/7P/7K w")

    print(board.board_fen())
Beispiel #6
0
def page(screen, users):

    # ---- init -----
    check = init_check(screen)

    # ---- chess -----
    chess_board = chess.Board()

    # ----- table -----
    table_size = size.Size(300, 300, width=480, height=480)
    table = board.Board(screen, table_size, 'w', 60, chess_board)

    # ----- DataTable -----
    data_table_size = size.Size(1000, 300, width=350, height=500)
    data_table = datas.DataTable(screen, (100, 50), data_table_size)

    # ----- "Quit" button -----
    quit_button_size = size.Size(600, 270, width=250, height=50)
    quit_button = button.Button(screen, quit_button_size, 'QUIT')

    # ----- "Rematch" button -----
    rematch_button_size = size.Size(600, 350, width=250, height=50)
    rematch_button = button.Button(screen, rematch_button_size, 'REMATCH')

    # ----- menu -----
    my_menu = menu.Menu(screen, [quit_button, rematch_button])

    # ----- Main loop -----
    while True:
        screen.fill(colors.white)

        # ---- Events ----
        table.dict_to_list(table.generate_fen())

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if my_menu.enabled:  # if the menu is enabled
                if my_menu.onTap_close_button(event):  # close button
                    my_menu.enabled = False

                if my_menu.onTap_button(event, 0):  # QUIT button
                    pygame.quit()
                    sys.exit()

                if my_menu.onTap_button(event, 1):  # REAMTCH button
                    second_page.page(screen, users)

            if not my_menu.enabled:  # if the menu is NOT enabled
                if data_table.menu_button_tapped(event):
                    my_menu.enabled = True
                if data_table.undo_button_tapped(event):
                    try:
                        chess_board.pop()
                    except:
                        pass

                if event.type == pygame.MOUSEBUTTONUP:
                    table.tap_move(event.pos)
                    table.onTap_pieces(event.pos)

        # ---- Draw ----
        table.draw()
        data_table.draw()
        table.draw_pieces()
        table.draw_legal_moves()
        if chess_board.is_check():
            draw_check(screen, check)

        if chess_board.is_checkmate():
            if chess_board.turn:
                black_win.page(screen, users)
            else:
                white_win.page(screen, users)

        if my_menu.enabled:  # if menu is enabled
            my_menu.draw(event)

        # ---- Updates ----
        pygame.display.update()
        pygame.time.Clock().tick(60)
Beispiel #7
0
class EvalTuner():
    # chess board instance
    board = chess.Board()
    
    # capture ordering
    mvv_lva = [
        0,   0,   0,   0,   0,   0,   0,  0,   0,   0,   0,   0,   0,
        0, 105, 205, 305, 405, 505, 605,  105, 205, 305, 405, 505, 605,
        0, 104, 204, 304, 404, 504, 604,  104, 204, 304, 404, 504, 604,
        0, 103, 203, 303, 403, 503, 603,  103, 203, 303, 403, 503, 603,
        0, 102, 202, 302, 402, 502, 602,  102, 202, 302, 402, 502, 602,
        0, 101, 201, 301, 401, 501, 601,  101, 201, 301, 401, 501, 601,
        0, 100, 200, 300, 400, 500, 600,  100, 200, 300, 400, 500, 600,

        0, 105, 205, 305, 405, 505, 605,  105, 205, 305, 405, 505, 605,
        0, 104, 204, 304, 404, 504, 604,  104, 204, 304, 404, 504, 604,
        0, 103, 203, 303, 403, 503, 603,  103, 203, 303, 403, 503, 603,
        0, 102, 202, 302, 402, 502, 602,  102, 202, 302, 402, 502, 602,
        0, 101, 201, 301, 401, 501, 601,  101, 201, 301, 401, 501, 601,
        0, 100, 200, 300, 400, 500, 600,  100, 200, 300, 400, 500, 600
    ];
    
    # game result mapping
    result = {
        '1-0': '1.0',
        '1/2-1/2': '0.5',
        '0-1': '0.0'
    }
    
    # init
    def __init__(self):
        with open('initial_weights.json') as f:
            self.eval_params = json.loads(f.read())
            self.map_params()
    
    # map evaluation parameters to handy shortcuts
    def map_params(self):
        # map game phases
        self.opening = self.eval_params['opening']
        self.middlegame = self.eval_params['middlegame']
        self.endgame = self.eval_params['endgame']
        
        # map game phase score margins
        self.opening_phase = self.eval_params['weights'][0][0]
        self.endgame_phase = self.eval_params['weights'][1][0]
        
        # map material weights
        self.material_weights = [
            self.eval_params['weights'][0][0:13],
            self.eval_params['weights'][1][0:13]
        ]
        
        # map piece square tables
        self.pst = [
            [
                self.eval_params['weights'][0][13:77],
                self.eval_params['weights'][0][77:141],
                self.eval_params['weights'][0][141:205],
                self.eval_params['weights'][0][205:269],
                self.eval_params['weights'][0][269:333],
                self.eval_params['weights'][0][333:397],
            ],
            
            [
                self.eval_params['weights'][1][13:77],
                self.eval_params['weights'][1][77:141],
                self.eval_params['weights'][1][141:205],
                self.eval_params['weights'][1][205:269],
                self.eval_params['weights'][1][269:333],
                self.eval_params['weights'][1][333:397],
            ]
        ]

    # get game phase score
    def get_phase_score(self):
        phase_score = 0
        material_weights_opening = self.eval_params['weights'][0][0:6]
        
        for square in range(64):
            if self.board.piece_at(square):
                if self.board.piece_at(square).piece_type > 1 and self.board.piece_at(square).piece_type < 6:
                    phase_score += material_weights_opening[self.board.piece_at(square).piece_type]

        return phase_score
    
    # static evaluation
    def evaluate(self):    
        # calculate game phase score based on material
        game_phase_score = self.get_phase_score()
        game_phase = -1;

        # init game phase
        if game_phase_score > self.opening_phase: game_phase = self.opening
        elif game_phase_score < self.endgame_phase: game_phase = self.endgame
        else: game_phase = self.middlegame

        # init scores
        score = 0;
        score_opening = 0;
        score_endgame = 0;

        # loop over bard squares
        for square in range(64):
            piece = 0;
            
            if self.board.piece_at(square):
                piece_type = self.board.piece_at(square).piece_type - 1
                
                if self.board.piece_at(square).color: piece = self.board.piece_at(square).piece_type
                else: piece = self.board.piece_at(square).piece_type + 6

                # evaluate material score
                score_opening += self.material_weights[self.opening][piece]
                score_endgame += self.material_weights[self.endgame][piece]
                
                # evaluate positional score
                if piece >= 1 and piece <= 6:
                    score_opening += self.pst[self.opening][piece_type][self.eval_params['mirror'][square]]
                    score_endgame += self.pst[self.endgame][piece_type][self.eval_params['mirror'][square]]
                
                elif piece >= 7 and piece <= 12:
                    score_opening -= self.pst[self.opening][piece_type][square]
                    score_endgame -= self.pst[self.endgame][piece_type][square]
        
        # interpolate values for middlegame     
        if game_phase == self.middlegame:
            try:
                score = (
                    score_opening * game_phase_score +
                    score_endgame * (self.opening_phase - game_phase_score)
                ) / self.opening_phase;
            
            except: score = 0
        
        # return pure score for opening / endgame
        elif game_phase == self.opening: score = score_opening;
        elif game_phase == self.endgame: score = score_endgame;
        
        score = int(score)
        if self.board.turn: return score
        else: return -score
    
    # quiescence search
    def quiescence(self, alpha, beta):
        stand_pat = self.evaluate();
        
        if stand_pat >= beta: return beta;
        if alpha < stand_pat: alpha = stand_pat;

        legal_moves = self.board.legal_moves
        move_list = []
        
        for move in legal_moves:
            if self.board.is_capture(move):
                try:
                    move_list.append({
                        'move': move,
                        'score': self.mvv_lva[
                                     self.board.piece_at(move.from_square).piece_type * 13 +
                                     self.board.piece_at(move.to_square).piece_type.  # HERE is the BUG with en-passant
                                 ]
                    })
                except AttributeError: # in case of en-passant move : the captured piece was not on the target square
                    move_list.append({
                        'move': move,
                        'score': self.mvv_lva[
                                     self.board.piece_at(move.from_square).piece_type * 13 +
                                     chess.PAWN      # in case of en-passant, the captured piece IS a pawn
                                 ]
                    })
        
        move_list = sorted(move_list, key=lambda k: k['score'], reverse=True) 

        for move in move_list:
            self.board.push(move['move'])
            score = -self.quiescence(-beta, -alpha)
            self.board.pop()
            
            if score >= beta: return beta
            if score > alpha: alpha = score;
        
        return alpha;
    
    # generate training dataset
    def generate_dataset(self, filename):
        with open(filename) as fr:
            next_game = chess.pgn.read_game(fr)
            count = 1
            
            while next_game:              
                print('extracting positions from game %s' % count)

                board = next_game.board()
                positions = []                
                
                move_num = 0
                
                for move in next_game.mainline_moves():
                    board.push(move)
                    move_num += 1
                    
                    if board.is_checkmate(): continue
                    if (self.evaluate() == self.quiescence(-50000, 50000)) and move_num > 5:
                        try: positions.append(board.fen() + ' [' + self.result[next_game.headers['Result']] + ']')
                        except: pass

                try: next_game = chess.pgn.read_game(fr)
                except: pass
                random.shuffle(positions)
                
                with open('positions.txt', 'a') as fw:
                    for position in positions:
                        fw.write(position + '\n')

                count += 1
    
    # extract weights from evaluation parameters
    def extract_weights(self):
        weights = []
        
        for phase in range(2):
            for weight in self.eval_params['weights'][phase]:
                weights.append(weight)

        return weights
    
    # update evaluation parameters with tuned weights
    def update_weights(self, weights):
        # update opening phase weights
        for index in range(int(len(weights) / 2)):
            self.eval_params['weights'][0][index] = weights[index]
    
        # update endgame phase weights
        for index in range(int(len(weights) / 2), len(weights)):
            self.eval_params['weights'][1][index - int(len(weights) / 2)] = weights[index]

        # update pointers
        self.map_params()
        
    # write weights to file
    def store_weights(self, filename):        
        # reset zero material score
        self.material_weights[self.opening][0] = 0;
        self.material_weights[self.endgame][0] = 0;
        
        with open('./temp_weights/' + filename, 'w') as f:
            f.write('  const openingPhaseScore = %s;\n' % self.opening_phase)
            f.write('  const endgamePhaseScore = %s;\n\n' % self.endgame_phase)
            f.write('  // material score\n  const materialWeights = [\n    // opening material score\n')
            f.write('    %s,\n\n' % self.material_weights[self.opening])
            f.write('    // endgame material score\n')
            f.write('    %s\n\n  ];\n\n' % self.material_weights[self.endgame])
            f.write('  // piece-square tables\n')
            f.write('  const pst = [\n')
            f.write('    // opening phase scores\n    [\n')
            
            for phase in range(2):
                for piece in [
                    {'pawn': 0},
                    {'knight': 1},
                    {'bishop': 2},
                    {'rook': 3},
                    {'queen': 4},
                    {'king': 5}
                ]:  
                    piece_type = list(piece.values())[0]
                    piece_name = list(piece.keys())[0]                   
                    
                    f.write('      // %s\n      [\n' % piece_name)
                    for row in range(8):
                        for col in range(8):
                            square = row * 8 + col
                            
                            if col == 0: f.write('        ')
                            if square != 63: f.write('%s%s,' % (' ' * (4 - len(str(self.pst[phase][piece_type][square]))),
                                                                       self.pst[phase][piece_type][square]))
                            
                            elif piece_name != 'king': f.write('%s%s,   o, o, o, o, o, o, o, o\n      ],\n'
                                % (' ' * (4 - len(str(self.pst[phase][piece_type][square]))),
                                self.pst[phase][piece_type][square]))

                            else: f.write('%s%s,   o, o, o, o, o, o, o, o\n      ]'
                                % (' ' * (4 - len(str(self.pst[phase][piece_type][square]))),
                                   self.pst[phase][piece_type][square]))
                        
                        if row != 7: f.write('   o, o, o, o, o, o, o, o,\n')
                        else: f.write('\n')
 
                    if phase == 0 and piece_name == 'king':
                        f.write('    ],\n\n    // endgame phase score\n    [\n')
            
            f.write('    ]\n  ];\n')            

    # get mean square error
    def mean_square_error(self, K, number_of_positions):
        with open('positions.txt', encoding='utf-8') as f:
            fens = f.read().split('\n')[0:number_of_positions]
            error = 0.0
            
            for fen in fens:
                try:
                    result = float(fen.split('[')[-1][:-1])
                    position = fen.split('[')[0]
                    self.board.set_fen(position)
                    score = self.evaluate()
                    sigmoid = 1 / (1 + pow(10, -K * score / 400))
                    error += pow(result - sigmoid, 2)
                
                except Exception as e: print(e)

            return error / number_of_positions

    # evaulation tuner
    def tune(self, K, number_of_positions):
        adjust_value = 1
        best_params = self.extract_weights()
        best_error = self.mean_square_error(K, number_of_positions)
        improved = True
        
        while improved:
            improved = False    
            for index in range(len(best_params)):
                new_params = json.loads(json.dumps(best_params))
                new_params[index] += adjust_value
                self.update_weights(new_params)
                new_error = self.mean_square_error(K, number_of_positions)

                print('Tuning param %s out of %s, mean square error %s' % 
                     (index, len(best_params), new_error))
                
                if new_error < best_error:
                    best_error = new_error
                    best_params = json.loads(json.dumps(new_params))
                    improved = 1
                    print('found better params +')
                    self.store_weights('tuning_weights.txt')
                
                else:
                    new_params[index] -= adjust_value * 2
                    self.update_weights(new_params)
                    new_error = self.mean_square_error(K, number_of_positions)
                    
                    if new_error < best_error:
                        best_error = new_error
                        best_params = json.loads(json.dumps(new_params))
                        improved = 1
                        print('found better params -')
                        self.store_weights('tuning_weights.txt')
            
            self.store_weights('session_weights_' + str(datetime.datetime.today().strftime('%Y-%m-%d-%H-%M')) + '.txt')
            print('Writing current session weights...')

        print('Writing final weights...')
        self.store_weights('final_weights.txt')
Beispiel #8
0
        for i in range(len(mass)):
            k = "q"
            if i == 0:
                k = "K"
            elif i == 1:
                k = "R"
            else:
                k = "k"
            fen[ord(mass[i][0]) - 97][int(mass[i][1]) - 1] = k

        for x in range(len(fen)):
            fen[x] = "".join([
                str(len(i)) if i[0][0] == "1" else i[0]
                for i in [list(g) for k, g in groupby(''.join(fen[x]))]
            ])

        original_fen = "/".join(fen)
        original_fen += ' b'

        board = chess.Board(fen=original_fen)
        print(original_fen)
        print(board)
        if board.is_checkmate():
            print("Checkmate")
        elif board.is_stalemate():
            print("Stalemate")
        elif board.is_check():
            print("Check")
        else:
            print("Normal")
Beispiel #9
0
def read_game(handle, Visitor=GameModelCreator):
    """
    Reads a game from a file opened in text mode.

    >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn")
    >>> first_game = chess.pgn.read_game(pgn)
    >>> second_game = chess.pgn.read_game(pgn)
    >>>
    >>> first_game.headers["Event"]
    'IBM Man-Machine, New York USA'

    By using text mode the parser does not need to handle encodings. It is the
    callers responsibility to open the file with the correct encoding.
    PGN files are ASCII or UTF-8 most of the time. So the following should
    cover most relevant cases (ASCII, UTF-8 without BOM, UTF-8 with BOM,
    UTF-8 with encoding errors).

    >>> pgn = open("data/pgn/kasparov-deep-blue-1997.pgn", encoding="utf-8-sig", errors="surrogateescape")

    Use `StringIO` to parse games from a string.

    >>> pgn_string = "1. e4 e5 2. Nf3 *"
    >>>
    >>> try:
    >>>     from StringIO import StringIO  # Python 2
    >>> except ImportError:
    >>>     from io import StringIO  # Python 3
    >>>
    >>> pgn = StringIO(pgn_string)
    >>> game = chess.pgn.read_game(pgn)

    The end of a game is determined by a completely blank line or the end of
    the file. (Of course blank lines in comments are possible.)

    According to the standard at least the usual 7 header tags are required
    for a valid game. This parser also handles games without any headers just
    fine.

    The parser is relatively forgiving when it comes to errors. It skips over
    tokens it can not parse. Any exceptions are logged.

    Returns the parsed game or ``None`` if the EOF is reached.
    """
    visitor = Visitor()

    dummy_game = Game()
    found_game = False
    found_content = False

    line = handle.readline()

    # Parse game headers.
    while line:
        # Skip empty lines and comments.
        if line.isspace() or line.lstrip().startswith("%"):
            line = handle.readline()
            continue

        if not found_game:
            visitor.begin_game()
            visitor.begin_headers()
            found_game = True

        # Read header tags.
        tag_match = TAG_REGEX.match(line)
        if tag_match:
            dummy_game.headers[tag_match.group(1)] = tag_match.group(2)
            visitor.visit_header(tag_match.group(1), tag_match.group(2))
        else:
            break

        line = handle.readline()

    if found_game:
        visitor.end_headers()

    # Get the next non-empty line.
    while line.isspace():
        line = handle.readline()

    # Movetext parser state.
    try:
        board_stack = collections.deque([dummy_game.board()])
    except ValueError as error:
        visitor.handle_error(error)
        board_stack = collections.deque([chess.Board()])

    # Parse movetext.
    while line:
        read_next_line = True

        # An empty line is the end of a game.
        if found_content and line.isspace():
            if found_game:
                visitor.end_game()
                return visitor.result()
            else:
                return

        for match in MOVETEXT_REGEX.finditer(line):
            token = match.group(0)

            if token.startswith("%"):
                # Ignore the rest of the line.
                line = handle.readline()
                continue

            if not found_game:
                found_game = True
                visitor.begin_game()

            if token.startswith("{"):
                # Consume until the end of the comment.
                line = token[1:]
                comment_lines = []
                while line and "}" not in line:
                    comment_lines.append(line.rstrip())
                    line = handle.readline()
                end_index = line.find("}")
                comment_lines.append(line[:end_index])
                if "}" in line:
                    line = line[end_index:]
                else:
                    line = ""

                visitor.visit_comment("\n".join(comment_lines).strip())

                # Continue with the current or the next line.
                if line:
                    read_next_line = False
                break
            elif token.startswith("$"):
                # Found a NAG.
                try:
                    nag = int(token[1:])
                except ValueError as error:
                    visitor.handle_error(error)
                else:
                    visitor.visit_nag(nag)
            elif token == "?":
                visitor.visit_nag(NAG_MISTAKE)
            elif token == "??":
                visitor.visit_nag(NAG_BLUNDER)
            elif token == "!":
                visitor.visit_nag(NAG_GOOD_MOVE)
            elif token == "!!":
                visitor.visit_nag(NAG_BRILLIANT_MOVE)
            elif token == "!?":
                visitor.visit_nag(NAG_SPECULATIVE_MOVE)
            elif token == "?!":
                visitor.visit_nag(NAG_DUBIOUS_MOVE)
            elif token == "(":
                if board_stack[-1].move_stack:
                    visitor.begin_variation()

                    board = board_stack[-1].copy()
                    board.pop()
                    board_stack.append(board)
            elif token == ")":
                # Found a close variation token. Always leave at least the
                # root node on the stack.
                if len(board_stack) > 1:
                    visitor.end_variation()
                    board_stack.pop()
            elif token in ["1-0", "0-1", "1/2-1/2", "*"
                           ] and len(board_stack) == 1:
                # Found a result token.
                found_content = True
                visitor.visit_result(token)
            else:
                # Found a SAN token.
                found_content = True

                # Replace zeros castling notation.
                if token == "0-0":
                    token = "O-O"
                elif token == "0-0-0":
                    token = "O-O-O"

                # Parse the SAN.
                try:
                    move = board_stack[-1].parse_san(token)
                except ValueError as error:
                    visitor.handle_error(error)
                else:
                    visitor.visit_move(board_stack[-1], move)
                    board_stack[-1].push(move)

        if read_next_line:
            line = handle.readline()

    if found_game:
        visitor.end_game()
        return visitor.result()
Beispiel #10
0
    async def chess(self, ctx: commands.Context, *args: str):
        """
        `!chess` __`Play chess`__

        **Usage:** !chess <user>

        **Examples:**
        `!chess abc#1234` starts a game of chess with abc#1234

        **Note:**
        Moves are in standard algebraic notation (e4, Nxf7, etc).
        """

        try:
            user = await MemberConverter().convert(ctx, " ".join(args))
        except BadArgument:
            return await ctx.send("That user doesn't exist.", delete_after=5)

        board = chess.Board()
        game = pgn.Game()
        node = None
        turns = [ctx.author, user]
        turn = random.choice([True, False])
        game.headers["Date"] = datetime.today().strftime("%Y.%m.%d")
        game.headers["White"] = turns[turn].display_name
        game.headers["Black"] = turns[not turn].display_name

        def render_board(board: chess.Board) -> BytesIO:
            boardimg = chess.svg.board(board=board, lastmove=board.peek() if board.move_stack else None, check=board.king(turn) if board.is_check() or board.is_checkmate() else None, flipped=board.turn == chess.BLACK)
            res = BytesIO()
            svg2png(bytestring=boardimg, write_to=res)
            res.seek(0)
            return res

        res = render_board(board)
        game_msg = await ctx.send(f"{turns[turn].mention}, its your turn.", file=discord.File(res, "file.png"))

        while True:
            try:
                msg = await self.bot.wait_for("message", timeout=600, check=lambda msg: msg.channel == ctx.channel and msg.author.id == turns[turn].id)
            except asyncio.TimeoutError:
                return await ctx.send("Timed out.", delete_after=5)

            if msg.content == "exit":
                res = render_board(board)
                game.headers["Result"] = board.result()
                await game_msg.delete()
                return await ctx.send(f"{turns[turn].mention} resigned. {turns[not turn].mention} wins.\n{str(game)}", file=discord.File(res, "file.png"))

            try:
                move = board.push_san(msg.content)
            except ValueError:
                continue

            await msg.delete()

            if not node:
                node = game.add_variation(move)
            else:
                node = node.add_variation(move)

            res = render_board(board)
            await game_msg.delete()

            if board.outcome() is not None:
                game.headers["Result"] = board.outcome().result()

                if board.is_checkmate():
                    return await ctx.send(f"Checkmate!\n\n{turns[not turn].mention} wins.\n{str(game)}", file=discord.File(res, "file.png"))
                else:
                    return await ctx.send(f"Draw!\n{str(game)}", file=discord.File(res, "file.png"))

            game_msg = await ctx.send(f"{turns[turn].mention}, its your turn." + ("\n\nCheck!" if board.is_check() else ""), file=discord.File(res, "file.png"))
            turn = not turn
 def __init__(self, color):
     self.color = color
     self.board = chess.Board()
     self.reward_map = {
         chess.PAWN: [
             0, 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 1, -2, -2, 1, 1, 0.5, 0.5,
             -0.5, -1, 0, 0, -1, -0.5, 0.5, 0, 0, 0, 2, 2, 0, 0, 0, 0.5,
             0.5, 1, 2.5, 2.5, 1, 0.5, 0.5, 1, 1, 2, 3, 3, 2, 1, 1, 5, 5, 5,
             5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         chess.KNIGHT: [
             -5, -4, -3, -3, -3, -3, -4, -5, -4, -2, 0, 0.5, 0.5, 0, -2, -4,
             -3, 0.5, 1, 1.5, 1.5, 1, 0.5, -3, -3, 0, 1.5, 2.0, 2.0, 1.5, 0,
             -3, -3, 0.5, 1.5, 2, 2, 1.5, 0.5, -3, -3, 0, 1, 1.5, 1.5, 1, 0,
             -3, -4, -2, 0, 0, 0, 0, -2, -4, -5, -4, -3, -3, -3, -3, -4, -5
         ],
         chess.BISHOP: [
             -2, -1, -1, -1, -1, -1, -1, -2, -1, 0.5, 0, 0, 0, 0, 0.5, -1,
             -1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 1, 1, 1, 1, 0, -1, -1, 0.5,
             0.5, 1, 1, 0.5, 0.5, -1, -1, 0, 0.5, 1, 1, 0.5, 0, -1, -1, 0,
             0, 0, 0, 0, 0, -1, -2, -1, -1, -1, -1, -1, -1, -2
         ],
         chess.ROOK: [
             0, 0, 0, 0.5, 0.5, 0, 0, 0, -0.5, 0, 0, 0, 0, 0, 0, -0.5, -0.5,
             0, 0, 0, 0, 0, 0, -0.5, -0.5, 0, 0, 0, 0, 0, 0, -0.5, -0.5, 0,
             0, 0, 0, 0, 0, -0.5, -0.5, 0, 0, 0, 0, 0, 0, -0.5, 0.5, 1, 1,
             1, 1, 1, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0
         ],
         chess.QUEEN: [
             -2, -1, -1, -0.5, -0.5, -1, -1, -2, -1, 0, 0.5, 0, 0, 0, 0, -1,
             -1, 0.5, 0.5, 0.5, 0.5, 0.5, 0, -1, 0, 0, 0.5, 0.5, 0.5, 0.5,
             0, -0.5, -0.5, 0, 0.5, 0.5, 0.5, 0.5, 0, -0.5, -1, 0, 0.5, 0.5,
             0.5, 0.5, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1, -2, -1, -1, -0.5,
             -0.5, -1, -1, -2
         ],
         chess.KING: [
             2,
             3,
             1,
             0,
             0,
             1,
             3,
             2,
             2,
             2,
             0,
             0,
             0,
             0,
             2,
             2,
             -1,
             -2,
             -2,
             -2,
             -2,
             -2,
             -2,
             -1,
             -2,
             -3,
             -3,
             -4,
             -4,
             -3,
             -3,
             -2,
             -3,
             -4,
             -4,
             -5,
             -5,
             -4,
             -4,
             -3,
             -3,
             -4,
             -4,
             -5,
             -5,
             -4,
             -4,
             -3,
             -3,
             -4,
             -4,
             -5,
             -5,
             -4,
             -4,
             -3,
             -3,
             -4,
             -4,
             -5,
             -5,
             -4,
             -4,
             -3,
         ]
     }
     if not color:
         for key in self.reward_map.keys():
             self.reward_map[key] = list(reversed(self.reward_map[key]))
     self.material_differential = 0
     self.dists = [
         [True, 0, 0, 0, 1, 0, 0],
         [True, 0, 1, 0, 0, 0, 0],
         [True, 0, 0, 1, 0, 0, 0],
         [True, 0, 0, 0, 0, 1, 0],
         [True, 0, 0, 0, 0, 0, 1],
         [True, 0, 0, 1, 0, 0, 0],
         [True, 0, 1, 0, 0, 0, 0],
         [True, 0, 0, 0, 1, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [True, 1, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 1, 0, 0, 0, 0, 0],
         [False, 0, 0, 0, 1, 0, 0],
         [False, 0, 1, 0, 0, 0, 0],
         [False, 0, 0, 1, 0, 0, 0],
         [False, 0, 0, 0, 0, 1, 0],
         [False, 0, 0, 0, 0, 0, 1],
         [False, 0, 0, 1, 0, 0, 0],
         [False, 0, 1, 0, 0, 0, 0],
         [False, 0, 0, 0, 1, 0, 0],
     ]
     self.piece_values = {
         chess.PAWN: 1,
         chess.KNIGHT: 3,
         chess.BISHOP: 3,
         chess.ROOK: 5,
         chess.QUEEN: 9,
         chess.KING: 1000
     }
     self.special_move_indices = {
         (2, 1, 0): 0,
         (1, 2, 0): 1,
         (-1, 2, 0): 2,
         (-2, 1, 0): 3,
         (-2, -1, 0): 4,
         (-1, -2, 0): 5,
         (-1, 2, 0): 6,
         (2, -1, 0): 7,
         (1, 0, 2): 8,
         (1, 0, 3): 9,
         (1, 0, 4): 10,
         (1, -1, 2): 11,
         (1, -1, 3): 12,
         (1, -1, 4): 13,
         (1, 1, 2): 14,
         (1, 1, 3): 15,
         (1, 1, 4): 16
     }
     self.unit_moves = {
         (1, 0): 0,
         (1, 1): 1,
         (0, 1): 2,
         (-1, 1): 3,
         (-1, 0): 4,
         (-1, -1): 5,
         (0, -1): 6,
         (1, -1): 7
     }
Beispiel #12
0
            print('--------------')
            print('Memory usage critical.')
            print('--------------')
            print('Saving Opening Book.')
            print('--------------')
            print('Total Completion rate: = ' + str(i / itermax))
            break

    filename = "C:/Users/44775/Documents/OpeningBook/Bk1.txt"
    assert os.path.exists(filename), 'File does not exist.'

    file_OB1 = open(filename, 'wb')
    pickle.dump(rootNode, file_OB1)

    return 'Opening Book Created.'


#filename = "C:/Users/44775/Documents/lichess_Games_2017_01/lichess_db_standard_rated_2017-01.10.pgn"
#CompleteRawData = ReadData(filename)
#Data = CleanDataSet(CompleteRawData,1300,225)

#cMoves = cleanMoves(Data[4])
#rtNode = UpdateGameTree(rootNode,cMoves,1)

rootNode = Node(board=chess.Board())
#gmstr = cleanMoves(CompleteRawData[4])

#ConstructGameTree(1300,225)

ConstructBook(350000, 10)
Beispiel #13
0
 def __init__(self, fen=None):
     if fen is None:
         fen = chess.Board().fen()
     super().__init__(fen, chess960=True)
    def run_game(self):
        mcts_player = mcts_pure(c_puct=5, n_playout=10)
        move_stack = ""
        board = chess.Board()

        chess_sets = Settings()
        screen = pygame.display.set_mode(
            (chess_sets.screen_width, chess_sets.screen_height))
        pygame.display.set_caption("Chess Game")

        pygame.init()
        image_path = '/home/k1758068/Desktop/alphaGoTest-master/image/'
        black_b = pygame.image.load(image_path + 'blackb.png').convert_alpha()
        black_k = pygame.image.load(image_path + 'blackk.png').convert_alpha()
        black_n = pygame.image.load(image_path + 'blackn.png').convert_alpha()
        black_p = pygame.image.load(image_path + 'blackp.png').convert_alpha()
        black_q = pygame.image.load(image_path + 'blackq.png').convert_alpha()
        black_r = pygame.image.load(image_path + 'blackr.png').convert_alpha()

        white_b = pygame.image.load(image_path + 'whiteb.png').convert_alpha()
        white_k = pygame.image.load(image_path + 'whitek.png').convert_alpha()
        white_n = pygame.image.load(image_path + 'whiten.png').convert_alpha()
        white_p = pygame.image.load(image_path + 'whitep.png').convert_alpha()
        white_q = pygame.image.load(image_path + 'whiteq.png').convert_alpha()
        white_r = pygame.image.load(image_path + 'whiter.png').convert_alpha()

        images = {
            3: [white_b, black_b],
            6: [white_k, black_k],
            2: [white_n, black_n],
            1: [white_p, black_p],
            5: [white_q, black_q],
            4: [white_r, black_r]
        }

        background_color = (230, 230, 230)
        image_path = '/home/k1758068/Desktop/alphaGoTest-master/image/'
        chess_board = pygame.image.load(image_path +
                                        'board_image.png').convert()

        with open(
                '/home/k1758068/Desktop/alphaGoTest-master/move_json_files/move12136.json',
                "rt") as f:
            screen.fill(background_color)
            chess_board_x = 0
            chess_board_y = 0

            screen.blit(chess_board, (chess_board_x, chess_board_y))
            d = (700 - 80) / 8
            for i in range(64):
                if board.piece_at(i):
                    piece = board.piece_at(i).piece_type
                    color = board.piece_at(i).color

                    if color:
                        piece = images[piece][0]
                    else:
                        piece = images[piece][1]

                    x = 48 + (i % 8) * d
                    y = (8 - (i // 8)) * d - 26
                    screen.blit(piece, (x, y))

            self.buff = json.load(f)
            result = self.buff[-1][0]
            white_weight = self.buff[-1][1]
            black_weight = self.buff[-1][2]
            result_real = 0
            states, mcts_probs, current_players = [], [], []
            print('stsrt')
            for j in range(len(self.buff) - 1):
                screen.fill(background_color)
                chess_board_x = 100
                chess_board_y = 50

                screen.blit(chess_board, (chess_board_x, chess_board_y))

                d = (950 - 55) / 8
                for i in range(64):
                    if board.piece_at(i):
                        piece = board.piece_at(i).piece_type
                        color = board.piece_at(i).color

                        screen.fill(background_color)
                        chess_board_x = 0
                        chess_board_y = 0

                        screen.blit(chess_board,
                                    (chess_board_x, chess_board_y))

                        d = (700 - 80) / 8
                        for i in range(64):
                            if board.piece_at(i):
                                piece = board.piece_at(i).piece_type
                                color = board.piece_at(i).color

                                if color:
                                    piece = images[piece][0]
                                else:
                                    piece = images[piece][1]

                                x = 48 + (i % 8) * d
                                y = (8 - (i // 8)) * d - 26
                                screen.blit(piece, (x, y))
                myfont = pygame.font.SysFont('test', 30)
                textsurface = myfont.render(move_stack, True, (0, 0, 0))
                screen.blit(textsurface, (1000, 1000))

                move = self.buff[j]
                # perform a move
                board.push(chess.Move.from_uci(move))
                screen.fill(background_color)

                chess_board_x = 0
                chess_board_y = 0

                screen.blit(chess_board, (chess_board_x, chess_board_y))

                d = (700 - 80) / 8
                for i in range(64):
                    if board.piece_at(i):
                        piece = board.piece_at(i).piece_type
                        color = board.piece_at(i).color

                        if color:
                            piece = images[piece][0]
                        else:
                            piece = images[piece][1]

                        x = 48 + (i % 8) * d
                        y = (8 - (i // 8)) * d - 26
                        screen.blit(piece, (x, y))
                time.sleep(0.5)
                #print("game over:",board.is_game_over(claim_draw=True))
                pygame.display.flip()
                result_real = board.result(claim_draw=True)

            pygame.display.flip()
Beispiel #15
0
def main() -> None:
    global final_fen
    global player_color
    global turn
    global fens_list
    global time_to_think
    global num_obs

    #update_screen_cords()
    while True:
        #To update the board position at screen
        if keyboard.is_pressed('a'):
            print('Set new coordinates for the screenshot')
            update_screen_cords()

        #Pause
        if keyboard.is_pressed('q'):
            print('Pause')
            while True:
                time.sleep(0.1)
                if keyboard.is_pressed('w'):
                    print('Continue')
                    break

        #Exit
        if keyboard.is_pressed('e'):
            print('Exit')
            engine.quit()
            raise SystemExit

        #Change time_to_think
        if keyboard.is_pressed('t'):
            print('Update time_to_think')
            print('Prev time_to_think was: ', time_to_think)
            is_valid = False
            while (is_valid == False):
                try:
                    time_to_think = float(
                        input('Introduce new time_to_think: '))
                    is_valid = True
                except Exception as e:
                    print('Invalid time_to_think value')

        #Change num_obs
        if keyboard.is_pressed('y'):
            print('Update num_obs')
            print('Prev num_obs was: ', num_obs)
            is_valid = False
            while (is_valid == False):
                try:
                    num_obs = int(input('Introduce new num_obs: '))
                    is_valid = True
                except Exception as e:
                    print('Invalid num_obs value')

        #Try to get the board position
        update_fens_list()

        if (len(fens_list) % 2 == 1):
            turn = 'w'
        else:
            turn = 'b'

        #Add to final_fen the castling rights acording to the last fen (fens_list[-1])
        if (turn == player_color):
            castling = ''
            test = fens_list[-1] + ' ' + 'w' + ' KQkq - 0 0'
            test_castling_board = chess.Board(test)
            if (test_castling_board.has_kingside_castling_rights(1)):
                castling += 'K'
            if (test_castling_board.has_queenside_castling_rights(1)):
                castling += 'Q'
            if (test_castling_board.has_kingside_castling_rights(0)):
                castling += 'k'
            if (test_castling_board.has_queenside_castling_rights(0)):
                castling += 'q'
            if (castling == ''):
                castling = '-'

            final_fen = fens_list[-1] + ' ' + turn + ' ' + castling + ' - 0 0'
            board = chess.Board(final_fen)

            if (board.is_valid()):
                info = engine.analyse(board,
                                      chess.engine.Limit(time=time_to_think))
                move = info['pv'][0].uci()
                board.push(chess.Move.from_uci(move))
                board_fen = board.fen().split(' ')[0]
                fens_list.append(board_fen)
                make_move(move)
            else:
                fens_list.pop()
                print("DEBUG: Invalid FEN")
                print(final_fen)
Beispiel #16
0
def play_immortal_game():
    board = chess.Board()

    # 1. e4 e5
    board.push_san("e4")
    board.push_san("e5")

    # 2. f4 exf4
    board.push_san("f4")
    board.push_san("exf4")

    # 3. Bc4 Qh4+
    board.push_san("Bc4")
    board.push_san("Qh4+")

    # 4. Kf1 b5?!
    board.push_san("Kf1")
    board.push_san("b5")

    # 5. Bxb5 Nf6
    board.push_san("Bxb5")
    board.push_san("Nf6")

    # 6. Nf3 Qh6
    board.push_san("Nf3")
    board.push_san("Qh6")

    # 7. d3 Nh5
    board.push_san("d3")
    board.push_san("Nh5")

    # 8. Nh4 Qg5
    board.push_san("Nh4")
    board.push_san("Qg5")

    # 9. Nf5 c6
    board.push_san("Nf5")
    board.push_san("c6")

    # 10. g4 Nf6
    board.push_san("g4")
    board.push_san("Nf6")

    # 11. Rg1! cxb5?
    board.push_san("Rg1")
    board.push_san("cxb5")

    # 12. h4! Qg6
    board.push_san("h4")
    board.push_san("Qg6")

    # 13. h5 Qg5
    board.push_san("h5")
    board.push_san("Qg5")

    # 14. Qf3 Ng8
    board.push_san("Qf3")
    board.push_san("Ng8")

    # 15. Bxf4 Qf6
    board.push_san("Bxf4")
    board.push_san("Qf6")

    # 16. Nc3 Bc5
    board.push_san("Nc3")
    board.push_san("Bc5")

    # 17. Nd5 Qxb2
    board.push_san("Nd5")
    board.push_san("Qxb2")

    # 18. Bd6! Bxg1?
    board.push_san("Bd6")
    board.push_san("Bxg1")

    # 19. e5! Qxa1+
    board.push_san("e5")
    board.push_san("Qxa1+")

    # 20. Ke2 Na6
    board.push_san("Ke2")
    board.push_san("Na6")

    # 21. Nxg7+ Kd8
    board.push_san("Nxg7+")
    board.push_san("Kd8")

    # 22. Qf6+! Nxf6
    board.push_san("Qf6+")
    board.push_san("Nxf6")

    # 23. Be7# 1-0
    board.push_san("Be7#")
    assert board.is_checkmate()
import sys
import chess
import random

import common

# Obtain random endgame position
positions = open('mates_and_endgames.txt').read().splitlines()
state = random.choice(positions)

agent = common.Agent()
experience = []

# Play out position until the game is over, or more than 50 moves were made
while True:
    board = chess.Board(state)
    if board.is_game_over() or board.fullmove_number > 50:
        break
    policy = agent.policy(state)
    experience.append((state, policy))
    move = common.sample(policy)
    board.push(chess.Move.from_uci(move))
    state = board.fen()
    sys.stderr.write(state + "\n")

# Assign game result
board = chess.Board(state)
results = [-0.75, -0.75]
if board.is_checkmate():
    if board.turn:
        results = [+1, -1]  # black won
Beispiel #18
0
 def gen_root(self) -> State[chess.Board]:
     return _State(chess.Board())
Beispiel #19
0
def evaluate_moves(position, type):
    pos = str(position)
    x = int(pos[0])
    y = int(pos[1])
    possible_moves = []  # Intializing empty list
    print("Position is: ", (x, y))
    print("Piece type is :", type)
    board = chess.Board()
    # resolving knight moves.
    if type == "Knight":
        print("Possible Knight moves are: ")
        possible_moves += [(x + 2, y + 1), (x + 2, y - 1), (x + 1, y + 2),
                           (x + 1, y - 2), (x - 2, y - 1), (x - 2, y + 1),
                           (x - 1, y + 2), (x - 1, y - 2)]
        print(possible_moves)

    #Resolving Rook moves
    elif type == "Rook":
        print("Possible Rook moves are: ")
        # resolving down side rook moves
        a = x + 1
        b = y
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a + 1][b][0] == "w":
                    possible_moves += ([[a + 1], [b]])
            except IndexError:
                pass
            a += 1

        # resolving left side rook moves
        a = x
        b = y - 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a][b - 1][0] == "w":
                    possible_moves += ([[a], [b - 1]])
            except IndexError:
                pass
            b -= 1

        # resolving up side rook
        a = x - 1
        b = y
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a - 1][b][0] == "w":
                    possible_moves += ([[a - 1], [b]])
            except IndexError:
                pass
            a -= 1

        # resolving right side rook
        a = x
        b = y + 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a][b + 1][0] == "w":
                    possible_moves += ([[a], [b + 1]])
            except IndexError:
                pass
            b += 1

    #Resolving Queen moves
    elif type == "Queen":
        print("Possible Queen moves are: ")
        # Resolving down and right side Queen
        a = x + 1
        b = y + 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a + 1][b + 1][0] == "w":
                    possible_moves += ([[a + 1], [b + 1]])
            except IndexError:
                pass
            a += 1
            b += 1

        # Resolving down and left side Queen
        a = x + 1
        b = y - 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a + 1][b - 1][0] == "w":
                    possible_moves += ([[a + 1], [b - 1]])
            except IndexError:
                pass
            a += 1
            b -= 1

        # resolving up and right side
        a = x - 1
        b = y + 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a - 1][b + 1][0] == "w":
                    possible_moves += ([[a - 1], [b + 1]])
            except IndexError:
                pass
            a -= 1
            b += 1

        # Resolving up and left
        a = x - 1
        b = y - 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a - 1][b - 1][0] == "w":
                    possible_moves += ([[a - 1], [b - 1]])
            except IndexError:
                pass
            a -= 1
            b -= 1

        # Resolving down side Queen
        a = x + 1
        b = y
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a + 1][b][0] == "w":
                    possible_moves += ([[a + 1], [b]])
            except IndexError:
                pass
            a += 1

        # Resolving left
        a = x
        b = y - 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a][b - 1][0] == "w":
                    possible_moves += ([[a], [b - 1]])
            except IndexError:
                pass
            b -= 1

        # Resolving up side
        a = x - 1
        b = y
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a - 1][b][0] == "w":
                    possible_moves += ([[a - 1], [b]])
            except IndexError:
                pass
            a -= 1

        # Resolving right side
        a = x
        b = y + 1
        while (7 > a >= 0 and 7 > b >= 0) and (board[a][b] == ""):
            possible_moves += ([[a], [b]])
            try:
                if board[a][b + 1][0] == "w":
                    possible_moves += ([[a], [b + 1]])
            except IndexError:
                pass
            b += 1
Beispiel #20
0
	def test_stalemate(self):
		"""Stalemate position should return a score of 0 for both colors."""
		stalemateblack = chess.Board(fen='k7/8/K1N5/8/8/8/8/8 b')
		self.assertTrue(score_board_rel(stalemateblack) == 0)
		stalematewhite = stalemateblack.mirror()
		self.assertTrue(score_board_rel(stalematewhite) == 0)
def __all_moves__():
    """
    returns a list of all possible chess moves
    :return:
    """
    possible_moves = []

    # all queen moves
    queen = chess.Piece(chess.QUEEN, chess.WHITE)
    for square in chess.SQUARES:
        board = chess.Board().empty()
        board.set_piece_at(square, queen)

        for move in board.legal_moves:
            possible_moves.append(str(move))

    # all knight moves
    knight = chess.Piece(chess.KNIGHT, chess.WHITE)
    for square in chess.SQUARES:
        board = chess.Board().empty()
        board.set_piece_at(square, knight)

        for move in board.legal_moves:
            possible_moves.append(str(move))

    # white pawn promotion
    back_rank = [
        chess.A8, chess.B8, chess.C8, chess.D8, chess.E8, chess.F8, chess.G8,
        chess.H8
    ]
    seventh_rank = [
        chess.A7, chess.B7, chess.C7, chess.D7, chess.E7, chess.F7, chess.G7,
        chess.H7
    ]

    # simple promotion
    pawn = chess.Piece(chess.PAWN, chess.WHITE)
    for square in seventh_rank:
        board = chess.Board().empty()
        board.set_piece_at(square, pawn)

        for move in board.legal_moves:
            possible_moves.append(str(move))

    # promotion with a capture
    knight = chess.Piece(chess.KNIGHT, chess.BLACK)
    knight_board = chess.Board().empty()
    for square in back_rank:
        knight_board.set_piece_at(square, knight)

    for square in seventh_rank:
        board = copy.deepcopy(knight_board)
        board.set_piece_at(square, pawn)

        for move in board.legal_moves:
            possible_moves.append(str(move))

    # # black pawn promotion
    # first_rank = [chess.A1, chess.B1, chess.C1, chess.D1, chess.E1, chess.F1, chess.G1, chess.H1]
    # second_rank = [chess.A2, chess.B2, chess.C2, chess.D2, chess.E2, chess.F2, chess.G2, chess.H2]
    #
    # # simple promotion
    # pawn = chess.Piece(chess.PAWN, chess.BLACK)
    # for square in second_rank:
    #     board = chess.Board().empty()
    #     board.set_piece_at(square, pawn)
    #     board.turn = chess.BLACK
    #
    #     for move in board.legal_moves:
    #         possible_moves.append(str(move))
    #
    # # promotion with a capture
    # knight = chess.Piece(chess.KNIGHT, chess.WHITE)
    # knight_board = chess.Board().empty()
    # for square in first_rank:
    #     knight_board.set_piece_at(square, knight)
    #
    # for square in second_rank:
    #     board = copy.deepcopy(knight_board)
    #     board.set_piece_at(square, pawn)
    #     board.turn = chess.BLACK
    #
    #     for move in board.legal_moves:
    #         possible_moves.append(str(move))

    # sort the list
    possible_moves.sort()

    return possible_moves
Beispiel #22
0
	def test_checkmate(self):
		"""Being checkmated should return a score of -inf, irrespective of color."""
		checkmatedblack = chess.Board(fen='k1Q5/8/K7/8/8/8/8/8 b')
		self.assertTrue(score_board_rel(checkmatedblack) == -math.inf)
		checkmatedwhite = checkmatedblack.mirror()
		self.assertTrue(score_board_rel(checkmatedwhite) == -math.inf)
Beispiel #23
0
import chess
import chess.variant
#import chess.engine

max_depth = 3

global_iteration_count = 0

PawnVal = 100
KnightVal = 350
BishopVal = 525
RookVal = 525
QueenVal = 1000
KingVal = 10000

globalBoard = chess.Board()


# this function merely calculates the material advantage of white over black
def diff_pieces(board_state: chess.Board):
    # get pieces of white and subtract them from black
    white_pawns = len(board_state.pieces(chess.PAWN, chess.WHITE))
    white_knights = len(board_state.pieces(chess.KNIGHT, chess.WHITE))
    white_bishops = len(board_state.pieces(chess.BISHOP, chess.WHITE))
    white_rooks = len(board_state.pieces(chess.ROOK, chess.WHITE))
    white_king = len(board_state.pieces(chess.KING, chess.WHITE))
    white_queen = len(board_state.pieces(chess.QUEEN, chess.WHITE))

    black_pawns = len(board_state.pieces(chess.PAWN, chess.BLACK))
    black_knights = len(board_state.pieces(chess.KNIGHT, chess.BLACK))
    black_bishops = len(board_state.pieces(chess.BISHOP, chess.BLACK))
Beispiel #24
0
def update_fen(df_elem):
    """takes as input a row with a full fen, and returns
    a new fen"""
    board = chess.Board(df_elem[["FEN"]][0])
    board.push_san(df_elem[["First Move"]][0])
    return board.fen()
a Angry Monkey.
"""


def pick_move(board, time_left_on_clock):
    """
    takes in a chess.Board
    as well as time_left_on_clock in seconds
    returns a chess.Move
    """
    moves = list(board.legal_moves)
    for m in moves:
        board.push(m)
        if board.is_checkmate():
            return m
        else:
            board.pop()
    capturing_moves = [m for m in moves if board.is_capture(m)]
    if capturing_moves:
        return random.choice(capturing_moves)
    else:
        return random.choice(moves)


if __name__ == "__main__":
    b = chess.Board()

    while not b.is_checkmate():
        move = pick_move(b, 0)
        b.push(move)
Beispiel #26
0
    async def _chess(self, ctx, user: discord.Member, *, fen=None):
        """Starts a chess game with another player.
           You may start with a custom position by providing a FEN at the end of the command.

           Games take place in DMs and all moves are made with Standard Algebraic Notation.

           **Usage:** `$chess <opponent> [FEN]`
        """
        if fen:
            try:
                board = chess.Board(fen)
            except ValueError:
                return await ctx.send(
                    'The custom FEN position you provided wasn\'t valid.')
        else:
            board = chess.Board()

        if ctx.author in self.in_game or user in self.in_game:
            return await ctx.send(
                'Either you or the user you challenged is already in a game.')
        m = await ctx.send(
            f'{user.mention}, press the check mark to accept the chess match.')
        emoji = ('\u2705', '\u274e')
        [await m.add_reaction(e) for e in emoji]

        def check(p):
            return p.user_id == user.id and p.message_id == m.id and str(
                p.emoji) in emoji

        try:
            payload = await self.bot.wait_for('raw_reaction_add',
                                              timeout=30,
                                              check=check)
        except asyncio.TimeoutError:
            [await m.remove_reaction(e, self.bot) for e in emoji]
            return await ctx.send(
                'You took too long to accept/decline the match.')

        if str(payload.emoji) == emoji[1]:
            return await ctx.send(f'{user.mention} declined the match.')

        await ctx.send(
            'How long does each player have for the entire match? Enter a number in minutes.'
        )

        def check(msg):
            return msg.author == ctx.author and msg.channel == ctx.channel and msg.content.isdigit(
            )

        try:
            m = await self.bot.wait_for('message', timeout=60, check=check)
        except asyncio.TimeoutError:
            return await ctx.send(
                "You took too long to say a time, I have timeout'd.")

        seconds = int(m.content) * 60

        wleft = seconds
        bleft = seconds
        self.in_game.append(ctx.author)
        self.in_game.append(user)

        white = ctx.author
        black = user

        moves = PrettyTable()
        resign = ctx.prefix.lower() + 'resign'
        timer = ctx.prefix.lower() + 'timer'
        moves.field_names = ['White', 'Black']

        await white.send('Your turn first.', file=fmtbrd(board, 'white'))
        await black.send('You are black. White moves first.',
                         file=fmtbrd(board, 'black'))

        await ctx.send('Head to DMs! Your game will be taking place there.\n\n'
                       f'`{ctx.prefix}resign` to resign\n'
                       f'`{ctx.prefix}timer` to check how much time left')

        async def wait_for():
            def check2(msg):
                return msg.author in (white, black) and not msg.guild and \
                       (msg.content.lower() == timer or msg.content.lower() == resign)

            while True:
                check2_msg = await self.bot.wait_for('message', check=check2)
                if check2_msg.author == white:
                    other = black
                    o_left = bleft
                    u_left = wleft
                else:
                    u_left = bleft
                    o_left = wleft
                if check2_msg.content.lower() == timer:
                    await check2_msg.author.send(
                        f'Your time left: `{u_left}`\nYour opponent time left: `{o_left}`'
                    )
                else:
                    self.in_game.remove(white)
                    self.in_game.remove(black)
                    await check2_msg.author.send('**You lost - Resignation**')
                    await other.send('**You won - Resignation**')
                    return

        task = self.bot.loop.create_task(wait_for())
        userd = False
        oppd = False

        async def task2():
            while True:
                if black not in self.in_game or white not in self.in_game:
                    return
                await asyncio.sleep(1)

                wleft -= 1
                bleft -= 1
                if wleft <= 0:
                    await white.send('**You lost - timeout**')
                    await black.send('**You won - timeout**')
                    self.in_game.remove(white)
                    self.in_game.remove(black)
                    return
                if bleft <= 0:
                    await white.send('**You lost - timeout**')
                    await black.send('**You won - timeout**')
                    self.in_game.remove(white)
                    self.in_game.remove(black)
                    return

        while True:
            if ctx.author in self.in_game and user in self.in_game:

                if board.turn:
                    left = wleft
                    user, opp = white, black
                else:
                    left = bleft
                    user, opp = black, white

                userd = True
                oppd = False

                def check(msg):
                    return msg.author.id == user.id and not msg.guild

                while True:
                    try:
                        m = await self.bot.wait_for('message',
                                                    check=check,
                                                    timeout=left)
                    except asyncio.TimeoutError:
                        task.cancel()
                        self.in_game.pop(user)
                        self.in_game.pop(opp)
                        await user.send('**You lost - Timeout**')
                        await opp.send('**You won - Timeout**')
                        return

                    try:
                        board.push_san(m.content)
                        userd = False
                        break
                    except ValueError:
                        await user.send(
                            'Not a legal move.\n'
                            '- Check'
                            '- Pin'
                            '- Uppercase all pieces and lowercase all squares\n'
                            '- More than one of the same piece could move to the square'
                        )

                if board.is_stalemate():
                    self.in_game.remove(user)
                    self.in_game.remove(opp)
                    task.cancel()
                    await user.send('**Draw - Stalemate**')
                    await opp.send('**Draw - Stalemate**')
                    return
                if board.is_checkmate():
                    self.in_game.remove(user)
                    self.in_game.remove(opp)
                    task.cancel()
                    await user.send('**You won - Checkmate**')
                    await opp.send('**You lost - Checkmate**')
                    return
                if board.is_insufficient_material():
                    self.in_game.remove(user)
                    self.in_game.remove(opp)
                    task.cancel()
                    await user.send('**Draw - Insufficient Material**')
                    await opp.send('**Draw - Insufficient Material**')
                    return
                if board.is_repetition(3):
                    self.in_game.remove(user)
                    self.in_game.remove(opp)
                    task.cancel()
                    await user.send('**Draw - Threefold Repetition**')
                    await opp.send('**Draw - Threefold Repetition**')
                    return
                if board.turn:
                    w_content = 'Your opponent moved. Your turn now.'
                    b_content = 'You moved. Waiting on your opponent.'
                else:
                    w_content = 'You moved. Waiting on your opponent.'
                    b_content = 'Your opponent moved. Your turn now.'
                await white.send(w_content, file=fmtbrd(board, 'white'))
                await black.send(b_content, file=fmtbrd(board, 'black'))
            else:
                return
Beispiel #27
0
def _min_max(
    context,
    board_fen,
    search_depth=None,
    max_player=True,
    alpha=-math.inf,
    beta=math.inf,
    save_tree=False,
    sum_children=False,
):
    board = chess.Board(fen=board_fen)
    if search_depth is None:
        search_depth = context.search_depth

    best_move = None
    best_eval = math.inf
    if max_player:
        best_eval = best_eval * -1

    if board.is_game_over():
        return None, 0

    for move in board.legal_moves:

        board.push(move)

        if search_depth == 0 or board.is_game_over():

            # If we are at the bottom already
            node_value = context.eval_board(board)

        else:
            # spawn a new thread

            _, node_value = _min_max(
                context,
                board.fen(),
                search_depth - 1,
                not max_player,
                alpha=alpha,
                beta=beta,
            )

        _ = board.pop()
        # try:
        # if sum_children:
        # node_value = context.eval_move(move, board) + level_eval
        # else:
        # node_value = context.eval_move(move, board)
        # except TypeError:
        # print(context.eval_move(move, board))
        # print(level_eval)

        if max_player:
            if best_eval < node_value:
                best_eval = node_value
                best_move = move

            if node_value > beta:
                return best_move, best_eval

            if node_value > alpha:
                alpha = node_value

        else:
            if best_eval > node_value:
                best_eval = node_value
                best_move = move

            if node_value < alpha:
                return best_move, best_eval

            if node_value < beta:
                beta = node_value

    return best_move, best_eval
Beispiel #28
0
 def __init__(self, board=chess.Board()):
     threading.Thread.__init__(self)
     self.board = board
     self.engine = ChessEngine()
     self.web= chessboard.Web()
     self.web.start()
Beispiel #29
0
import chess
import Chess_utils
import chess.engine

board = chess.Board()

engine = chess.engine.SimpleEngine.popen_uci(r"c:\\stockfish_20090216_x64")

limit = chess.engine.Limit(time=2.0)

print(board)
print("Whites turn")
chess.Color = False

while Chess_utils.continue_playing(board):

    validmove = False

    if not chess.Color:
        result = engine.play(board, limit)
        board.push(result.move)
    else:
        while (not validmove):
            print("your move:")
            try:
                move = Chess_utils.get_move()
                if chess.Move.from_uci(move) in board.legal_moves:
                    m = chess.Move.from_uci(move)
                    board.push(m)
                    validmove = True
                else:
Beispiel #30
0
    def alpha_beta_search(self, board, depth, alpha, beta, color):
        '''
        board是当前棋面
        depth是当前搜索深度
        alpha beta
        color是当前的下棋者
        '''
        #如果搜到游戏结束了,直接返回INF
        if board.is_game_over():
            if board.is_stalemate():
                return 0
            return -color * self.INF

        #如果达到搜索层数,直接返回value
        if depth == 0:
            if color == 1:
                return -self.valuation(
                    chess.Board(first_person_view_fen(self.board.fen(), 1)))
            else:
                return self.valuation(board)

        #在policy网络预测的值取前4个概率最大的走子
        legal_moves_list = list(board.legal_moves)
        #print()

        policy_list = []
        if color == 1:
            feature_plane = convert_board_to_plane(board.fen())
            feature_plane = feature_plane[np.newaxis, :]
            policy, _ = self.model.predict(feature_plane, batch_size=1)

            policy = [
                first_person_view_policy(policy[0], is_black_turn(board.fen()))
            ]
            policy_list = [(move, policy[0][self.move_hash[move.uci()]])
                           for move in legal_moves_list]
            policy_list = sorted(policy_list, key=lambda x: x[1],
                                 reverse=True)  #从大到小排序
        else:
            for move in legal_moves_list:
                policy_list.append((move, 1))

        #搜索前4个
        threshold = min(0.01, max([policy_v[1] for policy_v in policy_list]))
        lim = 5

        for move, policy_value in (policy_list[:lim]
                                   if color == 1 else policy_list):
            if policy_value < threshold:
                continue

            board.push(move)

            value = self.alpha_beta_search(board, depth - 1, alpha, beta,
                                           -color)

            board.pop()
            if self.search_depth == depth:
                self.move_value[move] = value
                #print(move.uci())
            '''if depth == 1:
                print(move.uci(), is_black_turn(board.fen()), ' ', board.fen(), 'policy=', _)'''
            if color == 1:
                alpha = max(alpha, value)
            else:
                beta = min(beta, value)
            if beta <= alpha:
                break
        return alpha if color == 1 else beta