3

我想从我从文本文件中读取的游戏(使用 python-chess 库)中顺序打印移动(每次移动一个字符串)。

所以,假设我有一个包含以下动作的游戏的 pgn 文件......

1. f3 e5 2. g4 Qh4#

...我想遍历这些动作并一一打印(使用 for 循环或类似方法),显示

f3

e5

g4

Qh4

我在这里找到了 python-chess 的文档: https ://python-chess.readthedocs.io/en/latest/

从文档中我了解到

  1. 我需要创建一个访问者的实例,它可以使用接受方法按 PGN 顺序遍历游戏节点
  2. san methon 会给我导致当前节点的移动的字符串

但是我发现这种文档很难阅读,并且可以通过示例得到很大帮助。

我设法做的是从 pgn 文件中读取游戏并使用变体方法一次性打印所有动作(而不是一个一个)。

import chess.pgn

pgn = open('I:\myfile.pgn')
my_game = chess.pgn.read_game(pgn)

print(my_game.variation(0))
4

1 回答 1

2

迭代主线动作

的文档chess.pgn.read_game()有一个迭代移动的示例。要将移动转换回标准代数符号,上下文需要位置,因此我们另外在 a 上进行所有移动board

import chess.pgn

pgn = open("test.pgn")
game = chess.pgn.read_game(pgn)

board = game.board()

for move in game.mainline_moves():
    print(board.san(move))
    board.push(move)

访客

上面的例子将整个游戏解析成一个数据结构(game: chess.pgn.Game)。访问者允许跳过该中间表示,这对于使用自定义数据结构或作为优化可能很有用。但这在这里似乎有点过分了。

尽管如此,为了完整性:

import chess.pgn

class PrintMovesVisitor(chess.pgn.BaseVisitor):
    def visit_move(self, board, move):
        print(board.san(move))

    def result(self):
        return None

pgn = open("test.pgn")
result = chess.pgn.read_game(pgn, Visitor=PrintMovesVisitor)

请注意,这也会以 PGN 顺序遍历侧面变化

于 2020-08-21T09:19:33.807 回答