Imprimir movimientos individuales con la biblioteca python-chess

Aug 21 2020

Quiero imprimir secuencialmente los movimientos (una cadena por movimiento a la vez) de un juego que leo (usando la biblioteca python-chess) desde un archivo de texto.

Entonces, digamos que tengo un archivo pgn con un juego que tiene los siguientes movimientos ...

1. f3 e5 2. g4 Dh4 #

... Me gustaría iterar a través de los movimientos e imprimirlos uno por uno (usando un bucle for o similar), mostrando

f3

e5

g4

Dh4

Encontré la documentación para python-chess aquí: https://python-chess.readthedocs.io/en/latest/

De la documentación entiendo que

  1. Necesitaría crear una instancia de un visitante que pueda atravesar los nodos del juego en orden PGN usando el método de aceptación
  2. que el san methon me daría la cadena para el movimiento que condujo al nodo actual

Pero encuentro este tipo de documentación difícil de leer y sería de gran ayuda con ejemplos.

Lo que logré hacer fue leer un juego de un archivo pgn e imprimir todos los movimientos de una sola vez (en lugar de uno por uno) usando el método de variación.

import chess.pgn

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

print(my_game.variation(0))

Respuestas

1 Niklas Aug 21 2020 at 09:19

Iterando sobre los movimientos de la línea principal

La documentación de chess.pgn.read_game()tiene un ejemplo para iterar sobre movimientos. Para volver a convertir los movimientos a la notación algebraica estándar, la posición es necesaria para el contexto, por lo que también hacemos todos los movimientos en 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

El ejemplo anterior analiza todo el juego en una estructura de datos ( game: chess.pgn.Game). Los visitantes permiten omitir esa representación intermedia, que puede ser útil para usar una estructura de datos personalizada en su lugar, o como una optimización. Pero eso parece exagerado aquí.

No obstante, para completar:

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)

Tenga en cuenta que esto también atraviesa variaciones laterales en el orden PGN.