예제 #1
0
def play_game(ws):
    board = generate_board(10)
    ws.send(json.dumps({"player": "random", "type": "player"}))
    engine = chess.engine.SimpleEngine.popen_uci("/usr/bin/stockfish")
    for state in board.states:
        analysis = engine.analyse(board, chess.engine.Limit(time=MOVE_GAP / 3))
        ws.send(
            json.dumps({
                "pieces": state,
                "score": analysis.score.white().score(),
                "type": "update"
            }))

    ws.send(json.dumps({"player": "nonrandom", "type": "player"}))

    while not board.is_game_over(claim_draw=True):
        result = engine.play(board, chess.engine.Limit(time=MOVE_GAP))
        analysis = engine.analyse(board, chess.engine.Limit(time=MOVE_GAP))
        print("score is:", analysis.score, "fen is", board.fen())
        board.push(result.move)
        ws.send(
            json.dumps({
                "pieces": board.get_pieces(),
                "score": analysis.score.white().score(),
                "type": "update"
            }))

    if board.is_checkmate():
        ws.send(json.dumps({"winner": not board.turn(), "type": "winner"}))
    else:
        ws.send(json.dumps({"winner": None, "type": "winner"}))
    engine.quit()
예제 #2
0
def compute_move_scores(game_str, engine):
    # we are black, crucially...
    moves = game_str.split(' ')
    board = chess.Board()
    bot_scores = []
    comp_scores = []
    for i, move in enumerate(moves):
        if i % 2 == 0:
            # this is a computer move, do not analyse it
            board.push_san(move)
        else:
            # this is our move, we need to provide analysis
            board.push_san(move)
            bot_score_tup = engine.analyse(board, chess.engine.Limit(time=0.1), game='key1')
            board.pop()
            computer_move = engine.play(board, chess.engine.Limit(time=0.05))
            board.push(computer_move.move)
            comp_score_tup = engine.analyse(board, chess.engine.Limit(time=0.1), game='key2')
            board.pop()
            board.push_san(move)

            if not bot_score_tup['score'].is_mate() and not comp_score_tup['score'].is_mate():
                bot_scores.append(bot_score_tup['score'].black().score())
                comp_scores.append(comp_score_tup['score'].black().score())

    bot_scores = np.array(bot_scores)
    comp_scores = np.array(comp_scores)

    # split the games up into early, mid and late-game
    early_game_cutoff = 12
    mid_game_cutoff = 24

    bot_early, comp_early = bot_scores[:early_game_cutoff], comp_scores[:early_game_cutoff]
    bot_mid, comp_mid = bot_scores[early_game_cutoff:mid_game_cutoff], comp_scores[early_game_cutoff:mid_game_cutoff]
    bot_late, comp_late = bot_scores[mid_game_cutoff:], comp_scores[mid_game_cutoff:]

    assert (len(bot_early) + len(bot_mid) + len(bot_late)) == len(bot_scores)
    assert (len(comp_early) + len(comp_mid) + len(comp_late)) == len(comp_scores)

    # compute MPS across full-game and across regions

    full_diff = bot_scores - comp_scores
    early_diff = bot_early - comp_early
    mid_diff = bot_mid - comp_mid
    late_diff = bot_late - comp_late

    norm_full = np.mean(np.abs(comp_scores))
    norm_early = np.mean(np.abs(comp_early))
    norm_mid = np.mean(np.abs(comp_mid))
    norm_late = np.mean(np.abs(comp_late))

    MPS_full = np.mean(full_diff / norm_full)
    MPS_early = np.mean(early_diff / norm_early)
    MPS_mid = np.mean(mid_diff / norm_mid)
    MPS_late = np.mean(late_diff / norm_late)

    return (bot_scores, comp_scores, MPS_full, MPS_early, MPS_mid, MPS_late)
