Open In App

Extract Data from PGN Files Using the Chess Library in Python

Last Updated : 28 Mar, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we are going to see how to extract data from PGN Files using the chess library in Python.

With the help of the chess library in python, we can perform several operations like validating a move, extracting data, and even making moves on the chessboard. In this article, we will extract data from a PGN file or a PGN string using the python-chess library.

Installing the library: Enter the following command in the command prompt.

pip install chess

What are PGN files?

PGN stands for Portable Game Notation. It is the standard format used to record the moves played by the players in a chess game. By using the PGN format, we can record and store the game moves in a regular text file. 

Whenever we play chess online on popular websites like https://chess.com or https://lichess.org, these websites automatically generate the PGN files of our games. We can use these files to watch and analyze our games in the future. We will use these PGN files in order to extract data from our chess games using the chess library in Python.

Let us take a look at the contents of a PGN file in order to understand the contents of the file.

[Event "Live Chess"]
[Site "Chess.com"]  
[Date "2021.08.05"] 
[Round "-"]
[White "urvishmhjn"]
[Black "yannickhs"]
[Result "1-0"]
[CurrentPosition "r1b1q1r1/p2nbk2/4pp1Q/1p1p3B/2pP3N/1PP1P3/P4PPP/R4RK1 b - -"]
[Timezone "UTC"]
[ECO "A45"]
[UTCDate "2021.08.05"]
[UTCTime "09:25:32"]
[WhiteElo "1220"]
[BlackElo "1140"]
[TimeControl "900+10"]
[Termination "urvishmhjn won by resignation"]

1. d4 Nf6 2. Bf4 e6 3. e3 d5 4. Bd3 c5 5. c3 c4 6. Be2 Nc6 
7. Nf3 Be7 8. Nbd2 O-O 9. O-O Nh5 10. Be5 Nxe5 11. Nxe5 Nf6 
12. b3 b5 13. Qc2 Nd7 14. Ndf3 f6 15. Ng4 h5 16. Nh6+ gxh6 
17. Qg6+ Kh8 18. Qxh6+ Kg8 19. Qxh5 Qe8 20. Qg4+ Kf7 
21. Nh4 Rg8 22. Qh5+ Kf8 23. Qh6+ Kf7 24. Bh5+ 1-0 

In the above file, we can see that some of the text is written inside square brackets. These square brackets are called tag pairs. The content inside a tag pair gives us basic information about the game and the players playing it. For example, tag pairs tell us the username of each player, the date on which the game was played, the time format of the game, which player won the game, etc. 

We can also see the text without square brackets. This text represents the moves played by each player. The numbers 1., 2., 3., etc. denote the move numbers. The text d4, Nf6, Bh+, etc. is the standard way of denoting the movement of a piece on the chessboard. Text 1-0  written at the end of the file denotes that white has won the game. 0-1 means that black has won, and 1/2-1/2 means that the game was a draw. 

Implementation

Now that we understand what PGN files are, we will import the chess library and call the Board() function to create a virtual chessboard.

We will also need to import chess.pgn to perform operations on the pgn file/string.

Python3




import chess
import chess.pgn
  
# creating a virtual chessboard
board = chess.Board()
  
print(board)


Output:

r n b q k b n r
p p p p p p p p
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
P P P P P P P P
R N B Q K B N R

If you have a .pgn file from which you want to extract data, use the following code. If you play chess on the above-mentioned websites, you can download the PGN files of your games from those websites.

pgn = open(“your-pgn-file.pgn”)  # opening the file in python

game = chess.pgn.read_game(pgn)  # reading the game present in file

If you have a string that contains the pgn file’s data, you will need to convert the string into a StringIO object because the chess library only supports the StringIO objects. You can use the following code.

Python3




# We need to convert the PGN string into a StringIO object
# to use a string in python-chess
from io import StringIO
  
# Paste your PGN string here
pgn_string = """[Event "Live Chess"]
[Site "Chess.com"]  
[Date "2021.08.05"] 
[Round "-"]
[White "urvishmhjn"]
[Black "yannickhs"]
[Result "1-0"]
[CurrentPosition "r1b1q1r1/p2nbk2/4pp1Q/1p1p3B/2pP3N/1PP1P3/P4PPP/R4RK1 b - -"]
[Timezone "UTC"]
[ECO "A45"]
[UTCDate "2021.08.05"]
[UTCTime "09:25:32"]
[WhiteElo "1220"]
[BlackElo "1140"]
[TimeControl "900+10"]
[Termination "urvishmhjn won by resignation"]
  
1. d4 Nf6 2. Bf4 e6 3. e3 d5 4. Bd3 c5 5. c3 c4 6. Be2 Nc6 
7. Nf3 Be7 8. Nbd2 O-O 9. O-O Nh5 10. Be5 Nxe5 11. Nxe5 Nf6 
12. b3 b5 13. Qc2 Nd7 14. Ndf3 f6 15. Ng4 h5 16. Nh6+ gxh6 
17. Qg6+ Kh8 18. Qxh6+ Kg8 19. Qxh5 Qe8 20. Qg4+ Kf7 
21. Nh4 Rg8 22. Qh5+ Kf8 23. Qh6+ Kf7 24. Bh5+ 1-0 
"""
  
# Converting the string into StringIO object
pgn = StringIO(pgn_string)
  
# Reading the game
game = chess.pgn.read_game(pgn)


We have defined a variable called game. It contains information about the entire game.

Let’s now find out some of the details of the game.

Python3




# username of the player playing with white
white_username = game.headers['White']
  
# username of the player playing with black
black_username = game.headers['Black']
time_control = game.headers['TimeControl'
  
# time format of the game
# who won the game
game_result = game.headers['Result']  
  
# Make sure that each header name
# used above is present in the PGN
print("White's chess.com Username:", white_username)
print("Black's chess.com Username:", black_username)
print("Game's Time Control:", time_control, "seconds")
print("Game Result:", game_result)
  
# If white wins: 1-0
# If black wins: 0-1
# If game drawn: 1/2-1/2


Output:

White's chess.com Username: urvishmhjn
Black's chess.com Username: yannickhs
Game's Time Control: 900+10 seconds
Game Result: 1-0

We can get the FEN (FEN is a text notation used to display the position of each piece at any given moment in the game) at any position in the game with the following code.

Python3




# The move number for which we want the FEN
move_number = 8
  
# Go through each move in the game until
# we reach the required move number
for number, move in enumerate(game.mainline_moves()):
      
    # It copies the move played by each 
    # player on the virtual board
    board.push(move)
      
    # Remember that number starts from 0
    if number == move_number:  
        break
  
fen = board.fen()
print(fen)


Output:

r1bq1rk1/pp2bppp/4p3/3pn2n/2pP4/2P1PN2/PP1NBPPP/R2Q1RK1 w – – 0 11

If you want to visualize the chessboard, you can print the board on the terminal.

Python3




print(board)


Output:

r n b q k b . r
p p . . . p p p
. . . . p n . .
. . p p . . . .
. . . P . B . .
. . P B P . . .
P P . . . P P P
R N . Q K . N R

Note: If you want real visualization of the chessboard, instead of a printout on the terminal, use Jupyter Notebook. The output in Jupyter Notebook will be something like this.

Python3




display(board)


Chessboard in Jupyter Notebook



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads