Python 国际象棋程序中的“断言错误:san() 和 lan() 期望移动合法或为空”

问题描述 投票:0回答:1
import chess
import chess.pgn
import chess.engine
import tkinter as tk
from tkinter import simpledialog
import os
from tqdm import tqdm

# Function to get FEN position from a popup window
def get_fen_position():
    root = tk.Tk()
    root.withdraw()
    fen_position = simpledialog.askstring("Input", "Paste the FEN position:")
    root.destroy()
    return fen_position

# Function to evaluate position using Stockfish
def evaluate_position(board, engine, depth_white=17, depth_black=6, multipv=3):
    if board.turn == chess.WHITE:
        result = engine.analyse(board, chess.engine.Limit(depth=depth_white))
        move = result['pv'][0]
        board.push(move)
    else:
        infos = engine.analyse(board, chess.engine.Limit(depth=depth_black), multipv=multipv)
        moves = [info['pv'][0] for info in infos if 'pv' in info]
        for move in moves:
            board.push(move)
            response = engine.analyse(board, chess.engine.Limit(depth=depth_white))
            board.pop()
    return board

# Function to recursively evaluate and write moves to PGN
def recursive_evaluation(board, engine, node, depth=1, max_depth=8, pbar=None):
    if depth > max_depth:
        return

    board = evaluate_position(board, engine)
    
    if board.turn == chess.BLACK:
        infos = engine.analyse(board, chess.engine.Limit(depth=6), multipv=3)
        for info in infos:
            if 'pv' not in info:
                continue
            new_board = board.copy()
            move = info['pv'][0]
            new_board.push(move)
            new_node = node.add_variation(move)
            recursive_evaluation(new_board, engine, new_node, depth + 1, max_depth, pbar)
    else:
        move = board.peek()
        new_node = node.add_variation(move)
        recursive_evaluation(board, engine, new_node, depth + 1, max_depth, pbar)
    
    if pbar:
        pbar.update(1)

# Main function to run the script
def main():
    # Path to Stockfish executable
    stockfish_path = 'C:/Users/Admintrator/Downloads/stockfish-windows-x86-64-avx2/stockfish/stockfish-windows-x86-64-avx2.exe'

    # Path to the existing PGN file
    pgn_path = "C:/Users/Admintrator/OneDrive - Nguyen Sieu School/Documents/EnCroissant/Nhị Cuộc Phi Đao.pgn"

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

    # Set Stockfish options for threads and hash size
    engine.configure({"Threads": 16, "Hash": 8192})

    # Get FEN position from user
    fen = get_fen_position()

    # Load the existing PGN file
    with open(pgn_path, "r", encoding="utf-8") as pgn:
        game = chess.pgn.read_game(pgn)

    # Set up the board with the given FEN position
    board = chess.Board(fen)
    node = game.end()

    # Initialize progress bar
    max_depth = 8
    total_steps = sum(3**i for i in range(max_depth))  # Total steps for progress bar
    with tqdm(total=total_steps, desc="Evaluating Position") as pbar:
        # Evaluate position and add moves to PGN
        recursive_evaluation(board, engine, node, max_depth=max_depth, pbar=pbar)

    # Write the updated game to the PGN file
    with open("evaluated_game.pgn", "w", encoding="utf-8") as pgn_out:
        exporter = chess.pgn.FileExporter(pgn_out)
        game.accept(exporter)
    
    # Close engine
    engine.quit()

if __name__ == "__main__":
    main()

我想制作一个工具,使用 stockfish 自动继续评估 .PGN 文件中的某个位置。不知何故,它跑了 3/4,并说:

Traceback (most recent call last):
  File "C:\Users\Admintrator\Downloads\FEN continue.py", line 98, in <module>
    main()
  File "C:\Users\Admintrator\Downloads\FEN continue.py", line 92, in main
    game.accept(exporter)
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\pgn.py", line 883, in accept
    self.variations[0]._accept(board, visitor)
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\pgn.py", line 756, in _accept
    top.node._accept_node(parent_board, visitor)
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\pgn.py", line 733, in _accept_node
    visitor.visit_move(parent_board, self.move)
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\pgn.py", line 1403, in visit_move
    self.write_token(board.san(move) + " ")
                     ^^^^^^^^^^^^^^^
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\__init__.py", line 2866, in san
    return self._algebraic(move)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\__init__.py", line 2879, in _algebraic
    san = self._algebraic_and_push(move, long=long)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\__init__.py", line 2884, in _algebraic_and_push
    san = self._algebraic_without_suffix(move, long=long)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Admintrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\chess\__init__.py", line 2920, in _algebraic_without_suffix
    assert piece_type, f"san() and lan() expect move to be legal or null, but got {move} in {self.fen()}"
AssertionError: san() and lan() expect move to be legal or null, but got f8b8 in r6K/p1pbqppp/2nP3n/bP6/2B1P3/1Qp2N2/P4PPP/RNB2RK1 b - - 0 11

我不知道要修复什么,尝试使用 ChatGPT 但仍然无法让它工作。经历了 Stackoverflow 上的每一个相同的错误,但仍然无法修复它。

chess python-chess stockfish
1个回答
0
投票

f8 上没有棋子为黑色,因此不能将任何棋子从该方格移动到 b8。请参考Lichess分中的位置。您看到的错误是由于“移动”不合法造成的。

© www.soinside.com 2019 - 2024. All rights reserved.