niklasf / python-chess

A chess library for Python, with move generation and validation, PGN parsing and writing, Polyglot opening book reading, Gaviota tablebase probing, Syzygy tablebase probing, and UCI/XBoard engine communication
https://python-chess.readthedocs.io/en/latest/
GNU General Public License v3.0
2.46k stars 531 forks source link

Question: how to get consistent scores from engine when comparing moves? #741

Closed matteson closed 3 years ago

matteson commented 3 years ago

Awesome library, thanks!

I'm trying to iterate through positions in a PGN file and generate the difference in scores between the best move and the move made. In the following code, I'd expect only positive numbers to be printed (infoBest['score'] strictly greater than infoGame['score']), but I find negative numbers pretty frequently.

I suspect I'm misunderstanding something. Could you point me in the right direction?

pgn = open(f'twic920.pgn')

game = chess.pgn.read_game(pgn)

engine = chess.engine.SimpleEngine.popen_uci('/usr/local/bin/stockfish')

board = game.board()
for move in game.mainline_moves():
    infoBest = engine.analyse(board, chess.engine.Limit(depth=18), game='best')
    infoGame = engine.analyse(board, chess.engine.Limit(depth=18), game='game', root_moves=[move])

    if board.turn:
        print(infoBest['score'].white().score() - infoGame['score'].white().score())
    else:
        print(infoBest['score'].black().score() - infoGame['score'].black().score())

    board.push(move)
niklasf commented 3 years ago

Hi, thanks!

Some small negative values are expected here. Engines aren't perfect, and restricting search to a particular move allows spending more time on that move. So the more focused analysis may find that the move in better than the original evaluation. Deeper search will reduce but never eliminate this effect.

Some advice: