How to use opening books on mac/linux 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

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

$&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)
...


I checked the build folder from polyglot-chess, but there isn't a polyglot file at that location.
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 and a polyglot opening book of your choice. In this example I'm using gm2001.bin, which you can get from here.

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.