Imprimir movimientos individuales con la biblioteca python-chess
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
- 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
- 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
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.