Impressão de movimentos individuais com a biblioteca python-chess

Aug 21 2020

Quero imprimir sequencialmente os movimentos (uma string por movimento por vez) de um jogo que li (usando a biblioteca de xadrez python) de um arquivo de texto.

Então, digamos que eu tenha um arquivo pgn com um jogo que tem os seguintes movimentos ...

1. f3 e5 2. g4 Qh4 #

... Eu gostaria de iterar os movimentos e imprimi-los um por um (usando um loop for ou semelhante), mostrando

f3

e5

g4

Qh4

Encontrei a documentação para python-chess aqui: https://python-chess.readthedocs.io/en/latest/

Pela documentação eu entendo que

  1. Eu precisaria criar uma instância de um visitante que pudesse atravessar os nós do jogo em ordem PGN usando o método de aceitação
  2. que o san methon me daria a string para o movimento que levou ao nó atual

Mas acho esse tipo de documentação difícil de ler e seria muito ajudado com exemplos.

O que consegui fazer é ler um jogo de um arquivo pgn e imprimir todos os movimentos de uma vez (em oposição a um por um) usando o método de variação.

import chess.pgn

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

print(my_game.variation(0))

Respostas

1 Niklas Aug 21 2020 at 09:19

Iterando sobre movimentos da linha principal

A documentação de chess.pgn.read_game()tem um exemplo para iteração de movimentos. Para converter os movimentos de volta para a notação algébrica padrão, a posição é necessária para o contexto, portanto, adicionalmente fazemos todos os movimentos em 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)

Visitantes

O exemplo acima analisa todo o jogo em uma estrutura de dados ( game: chess.pgn.Game). Os visitantes permitem pular essa representação intermediária, o que pode ser útil para usar uma estrutura de dados customizada ou como uma otimização. Mas isso parece exagero aqui.

No entanto, para integridade:

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)

Observe que isso também atravessa variações laterais na ordem PGN.