如何用chess.engine.SimpleEngine实现类似Stockfish的get_top_moves(5)功能?
解决python-chess SimpleEngine异步分析无法同步调用的问题
要实现类似Stockfish的get_top_moves(5)功能,核心是将SimpleEngine.analysis的异步调用转为同步执行,以下是具体实现方案:
方案:用asyncio.run封装异步分析逻辑
直接通过asyncio.run将异步的分析代码包裹在同步函数中,无需修改现有同步代码结构:
实现代码
import asyncio import chess import chess.engine def get_top_moves(engine, board, num_moves=5, depth=18, root_moves=None): async def _async_collect_moves(): move_evaluations = {} # 异步遍历引擎分析输出 async for info in engine.analysis( board, chess.engine.Limit(depth=depth), multipv=num_moves, root_moves=root_moves ): # 提取multipv对应的走法和评估分数 if "score" in info and "pv" in info: score = info["score"].relative # 遍历每一条候选线路,取第一步作为候选走法 for idx, pv_line in enumerate(info["pv"], start=1): if idx > num_moves: break move = pv_line move_evaluations[move] = score # 根据当前方排序:白方取分数高的,黑方取分数低的 sort_key = lambda item: item[1] reverse = board.turn == chess.WHITE sorted_moves = sorted(move_evaluations.items(), key=sort_key, reverse=reverse) # 返回前num_moves个结果,格式可按需调整 return [ {"move": move.uci(), "score": score.score()} for move, score in sorted_moves[:num_moves] ] # 同步执行异步函数 return asyncio.run(_async_collect_moves())
使用示例
# 初始化Stockfish引擎(替换为你的引擎路径) engine = chess.engine.SimpleEngine.popen_uci("/usr/bin/stockfish") # 初始化棋盘 board = chess.Board() # 获取前5个最佳走法 top_moves = get_top_moves(engine, board, num_moves=5, depth=18) # 打印结果 for i, move_data in enumerate(top_moves, 1): print(f"第{i}位走法: {move_data['move']}, 评估分: {move_data['score']}") # 关闭引擎 engine.quit()
关键说明
multipv=num_moves参数让引擎返回指定数量的候选走法- 评估分数使用
relative属性,确保分数是相对于当前走子方的(白方正分优,黑方负分优) - 排序逻辑根据当前走子方调整,保证返回的是对当前方最优的顺序
- 如果传入
root_moves,需确保是合法的chess.Move对象列表
内容的提问来源于stack exchange,提问作者Giovanni Grotto
相关产品推荐
相关产品推荐

