13

I am trying to get Stockfish's evaluation of a board position(which is in PGN format) using command line.
I know it accepts board position in FEN format, but is there any way i can provide PGN format?
If no, how can i convert PGN format to FEN?
Is there any tool in Python which can help me out?

1
  • This is great, but is it possible to update the code for the latest version of the chess lib?
    – Laurence
    Apr 21, 2021 at 21:08

1 Answer 1

11

Yes there are easy ways to do this. I'm going to briefly show you one quick way of doing it in python, using the python-chess module. If the in-code comments are not enough, feel free to ask for clarifications or possible extensions of the code:

To showcase a working example, I've taken a game between Adams and Kasparov, you can download the PGN from the hyperlink. And our engine is the latest Stockfish available taken from the official website.

Lets call it PGNeval.py:

import chess
import chess.uci
import chess.pgn
import sys

arguments = sys.argv
pgnfilename = str(arguments[1])

#Read pgn file:
with open(pgnfilename) as f:
    game = chess.pgn.read_game(f)

#Go to the end of the game and create a chess.Board() from it:
game = game.end()
board = game.board()

#So if you want, here's also your PGN to FEN conversion:
print 'FEN of the last position of the game: ', board.fen()

#or if you want to loop over all game nodes:
#while not game.is_end():
    #node = game.variations[0]
    #board = game.board() #print the board if you want, to make sure
    #game = node         

#Now we have our board ready, load your engine:
handler = chess.uci.InfoHandler()
engine = chess.uci.popen_engine('...\stockfish_8_x64') #give correct address of your engine here
engine.info_handlers.append(handler)

#give your position to the engine:
engine.position(board)

#Set your evaluation time, in ms:
evaltime = 5000 #so 5 seconds
evaluation = engine.go(movetime=evaltime)

#print best move, evaluation and mainline:
print 'best move: ', board.san(evaluation[0])
print 'evaluation value: ', handler.info["score"][1].cp/100.0
print 'Corresponding line: ', board.variation_san(handler.info["pv"][1])

Lets test it with the aformentioned game PGN, our command is:

python PGNeval.py adams_kasparov_2005.pgn

And here's the output I get:

FEN of the last position of the game: br3r2/5ppk/p2pp3/4b1BP/N3P3/q4P2/1PnQB3/1K4RR w - - 4 27 best move: Qxc2 evaluation value: -10.87 Corresponding line: 27. Qxc2 Rfc8

4
  • 1
    Is there any way i can traverse to any node of a game(not just end node)?
    – John
    Jul 28, 2017 at 20:07
  • 2
    yes, just loop over the nodes, I've added one way of doing this in the edit.
    – Ellie
    Jul 28, 2017 at 21:36
  • 1
    variations gives you all child nodes which you are re-assigning to game to traverse till end. Thanks phonon for your help.
    – John
    Jul 29, 2017 at 3:44
  • 3
    my pleasure. Have fun playing around with this module, it's well written.
    – Ellie
    Jul 29, 2017 at 18:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.