Answers.Body: <p>You can do this on your own in a customized fashion (i.e. you control when to run the engine or to use the book) with a bit of scripting in python, using the <a href="https://pypi.org/project/python-chess/" rel="nofollow noreferrer">python-chess module</a> and a polyglot opening book of your choice. In this example I'm using <code>gm2001.bin</code>, which you can get from <a href="https://sourceforge.net/p/craftychessinterface/wiki/UCI%20engine%20opening%20book/" rel="nofollow noreferrer">here</a>.</p>
  
  <p>As dummy example I have chosen two positions: </p>
  
  <ul>
  <li><code>fen = 'rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq - 0 3'</code> A basic Catalan position for which I know the book still has a move.</li>
  <li><code>fen2 = 'rnbqkb1r/ppp1ppp1/5n2/3p3p/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq - 0 4'</code> A position for which there are no book moves left in the chosen opening book.</li>
  </ul>
  
  <p>What the code does is very basic: if it finds an opening move, then it makes that move (if there are more opening branches, you need to figure out how you want to choose the line to play), otherwise, it calls Stockfish with 10 seconds of movetime and makes the top engine move.</p>
  
  <pre><code>import chess
  import chess.uci
  import chess.polyglot
  
  fen = 'rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq - 0 3'
  fen2 = 'rnbqkb1r/ppp1ppp1/5n2/3p3p/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq - 0 4'
  board = chess.Board(fen)
  print board
  
  handler = chess.uci.InfoHandler()
  engine = chess.uci.popen_engine('stockfish_8_x64') #Provide correct address to where your engine is stored
  evaltime = 10000
  
  reader = chess.polyglot.open_reader('gm2001.bin') #Provide correct address to where your bin file is stored
  n = sum(1 for _ in reader.find_all(board))
  
  if n==0:
      print 'empty, using SF top move with 10 sec movetime'
      engine.info_handlers.append(handler)
      if board.is_checkmate():
          print 'Game has ended: checkmate'
      else:
          engine.position(board)
          eval = engine.go(movetime=evaltime)
          nextmove = board.san(eval[0])
          if handler.info["score"][1].cp != None:
              print 'Top move: ', nextmove, ' Evaluation: ',round(handler.info["score"][1].cp/100.0,2)
          else:
              print nextmove
          print board.variation_san(handler.info["pv"][1])
          print 'nodes: ', handler.info["nodes"], ' depth: ', handler.info["depth"], ' time: ', handler.info["time"]
          board.push_san(nextmove)
          print '---- Updated position:'
          print board
  else:
      for entry in reader.find_all(board):
          print 'Found book moves:'
          nextmove = board.san(entry.move())
          print str(nextmove)
          board.push_san(nextmove)
          print '---- Updated position:'
          print board
          break
  </code></pre>
  
  <p>Output for the first <code>fen</code>:</p>
  
  <pre><code>r n b q k b . r
  p p p . p p p p
  . . . . . n . .
  . . . p . . . .
  . . . P . . . .
  . . . . . N P .
  P P P . P P . P
  R N B Q K B . R
  Found book moves:
  c6
  ---- Updated position:
  r n b q k b . r
  p p . . p p p p
  . . p . . n . .
  . . . p . . . .
  . . . P . . . .
  . . . . . N P .
  P P P . P P . P
  R N B Q K B . R
  </code></pre>
  
  <p>and output for the 2nd fen (<code>fen2</code>):</p>
  
  <pre><code>r n b q k b . r
  p p p . p p p .
  . . . . . n . .
  . . . p . . . p
  . . . P . . . .
  . . . . . N P .
  P P P . P P . P
  R N B Q K B . R
  empty, using SF top move with 10 sec movetime
  Top move:  Bg2  Evaluation:  0.24
  4. Bg2 c5 5. c4 cxd4 6. cxd5 Qxd5 7. Qxd4 Nc6 8. Qxd5 Nxd5 9. Bd2 Ndb4 10. Na3 Be6 11. Ng5 Bd5 12. Bxd5 Nxd5 13. e4 Ndb4 14. Nb5 Nd3+ 15. Ke2
  nodes:  14946976  depth:  21  time:  10001
  ---- Updated position:
  r n b q k b . r
  p p p . p p p .
  . . . . . n . .
  . . . p . . . p
  . . . P . . . .
  . . . . . N P .
  P P P . P P B P
  R N B Q K . . R
  </code></pre>
  
  <p>You should be able to take it from here and extend the code however you want.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-06-18T21:00:53.677Z
