Printing individual moves with the python-chess library

Tags: , ,



I want to sequentially print the moves (one string per move at a time) from a game I read (using the python-chess library) from a text file.

So, say I have a pgn file with a game that has the following moves…

1. f3 e5 2. g4 Qh4#

… I would like to iterate through the moves and print them one by one (using a for loop or similar), showing

f3

e5

g4

Qh4

I found the documentation for python-chess here: https://python-chess.readthedocs.io/en/latest/

From the documentation I understand that

  1. I would need to create an instance of a visitor that can traverse the game nodes in PGN order using the accept method
  2. that the san methon would give me the string for the move that led to the current node

But I find this kind of documentation hard to read and would be greatly helped with examples.

What I managed to do is read a game from a pgn file and print all the moves in one go (as opposed to one by one) using the variation method.

import chess.pgn

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

print(my_game.variation(0))

Answer

Iterating over mainline moves

The documentation for chess.pgn.read_game() has an example for iterating over moves. To convert the moves back to standard algebraic notation, the position is needed for context, so we additionally make all the moves on 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)

Visitors

The above example parses the entire game into a data structure (game: chess.pgn.Game). Visitors allow skipping that intermediate representation, which can be useful to use a custom data structure instead, or as an optimization. But that seems overkill here.

Nonetheless, for completeness:

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)

Note that this also traverses side variations in PGN order.



Source: stackoverflow