def coach_opinion(board, curr_move):
    engine = chess.engine.SimpleEngine.popen_uci("stockfish_20011801_x64.exe")
    curr_analyse = engine.analyse(board, chess.engine.Limit(depth=20))
    curr_score = int(str(curr_analyse.score)) / 100
    board.pop()
    prev_analyse = engine.analyse(board,
                                  chess.engine.Limit(depth=20),
                                  multipv=3)
    prev_score = int(str(prev_analyse[0].score)) / 100
    best_move = prev_analyse[0]['pv'][0]
    very_good_move = prev_analyse[1]['pv'][0]
    good_move = prev_analyse[2]['pv'][0]
    result = ""
    final_result = ""
    if str(curr_move) == str(best_move):
        result = "Best Move!"
    elif str(curr_move) == str(very_good_move):
        result = "Very Good Move!"
    elif str(curr_move) == str(good_move):
        result = "Good Move!"
    else:
        if board.turn:
            if prev_score >= 0:
                if 0 < curr_score < prev_score:
                    result = "Bad Move!"
                elif curr_score == 0:
                    result = "Very Bad Move!"
                else:
                    result = "Losing Move!"
            elif curr_score - prev_score >= -1.00:
                result = "Bad Move!"
            elif curr_score - prev_score >= -3.00:
                result = "Very Bad Move!"
            else:
                result = "Losing Move!"
        else:
            if prev_score < 0:
                if 0 > curr_score > prev_score:
                    result = "Bad Move!"
                elif curr_score == 0:
                    result = "Very Bad Move!"
                else:
                    result = "Losing Move!"
            elif curr_score - prev_score <= 1.00:
                result = "Bad Move!"
            elif curr_score - prev_score <= 3.00:
                result = "Very Bad Move!"
            else:
                result = "Losing Move!"
    result += "(" + str(curr_score) + ")"
    final_result = result + " (The Best Move was " + str(
        best_move) + ", " + str(
            int(str(prev_analyse[0]['score'])) / 100) + " )"
    engine.close()
    board.push_uci(curr_move)
    return final_result
예제 #4
0
    def __move_piece(self, engine, book, side):

        score_change = 0
        moves_mate = math.inf
        promote_to_Q = False

        if len(self.moves_game) != 0:
            self.board.push_san(self.moves_game[-1])

        if sum(1 for _ in book.find_all(self.board)) != 0:
            for entry in book.find_all(self.board):
                next_move = entry.move
                self.board.push(next_move)
                break
        else:
            if self.elapsed_time < 50:
                score_prior = engine.analyse(self.board,
                                             chess.engine.Limit(time=0.2))
                engine_move = engine.play(self.board,
                                          chess.engine.Limit(time=0.1))
                next_move = engine_move.move
                self.board.push(next_move)
                if len(str(next_move)) == 5 and str(next_move)[-1] == 'q':
                    promote_to_Q = True
                if not promote_to_Q:
                    score_after = engine.analyse(self.board,
                                                 chess.engine.Limit(time=0.2))
                    if str(score_after["score"])[0] == '#':
                        moves_mate = int(str(score_after["score"])[2:])
                    else:
                        score_change = (int(str(score_after["score"])) -
                                        int(str(score_prior["score"]))) / 100
            else:
                engine_move = engine.play(self.board,
                                          chess.engine.Limit(time=0.1))
                next_move = engine_move.move
                self.board.push(next_move)

        start_click = str(next_move)[0:2]
        end_click = str(next_move)[2:4]

        if side == 'white':
            start_pos = self.pos_w[start_click]
            end_pos = self.pos_w[end_click]
        else:
            start_pos = self.pos_b[start_click]
            end_pos = self.pos_b[end_click]

        time.sleep(
            self.__wait_time(side, score_change, moves_mate, end_click,
                             promote_to_Q))
        pyautogui.click(start_pos[0], start_pos[1])
        pyautogui.click(end_pos[0], end_pos[1])
        if promote_to_Q:
            pyautogui.click(end_pos[0], end_pos[1])
예제 #5
0
def complexity(board, engine, minDepth=2, maxDepth=16):
    c = 0
    bestMove = engine.analyse(board,
                              chess.engine.Limit(depth=minDepth))["pv"][0]

    for i in range(minDepth + 2, maxDepth + 1, 2):
        analysis = engine.analyse(board,
                                  chess.engine.Limit(depth=i),
                                  multipv=2)
        if analysis[0]["pv"][0] != bestMove:
            bestMove = analysis[0]["pv"][0]
            c += analysis[0]["score"].relative.score(
            ) - analysis[1]["score"].relative.score()

    return c
예제 #6
0
 def cruncher(thread_id: int):
     eval_nb = 0
     db = pymongo.MongoClient()['puzzler']
     bad_coll = db['puzzle2_bad_maybe']
     play_coll = db['puzzle2_puzzle']
     engine = SimpleEngine.popen_uci('./stockfish')
     engine.configure({'Threads': 4})
     for doc in bad_coll.find({"bad": {"$exists": False}}):
         try:
             if ord(doc["_id"][4]) % threads != thread_id:
                 continue
             doc = play_coll.find_one({'_id': doc['_id']})
             if not doc:
                 continue
             puzzle = read(doc)
             board = puzzle.mainline[len(puzzle.mainline) - 2].board()
             info = engine.analyse(
                 board,
                 multipv=5,
                 limit=chess.engine.Limit(nodes=30_000_000))
             bad = False
             for score in [pv["score"].pov(puzzle.pov) for pv in info]:
                 if score < Mate(1) and score > Cp(250):
                     bad = True
             # logger.info(puzzle.id)
             bad_coll.update_one({"_id": puzzle.id},
                                 {"$set": {
                                     "bad": bad
                                 }})
         except Exception as e:
             logger.error(e)
예제 #7
0
    def run(self):
        log_interval = 1
        engine = chess.engine.SimpleEngine.popen_uci(self.engine_path)

        with open(self.pgn_path) as pgn, open(
                os.path.splitext(self.pgn_path)[0] + '-dataset.csv',
                'w',
                newline='') as out:
            outwriter = csv.writer(out)

            gn = 0
            while game := chess.pgn.read_game(pgn):
                gn += 1

                if gn % log_interval == 0:
                    print('\rParsing Game #' + str(gn), end='')

                board = chess.Board()

                for move in game.mainline_moves():
                    board.push(move)
                    fen = board.fen()
                    info = engine.analyse(board, chess.engine.Limit(depth=8))
                    value = info['score'].white().score(mate_score=10000)
                    if board.turn == chess.BLACK:
                        value *= -1
                    value = self.normalize_cp(value)
                    outwriter.writerow([fen, value])
예제 #8
0
def compute_score_a_by_depth(engine, board, depth):
    info = engine.analyse(board, chess.engine.Limit(depth=depth), info=Info.ALL)
    if info.get("score"):
        score = info.get("score").white().score()
    else:
        score = 0
    return score
예제 #9
0
def compute_score_a(engine, board, time):
    info = engine.analyse(board, chess.engine.Limit(time=time), info=Info.ALL)
    if info.get("score"):
        score = info.get("score").white().score()
    else:
        score = 0
    return score
예제 #10
0
def game_analyzer(flat_list = ['rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1']):
    current_fen = []
    player = []
    move = []
    piece = []
    score = []
    mate = []

    for fen in flat_list:
        board = chess.Board(fen)
        for el in board.legal_moves:
            info = engine.analyse(board, chess.engine.Limit(time=.1), root_moves=[el])
            t = str(info["score"])
            price = re.search('-?\d+\.?\d*',t)[0]
            current_fen.append(fen)
            move.append(str(board.san(el)))
            score.append(round(int(price)/100.,2))
            mate.append(str(board.san(el)).endswith('+'))
            if "BLACK" in str(info["score"]):
                player.append("BLACK")
            else:
                player.append("WHITE")
            if len(board.san(el).replace("x","").replace("+","")) == 2:
                piece.append("P")
            else: piece.append(board.san(el).replace("x","").replace("+","")[0].upper())
    # engine.quit()

    df2 = pd.DataFrame({'FEN':current_fen,'Player':player, 'Move':move, 'Score':score, 'Mate':mate})
    return df2
예제 #11
0
def stockfish_info(fen, move, engine, depth, multipv=None):
    board = chess.Board(fen)
    move = [chess.Move.from_uci(move)] if move else None
    return engine.analyse(board,
                          root_moves=move,
                          multipv=multipv,
                          limit=chess.engine.Limit(depth=depth))
예제 #12
0
파일: dataset.py 프로젝트: br0r/brobot
    def parser(row):
        (fen,) = row
        board = chess.Board(fen=fen)
        ev = engine.analyse(board, chess.engine.Limit(depth=depth))
        if not 'pv' in ev:
            return None
        score = ev['score'].white()
        pv = ev['pv'][0].uci()
        if isinstance(score, chess.engine.Mate) or isinstance(score, chess.engine.MateGivenType):
            y = None # Ignore mates
        else:
            y = float(str(score))

        if not y:
            return None

        arr = []
        posx = parsef(board)
        moves = []
        for move in board.legal_moves:
            if pv != move.uci():
                moves.append(move.uci())
        if not moves:
            return None
        mx = parsemove(board, chess.Move.from_uci(pv))
        arr.append(((*posx, mx), 1))
        mx = parsemove(board, chess.Move.from_uci(random.choice(moves)))
        arr.append(((*posx, mx), 0))
        return arr
