如何使用python-chess库对mainline进行切片并打印指定范围棋谱?
python-chess 库的棋局主线(mainline)本身是可迭代序列,原生不直接支持列表风格的切片操作,我们可以通过将其转换为着法列表后二次处理,就能实现你要的切片导出需求。
完整实现步骤
- 先加载你的棋谱数据,获取mainline着法列表
import io import chess import chess.pgn # 加载示例西西里防御棋谱 pgn_content = "1. e4 c5 2. b4 cxb4 3. d4 d5 4. e5 Nc6 5. a3 Qb6 6. Ne2 Bf5 7. axb4 Nxb4 8. Na3 Rc8 9. Nf4 Bxc2 10. Qg4 e6 *" game = chess.pgn.read_game(io.StringIO(pgn_content)) # 将mainline转换为着法列表,每个元素对应一步单方着法(半回合) move_list = list(game.mainline())
- 封装切片导出函数,支持类列表的
[start:stop:step]用法
def export_moves_slice(move_list, start=0, stop=None, step=1): """ 对着法列表做切片,导出为标准PGN棋谱字符串 :param start: 切片起始索引(从0开始,对应第一步白方着法e4) :param stop: 切片终止索引,不包含该位置的着法 :param step: 切片步长 """ # 取切片后的着法 sliced = move_list[start:stop:step] # 生成临时棋局导出棋谱 temp_game = chess.pgn.Game() current_node = temp_game for move in sliced: current_node = current_node.add_variation(move) # 导出时不包含额外头部、变例、注释 exporter = chess.pgn.StringExporter(headers=False, variations=False, comments=False) return temp_game.accept(exporter).strip()
- 封装到指定白方步数截止的导出函数
def export_until_white_step(move_list, white_step_num): """ 导出到指定白方步数截止的棋谱 :param white_step_num: 白方第N步,比如传3就是到白方第3步d4截止 """ # 白方第n步对应的索引是 2*(n-1),取到下一个索引前即可 stop_index = 2 * (white_step_num - 1) + 1 return export_moves_slice(move_list, stop=stop_index)
效果测试
测试1:获取1到5回合的完整棋谱(对应你要的main_sicilian[1:5]效果)
print(export_moves_slice(move_list, stop=10)) # 输出:1. e4 c5 2. b4 cxb4 3. d4 d5 4. e5 Nc6 5. a3 Qb6
注:5个完整回合共10步单方着法,所以stop参数传10即可。
测试2:获取到白方第3步截止的棋谱
print(export_until_white_step(move_list, 3)) # 输出:1. e4 c5 2. b4 cxb4 3. d4
进阶说明
如果你想要完全实现main_sicilian[start:stop:step]的直接切片语法,可以自定义类继承原生的Mainline类,重写__getitem__方法调用上面的导出逻辑即可,对于初学者来说上述函数已经可以覆盖绝大多数使用场景。
内容的提问来源于stack exchange,提问作者mykahveli
相关产品推荐
相关产品推荐