Answers.Text: Thanks a lot! Unfortunate, I'm a python noob, and have an issue running this code. I'm using python3/pip3 and installed the chess module: `pip install python-chess`  Furthermore I had to change all the print statements from `print ....` to `print(....)`. I don't know why! But now I have an error which I don't know how to solve, it cannot find `chess.uci`: `No module named 'chess.uci'` Any suggestions why that is?
Answers.UserDisplayName: Jeanluca Scaljeri
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-06-18T21:31:46.187Z
Answers.Text: No problem. I am using Python 2.7 still, and you have python 3 it seems, that's why you had to change the print commands. The chess.uci error seems to simply mean you haven't installed the additional packages, try something like `pip install python-chess[uci]` (or in your case `pip3`). In the newer versions of python-chess `uci` has been replaced by `engine`, so try also `pip3 install python-chess[engine]` and then see the [related docs](https://python-chess.readthedocs.io/en/latest/engine.html) for possible syntax changes using the newest version. Let me know if you're still stuck.
Answers.UserDisplayName: Ellie
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-06-19T08:03:20.340Z
Answers.Text: Check, I have it working now. Thanks a lot!!
Answers.UserDisplayName: Jeanluca Scaljeri
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-06-18T11:43:01.560Z
Answers.LastActivityDate: 2019-06-18T11:43:01.560Z
Answers.UserDisplayName: Ellie
Body: <p>I would like to use opening books for my stockfish chess engine, but I'm not sure how to do this. As far as I understand stockfish doesn't support these, so I though I setup a system next to stockfish, which is used until it doesn't return any moves anymore.</p>
  
  <p>These .bin files can be found anywhere, for example</p>
  
  <pre><code>http://rebel13.nl/download/books.html
  </code></pre>
  
  <p>or</p>
  
  <pre><code>https://github.com/joeyrobert/ceruleanjs_opening_books
  </code></pre>
  
  <p>Anyway, I downloaded a couple of .bin files, and thought to use it with <a href="https://www.npmjs.com/package/polyglot-chess" rel="nofollow noreferrer"><code>polyglot-chess</code></a></p>
  
  <pre><code>var Polyglot = require('polyglot-chess');
  
  var obj = new Polyglot();
  
  var fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
  console.log("Polyglot hash for fen " + fen + " is: " + obj.hash(fen));
  console.log("Best move in the book is: " + obj.find(fen, "book.bin", true));
  console.log("Random move in the book is: " + obj.find(fen, "book.bin", false));
  </code></pre>
  
  <p>Now when I try to run it</p>
  
  <pre><code>$&gt; node index.js 
  internal/modules/cjs/loader.js:615
     throw err;
     ^
  
  Error: Cannot find module '../build/Release/polyglot'
      at Function.Module._resolveFilename (internal/modules/cjs/loader.js:613:15)
  ...
  </code></pre>
  
  <p>I checked the build folder from polyglot-chess, but there isn't a polyglot file at that location. </p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-06-18T05:56:21.247Z
Comments.Text: I'm not sure what you mean by "needs a polyglot tool". From what I can see, the polyglot-chess package is capable of reading the binary files without any external tool.
Comments.UserDisplayName: ProgramFOX
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-06-18T06:53:32.117Z
Comments.Text: My mistake. It seems that polyglot-chess ships with all the files needed. But I get the impression it still needs to be build
Comments.UserDisplayName: Jeanluca Scaljeri
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-06-18T07:00:38.313Z
Comments.Text: I also update my post with more details of the issue I have
Comments.UserDisplayName: Jeanluca Scaljeri
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-06-18T07:16:17.517Z
Comments.Text: Right, I see. It has to compile the native C++ file first, and that's what it's failing at for me when doing npm install. Not too surprising actually, considering the age of the package...
Comments.UserDisplayName: ProgramFOX
Tags: <engines><computer-chess>
Title: How to use opening books on mac/linux
ThreadText: # How to use opening books on mac/linux
  
  (Asked by: username_0 on 2019-06-18)
  
  I would like to use opening books for my stockfish chess engine, but I'm not sure how to do this. As far as I understand stockfish doesn't support these, so I though I setup a system next to stockfish, which is used until it doesn't return any moves anymore.
  
  These .bin files can be found anywhere, for example
  
  ```
  http://rebel13.nl/download/books.html
  
  ```
  
  or
  
  ```
  https://github.com/joeyrobert/ceruleanjs_opening_books
  
  ```
  
  Anyway, I downloaded a couple of .bin files, and thought to use it with [`polyglot-chess`](https://www.npmjs.com/package/polyglot-chess)
  
  ```
  var Polyglot = require('polyglot-chess');
  
  var obj = new Polyglot();
  
  var fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
  console.log("Polyglot hash for fen " + fen + " is: " + obj.hash(fen));
  console.log("Best move in the book is: " + obj.find(fen, "book.bin", true));
  console.log("Random move in the book is: " + obj.find(fen, "book.bin", false));
  
  ```
  
  Now when I try to run it
  
  ```
  $> node index.js 
  internal/modules/cjs/loader.js:615
     throw err;
     ^
  
  Error: Cannot find module '../build/Release/polyglot'
      at Function.Module._resolveFilename (internal/modules/cjs/loader.js:613:15)
  ...
  
  ```
  
  I checked the build folder from polyglot-chess, but there isn't a polyglot file at that location.
  
  **Tags:** engines, computer-chess
  
  > **Comments:**
  > **username_1**: I'm not sure what you mean by "needs a polyglot tool". From what I can see, the polyglot-chess package is capable of reading the binary files without any external tool.  
  > **username_0**: My mistake. It seems that polyglot-chess ships with all the files needed. But I get the impression it still needs to be build  
  > **username_0**: I also update my post with more details of the issue I have  
  > **username_1**: Right, I see. It has to compile the native C++ file first, and that's what it's failing at for me when doing npm install. Not too surprising actually, considering the age of the package...  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2019-06-18. Score: 3 | Accepted answer
  
  You can do this on your own in a customized fashion (i.e. you control when to run the engine or to use the book) with a bit of scripting in python, using the [python-chess module](https://pypi.org/project/python-chess/) and a polyglot opening book of your choice. In this example I'm using `gm2001.bin`, which you can get from [here](https://sourceforge.net/p/craftychessinterface/wiki/UCI%20engine%20opening%20book/).
  
  As dummy example I have chosen two positions:
  
  * `fen = 'rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq - 0 3'` A basic Catalan position for which I know the book still has a move.
  * `fen2 = 'rnbqkb1r/ppp1ppp1/5n2/3p3p/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq - 0 4'` A position for which there are no book moves left in the chosen opening book.
  
  What the code does is very basic: if it finds an opening move, then it makes that move (if there are more opening branches, you need to figure out how you want to choose the line to play), otherwise, it calls Stockfish with 10 seconds of movetime and makes the top engine move.
  
  ```
  import chess
  import chess.uci
  import chess.polyglot
  
  fen = 'rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq - 0 3'
  fen2 = 'rnbqkb1r/ppp1ppp1/5n2/3p3p/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq - 0 4'
  board = chess.Board(fen)
  print board
  
  handler = chess.uci.InfoHandler()
  engine = chess.uci.popen_engine('stockfish_8_x64') #Provide correct address to where your engine is stored
  evaltime = 10000
  
  reader = chess.polyglot.open_reader('gm2001.bin') #Provide correct address to where your bin file is stored
  n = sum(1 for _ in reader.find_all(board))
  
  if n==0:
      print 'empty, using SF top move with 10 sec movetime'
      engine.info_handlers.append(handler)
      if board.is_checkmate():
          print 'Game has ended: checkmate'
      else:
          engine.position(board)
          eval = engine.go(movetime=evaltime)
          nextmove = board.san(eval[0])
          if handler.info["score"][1].cp != None:
              print 'Top move: ', nextmove, ' Evaluation: ',round(handler.info["score"][1].cp/100.0,2)
          else:
              print nextmove
          print board.variation_san(handler.info["pv"][1])
          print 'nodes: ', handler.info["nodes"], ' depth: ', handler.info["depth"], ' time: ', handler.info["time"]
          board.push_san(nextmove)
          print '---- Updated position:'
          print board
  else:
      for entry in reader.find_all(board):
          print 'Found book moves:'
          nextmove = board.san(entry.move())
          print str(nextmove)
          board.push_san(nextmove)
          print '---- Updated position:'
          print board
          break
  
  ```
  
  Output for the first `fen`:
  
  ```
  r n b q k b . r
  p p p . p p p p
  . . . . . n . .
  . . . p . . . .
  . . . P . . . .
  . . . . . N P .
  P P P . P P . P
  R N B Q K B . R
  Found book moves:
  c6
  ---- Updated position:
  r n b q k b . r
  p p . . p p p p
  . . p . . n . .
  . . . p . . . .
  . . . P . . . .
  . . . . . N P .
  P P P . P P . P
  R N B Q K B . R
  
  ```
  
  and output for the 2nd fen (`fen2`):
  
  ```
  r n b q k b . r
  p p p . p p p .
  . . . . . n . .
  . . . p . . . p
  . . . P . . . .
  . . . . . N P .
  P P P . P P . P
  R N B Q K B . R
  empty, using SF top move with 10 sec movetime
  Top move:  Bg2  Evaluation:  0.24
  4. Bg2 c5 5. c4 cxd4 6. cxd5 Qxd5 7. Qxd4 Nc6 8. Qxd5 Nxd5 9. Bd2 Ndb4 10. Na3 Be6 11. Ng5 Bd5 12. Bxd5 Nxd5 13. e4 Ndb4 14. Nb5 Nd3+ 15. Ke2
  nodes:  14946976  depth:  21  time:  10001
  ---- Updated position:
  r n b q k b . r
  p p p . p p p .
  . . . . . n . .
  . . . p . . . p
  . . . P . . . .
  . . . . . N P .
  P P P . P P B P
  R N B Q K . . R
  
  ```
  
  You should be able to take it from here and extend the code however you want.
  
  > **Comments:**
  > **username_0**: Thanks a lot! Unfortunate, I'm a python noob, and have an issue running this code. I'm using python3/pip3 and installed the chess module: `pip install python-chess`  Furthermore I had to change all the print statements from `print ....` to `print(....)`. I don't know why! But now I have an error which I don't know how to solve, it cannot find `chess.uci`: `No module named 'chess.uci'` Any suggestions why that is?  
  > **username_2**: No problem. I am using Python 2.7 still, and you have python 3 it seems, that's why you had to change the print commands. The chess.uci error seems to simply mean you haven't installed the additional packages, try something like `pip install python-chess[uci]` (or in your case `pip3`). In the newer versions of python-chess `uci` has been replaced by `engine`, so try also `pip3 install python-chess[engine]` and then see the [related docs](https://python-chess.readthedocs.io/en/latest/engine.html) for possible syntax changes using the newest version. Let me know if you're still stuck.  
  > **username_0**: Check, I have it working now. Thanks a lot!!  
  
  ---
  
  