예제 #13
0
def find_mate(boardFEN):  #Should only be used if mate is possible
    board = chess.Board(boardFEN)
    engine = chess.engine.SimpleEngine.popen_uci(engine_name("stockfish"))
    info = engine.analyse(board, chess.engine.Limit(
        depth=20))  #Limit the possible checkmate found to be under 20 moves

    board_states = []  #List of every board state in FEN notation during mate
    board_states.append(boardFEN)

    game = chess.pgn.Game()
    game.setup(boardFEN)
    x = 0
    if not (info["score"].is_mate()):
        engine.quit()
        return None  #The score given is not a mate, therefore, the function cannot return a mate. Therefore, it returns None
    for i in info["pv"]:  #Loop through every move and add them to the lists
        if x == 0:
            node = game.add_main_variation(
                i)  #If first loop, create the main line found by engine
            x = x + 1
        else:
            node = node.add_main_variation(
                i)  #Add to the main line if not first loop
        board.push(i)
        board_states.append(
            board.fen())  #Add the FEN board state after the move was made
    engine.quit()
    return game
예제 #14
0
def get_raw_analysis(engine, board, analysis_limit):
    """
    Analyze a position with Stockfish.

    :param engine: a SimpleEngine object, probably from load_engine()
    :param board: a python-chess Board object
    :param analysis_limit: a chess.engine.Limit object describing how deeply to read
    :return: raw output from engine analysis: list of dict objects like
    {
        'depth': 14,
        'seldepth': 27,
        'multipv': 1,
        'score': PovScore(Cp(-20), WHITE),
        'nodes': 3702548,
        'nps': 1161765,
        'tbhits': 0,
        'time': 3.187,
        'pv': [Move.from_uci('b1c3'), ... Move.from_uci('g1f1')]
    }

    Note: analysis limit can be in seconds:
        chess.engine.Limit(time=3)
    or in search depth:
        chess.engine.Limit(depth=14)
    """

    # Run analysis for all possible variations
    info = engine.analyse(board, analysis_limit, multipv=500)
    return info
def get_optimality_scores(board, engine):

    # Dict with results
    scores = {}

    # Get scores for given board
    for el in board.legal_moves:
        score_info = engine.analyse(board,
                                    chess.engine.Limit(time=.01),
                                    root_moves=[el])["score"]

        # Calculate score
        score = 0.0
        if (board.turn):
            score = score_info.white().score(mate_score=1000000)
            if (score_info.white().is_mate()):
                score -= score_info.white().mate() * 100
        else:
            score = score_info.black().score(mate_score=1000000)
            if (score_info.black().is_mate()):
                score -= score_info.black().mate() * 100
        score = round(score / 100, 2)

        # Store in dict
        scores[el] = score

    # Return scores
    return scores
예제 #16
0
 def pick_move(root):
     '''
     root is a MoveNode
     Pick a move that is best to play for self.player
     '''
     # Two cases:
     # Either the "root" is a leaf, i.e depth = 0
     if root.depth == 0:
         # Here there is no decision to make, just return the move and the engine's evaluation
         score = engine.analyse(
             root.board, chess.engine.Limit(time=ANALYSIS_TIME))["score"]
         return (score, root)
     else:
         # The "root" is somewhere else in the tree, in which case it will choose the best child.
         # resolve all the children, and take the best move
         opt_child = root.children[
             0]  # know it has kids because depth is non-0
         opt_score = MoveSelector.pick_move(opt_child)[0]
         for i in range(1, len(root.children)):
             child = root.children[i]
             result = MoveSelector.pick_move(child)
             if MoveSelector.compare_scores(result[0], opt_score,
                                            root.player):
                 opt_score = result[0]
                 opt_child = result[1]
         return (opt_score, opt_child)
