Answers.Body: <p>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 <a href="https://pypi.python.org/pypi/python-chess" rel="noreferrer">python-chess</a> module.
  If the in-code comments are not enough, feel free to ask for clarifications or possible extensions of the code:</p>
  
  <p>To showcase a working example, I've taken a game between <a href="http://www.chessgames.com/perl/chessgame?gid=1333302" rel="noreferrer">Adams and Kasparov</a>, you can download the PGN from the hyperlink. And our engine is the latest Stockfish available taken from the <a href="https://stockfishchess.org/" rel="noreferrer">official website</a>.</p>
  
  <p>Lets call it <code>PGNeval.py</code>:</p>
  
  <pre><code>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])
  </code></pre>
  
  <p>Lets test it with the aformentioned game PGN, our command is:</p>
  
  <p><code>python PGNeval.py adams_kasparov_2005.pgn</code></p>
  
  <p>And here's the output I get:</p>
  
  <p><code>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</code></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-28T20:07:43.223Z
Answers.Text: Is there any way i can traverse to any node of a game(not just end node)?
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-28T21:36:01.330Z
Answers.Text: yes, just loop over the nodes, I've added one way of doing this in the edit.
Answers.UserDisplayName: Ellie
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-29T03:44:44.243Z
Answers.Text: `variations` gives you all child nodes which you are re-assigning to `game` to traverse till end. Thanks phonon for your help.
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-29T18:33:17.393Z
Answers.Text: my pleasure. Have fun playing around with this module, it's well written.
Answers.UserDisplayName: Ellie
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-28T17:36:39.673Z
Answers.LastActivityDate: 2017-07-28T21:38:05.890Z
Answers.LastEditDate: 2017-07-28T21:38:05.890Z
Answers.UserDisplayName: Ellie
Body: <p>I am trying to get Stockfish's evaluation of a board position(which is in PGN format) using command line.<br>I know it accepts board position in FEN format, but is there any way i can provide PGN format?<br>
  If no, how can i convert PGN format to FEN?<br>
  Is there any tool in Python which can help me out?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2021-04-21T21:08:03.410Z
Comments.Text: This is great, but is it possible to update the code for the latest version of the chess lib?
Comments.UserDisplayName: Laurence
Tags: <analysis><stockfish><programming><pgn><fen>
Title: Stockfish evaluation of a position from PGN
ThreadText: # Stockfish evaluation of a position from PGN
  
  (Asked by: username_0 on 2017-07-28)
  
  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?
  
  **Tags:** analysis, stockfish, programming, pgn, fen
  
  > **Comments:**
  > **username_1**: This is great, but is it possible to update the code for the latest version of the chess lib?  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2017-07-28. Score: 11 | Accepted answer
  
  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](https://pypi.python.org/pypi/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](http://www.chessgames.com/perl/chessgame?gid=1333302), you can download the PGN from the hyperlink. And our engine is the latest Stockfish available taken from the [official website](https://stockfishchess.org/).
  
  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`
  
  > **Comments:**
  > **username_0**: Is there any way i can traverse to any node of a game(not just end node)?  
  > **username_2**: yes, just loop over the nodes, I've added one way of doing this in the edit.  
  > **username_0**: `variations` gives you all child nodes which you are re-assigning to `game` to traverse till end. Thanks phonon for your help.  
  > **username_2**: my pleasure. Have fun playing around with this module, it's well written.  
  
  ---
  
  