예제 #17
0
def main():
    train_data = []
    for x in range(num_games):
        print("Starting game:" + str(x))
        board = chess.Board()
        while not board.is_game_over() and board.fullmove_number < 20:
            legal_moves = board.legal_moves
            data = []
            if board.turn == chess.BLACK:
                for move in legal_moves:
                    board.push(move)
                    # Estimate moves
                    info = engine.analyse(
                        board, chess.engine.Limit(time=0.0100, depth=6))
                    board.pop()
                    data.append((move, str(info["score"])))
                train_data.append(([to_X(board)], to_Y(data)))

            # Make best move
            result = engine.play(board, chess.engine.Limit(time=0.100))
            board.push(result.move)
            # Make random move
            # board.push(random.choice(data)[0])
        if (x + 1) % 96 == 0:
            train_data_formatted = split_data(train_data)
            model.fit([train_data_formatted[0]], [train_data_formatted[1]],
                      epochs=1050,
                      batch_size=32,
                      callbacks=callbacks,
                      verbose=2)
            train_data = []
            model.save("checkpoints/" + model_name +
                       datetime.now().strftime("D%d-H%H-M%M") + ".h5")
            model.save("models/" + model_name + ".h5")
    engine.quit()
예제 #18
0
def AI_move():
    """
    #get move from AI
    board.export_fen()
    """
    #move = random.choice(board.get_valid_moves())
    print(board.export_fen())
    chess_board = chess.Board(board.export_fen())
    print(chess.Board())
    print(chess_board)
    try:
        move = board.move_from_san(
            engine.analyse(chess_board, chess.engine.Limit(time=.1))["pv"][0])
    except:
        # while this block can definitely be reached on not moving the king out of danger,
        # there may be other, unintended ways to get here that I do not fully understand
        print("stupid move")
        return board.to_play

    #move = AI_board.search()[0]
    if move[2] == 6:
        print("King captured")
        return board.to_play
    else:
        won = None
    AI_board.make_move(move)
    board.make_move(move)
    AI_board.evaluate()
예제 #19
0
def getEngineEval():
    if token.validate_token(request.args.get('token', False)):
        __location__ = os.path.realpath(
            os.path.join(os.getcwd(), os.path.dirname(__file__)))
        __filename__ = 'stockfish-prod' if os.environ.get(
            "Production", False) else 'stockfish-dev'

        # Assign game Position
        with chess.engine.SimpleEngine.popen_uci(
                os.path.join(__location__, __filename__)) as engine:
            try:
                fen_notation = request.args.get('fen_notation', "")
                board = chess.Board(fen_notation)
            except ValueError:
                return jsonify({
                    "fen_notation_error":
                    "Please supply a valid fen notation",
                })
            strength = request.args.get('strength', 1)
            time = min(1, 0.01 * 10**int(strength))
            res = engine.play(board, chess.engine.Limit(time=time, depth=20))
            info = engine.analyse(board, chess.engine.Limit(time=time,
                                                            depth=20))

            engine.close()

            return jsonify({
                "best_move": str(res.move),
                "ponder": str(res.ponder),
                "evaluation": str(info["score"].white()),
            })
    return jsonify({
        "access_token_error":
        "There seems to be a problem with your access token",
    })
예제 #20
0
def make_move():
    # extract FEN string from HTTP POST request body
    fen = request.form.get('fen')

    # init python chess board instance
    board = chess.Board(fen)

    # search for best move
    info = engine.analyse(board, chess.engine.Limit(time=0.1))

    # extract best move from PV
    best_move = info['pv'][0]

    # update internal python chess board state
    board.push(best_move)

    # extract FEN from current board state
    fen = board.fen()

    return {
        'fen': fen,
        'best_move': str(best_move),
        'score': str(info['score']),
        'pv': ' '.join([str(move) for move in info['pv']]),
        'nodes': info['nodes'],
        'time': info['time']
    }
예제 #21
0
    def get(self):
        ret_dict = {}
        parser = reqparse.RequestParser()
        parser.add_argument('fen', type=str)
        parser.add_argument('svg', type=str)
        args = parser.parse_args()

        engine = chess.engine.SimpleEngine.popen_uci(stockfish_path)

        board = chess.Board(fen=args['fen'])
        info = engine.analyse(board, chess.engine.Limit(time=0.100))

        next_move_limit = chess.engine.Limit(time=2.0)
        next_move = engine.play(board, next_move_limit)

        engine.quit()
        ret_dict = {
            'current_score': str(info["score"]),
            'next_move_suggestion': str(next_move.move),
            'next_move_suggestions': str(next_move.info),
            'board_before': str(board),
        }

        if ('svg' in args and args['svg'] == '1'):
            ret_dict['svg'] = chess.svg.board(board=board,
                                              lastmove=next_move.move)

        return ret_dict
예제 #22
0
 def cruncher(thread_id: int):
     eval_nb = 0
     build_coll = pymongo.MongoClient()['puzzler']['puzzle2']
     engine = SimpleEngine.popen_uci('./stockfish')
     engine.configure({'Threads': 4})
     engine_limit = chess.engine.Limit(depth=30,
                                       time=15,
                                       nodes=12_000_000)
     for doc in build_coll.find({"cp": None}):
         try:
             if ord(doc["_id"][4]) % threads != thread_id:
                 continue
             puzzle = read(doc)
             board = puzzle.game.end().board()
             if board.is_checkmate():
                 cp = 999999999
                 eval_nb += 1
                 logger.info(f'{thread_id} {eval_nb} {puzzle.id}: mate')
             else:
                 info = engine.analyse(board, limit=engine_limit)
                 score = info["score"].pov(puzzle.pov)
                 score_cp = score.score()
                 cp = 999999999 if score.is_mate() else (
                     999999998 if score_cp is None else score_cp)
                 eval_nb += 1
                 logger.info(
                     f'{thread_id} {eval_nb} {puzzle.id}: {cp} knps: {int(info["nps"] / 1000)} kn: {int(info["nodes"] / 1000)} depth: {info["depth"]} time: {info["time"]}'
                 )
             build_coll.update_one({"_id": puzzle.id},
                                   {"$set": {
                                       "cp": cp
                                   }})
         except Exception as e:
             print(doc)
             logger.error(e)
예제 #23
0
def make_move():
    # extract FEN string from HTTP POST request body
    fen = request.form.get('fen')

    # extract fixed depth value
    fixed_depth = request.form.get('fixed_depth')

    # extract move time value
    move_time = request.form.get('move_time')

    # init python chess board instance
    board = chess.Board(fen)

    # if move time is available
    if move_time != '0':
        if move_time == 'instant':
            # search for best move instantly
            info = engine.analyse(board, chess.engine.Limit(time=0.1))
        else:
            # search for best move with fixed move time
            info = engine.analyse(board,
                                  chess.engine.Limit(time=int(move_time)))

    # if fixed depth is available
    if fixed_depth != '0':
        # search for best move instantly
        info = engine.analyse(board,
                              chess.engine.Limit(depth=int(fixed_depth)))

    # extract best move from PV
    best_move = info['pv'][0]

    # update internal python chess board state
    board.push(best_move)

    # extract FEN from current board state
    fen = board.fen()

    return {
        'fen': fen,
        'best_move': str(best_move),
        'score': str(info['score']),
        'depth': info['depth'],
        'pv': ' '.join([str(move) for move in info['pv']]),
        'nodes': info['nodes'],
        'time': info['time']
    }
예제 #24
0
파일: processor.py 프로젝트: mikhas/cheviz
    def run(self,
            reduced: Callable,
            square_filter: Callable,
            echo: int = 1,
            depth: int = 20) -> pd.DataFrame:
        engine = self.engine_maker()
        result = pd.DataFrame(columns=[
            'SideThatMoved', 'SideToMove', 'Score', 'PovScore',
            'HalfMoveConfiguration', 'FEN', 'LastWhiteMove', 'LastBlackMove',
            'ViewForWhite', 'ViewForBlack', 'Zeros', 'ZerosWithEcho'
        ])

        for curr_move in range(0, len(self.moves)):
            bm_offset = (curr_move + 1) % 2
            adjusted_wm = (curr_move // 2) * 2
            adjusted_bm = curr_move - bm_offset

            side = bool(
                bm_offset)  # white: 1, black: 0, same as in python-chess
            if not self.first_move_by_white:
                adjusted_wm, adjusted_bm = adjusted_bm, adjusted_wm  # not tested!

            last_white_move = self.moves[adjusted_wm]
            last_black_move = self.moves[
                adjusted_bm] if adjusted_bm > -1 else None

            white = self.msw(range(adjusted_wm - (echo * 2), adjusted_wm + 1),
                             chess.WHITE, square_filter)
            black = self.msb(range(adjusted_bm - (echo * 2), adjusted_bm + 1),
                             chess.BLACK, square_filter)
            zeros_white = reduced(
                self.msz(range(curr_move, curr_move + 1), chess.WHITE,
                         square_filter).result)
            zeros_black = reduced(
                self.msz(range(curr_move, curr_move + 1), chess.BLACK,
                         square_filter).result)

            reduced_white = reduced(white.result)
            reduced_black = reduced(black.result)

            # would be nice if engine.analyse could be made to run async/in parallel
            current_board = white.board if side else black.board
            score = engine.analyse(current_board,
                                   chess.engine.Limit(depth=depth))['score']

            result.loc[curr_move] = [
                'White' if side else 'Black', 'Black' if side else 'White',
                int(score.pov(chess.WHITE).__str__()),
                int(score.pov(score.turn).__str__()),
                (curr_move, adjusted_wm, adjusted_bm),
                current_board.fen(), last_white_move, last_black_move,
                reduced_white, reduced_black,
                cda.countZeros(np.logical_or(zeros_white, zeros_black)),
                cda.countZeros(np.logical_or(reduced_white, reduced_black))
            ]

        engine.quit(
        )  # This is important, otherwise we leak opened file objects!
        return result
예제 #25
0
def stockfish(board, pov):
    scores = [
        engine.analyse(board, chess.engine.Limit(
            depth=d))["score"].pov(pov).score(mate_score=10000)
        for d in (5, 10, 15)
    ]

    return sum(a * b for a, b in zip(scores, (3, 2, 1)))
예제 #26
0
def evalBoard(board):
    global count
    print(count)
    count += 1
    k = engine.analyse(
        board, chess.engine.Limit(time=0.05))['score'].relative.__str__()
    print(k)
    return k
예제 #27
0
def compute_best_move_score(engine, board, move, time):
    board.push(move)
    info = engine.analyse(board=board, limit=chess.engine.Limit(time=time), info=Info.ALL)
    board.pop()
    score = info.get('score').white().score()
    if score is None:
        score = 0
    return score
예제 #28
0
def get_engine_moves(fen, engine):
    engine_moves = []
    board = chess.Board(fen)
    info = engine.analyse(board, chess.engine.Limit(depth=15), multipv=3)

    for i in range(len(info)):
        engine_moves.append(board.san(info[i]['pv'][0]))
    return engine_moves
예제 #29
0
def evalBoard(board):
    global count
    print(count)
    count += 1
    k = engine.analyse(
        board, chess.engine.Limit(time=0.1))['score'].relative.__str__()
    k = replaceForcedMate(k)
    return k
예제 #30
0
def analyse_position(eval_cursor, eval_board, root_moves=None, extended=False):
    """
    Commit analysis to DB.
    Can confine to given root moves,
    or search for new moves with extended=True
    """
    if root_moves:
        time_limit = chess.engine.Limit(time=min(5, max(2, len(root_moves))))
        lines = engine.analyse(eval_board,
                               time_limit,
                               root_moves=root_moves,
                               multipv=len(root_moves))
    else:
        if extended:
            taken_ucis = list(
                map(lambda m: m['uci'],
                    eval_cursor['theory'] + eval_cursor['moves']))
            scout_lines = engine.analyse(eval_board,
                                         chess.engine.Limit(time=0.3),
                                         multipv=len(taken_ucis) + 3)
            scouted_moves = list(map(lambda line: line['pv'][0], scout_lines))
            new_moves = [m for m in scouted_moves if m.uci() not in taken_ucis]
            lines = engine.analyse(eval_board,
                                   chess.engine.Limit(time=3),
                                   root_moves=new_moves,
                                   multipv=len(new_moves))
        else:
            lines = engine.analyse(eval_board,
                                   chess.engine.Limit(time=2),
                                   multipv=3)

    uci_score_dict = {
        line['pv'][0].uci(): line['score'].relative.score(mate_score=100000)
        for line in lines
    }
    print(uci_score_dict)
    if any([v is None for v in uci_score_dict.values()]):
        print('Somehow, some score is None')
        print(uci_score_dict)
        print(lines)
    if eval_cursor['score'] is None:
        print('will crash now')
        print(eval_cursor)
        print(eval_board.move_stack)
    set_position_moves_scores(eval_cursor, uci_score_dict)