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.42k stars 529 forks source link

InfoHandler does not get UCI info lines for more than 20 PVs #289

Closed rajb245 closed 6 years ago

rajb245 commented 6 years ago

I'm using python-chess 0.23.5 from pypi, installed using pip on Windows with python '3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]'

I have a position where I want to use an engine to do a shallow, broad analysis and return me centipawn scores. In this case, there are 32 legal moves in the position, and I wanted a depth 10 scoring of all the legal moves. When I tried this using python-chess, I found that the InfoHandler was capturing "info" lines from the engine on only 20 variations, even though the engine MultiPV was set to something larger. The below test-case and output should demonstrate the problem. I verified that if I send the corresponding UCI commands to the engine with 32 PVs, it does indeed output info strings for 32 variations; UCI code is further down at the bottom.

Here is the python-chess test code:

import chess
from chess import uci
ENGINE_PATH = ''#insert path to engine here, i used stockfish build from source
engine = chess.uci.popen_engine(ENGINE_PATH) #engine
engine.uci()
engine.isready()
info_handler = chess.uci.InfoHandler() #create info handler
engine.info_handlers.append(info_handler) #bind info handler
#this position has 32 legal moves
board = chess.Board('r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - 0 4')
scoringDepth = 10 #we'll try to score them all to depth 10
nLegalMoves = board.legal_moves.count() #should be 32
#now we'll step through various values of MultiPV and see what InfoHander does
for multipv in range(1,nLegalMoves+1):
    engine.setoption({'MultiPV':multipv})
    engine.go(depth=scoringDepth)
    print('Scored',multipv,'moves; info_handler returned ', info_handler.info['multipv'], 'variations')

python-chess test-code output:

Scored 1 moves; info_handler returned 1 variations Scored 2 moves; info_handler returned 2 variations Scored 3 moves; info_handler returned 3 variations Scored 4 moves; info_handler returned 4 variations Scored 5 moves; info_handler returned 5 variations Scored 6 moves; info_handler returned 6 variations Scored 7 moves; info_handler returned 7 variations Scored 8 moves; info_handler returned 8 variations Scored 9 moves; info_handler returned 9 variations Scored 10 moves; info_handler returned 10 variations Scored 11 moves; info_handler returned 11 variations Scored 12 moves; info_handler returned 12 variations Scored 13 moves; info_handler returned 13 variations Scored 14 moves; info_handler returned 14 variations Scored 15 moves; info_handler returned 15 variations Scored 16 moves; info_handler returned 16 variations Scored 17 moves; info_handler returned 17 variations Scored 18 moves; info_handler returned 18 variations Scored 19 moves; info_handler returned 19 variations Scored 20 moves; info_handler returned 20 variations Scored 21 moves; info_handler returned 20 variations Scored 22 moves; info_handler returned 20 variations Scored 23 moves; info_handler returned 20 variations Scored 24 moves; info_handler returned 20 variations Scored 25 moves; info_handler returned 20 variations Scored 26 moves; info_handler returned 20 variations Scored 27 moves; info_handler returned 20 variations Scored 28 moves; info_handler returned 20 variations Scored 29 moves; info_handler returned 20 variations Scored 30 moves; info_handler returned 20 variations Scored 31 moves; info_handler returned 20 variations Scored 32 moves; info_handler returned 20 variations

UCI commands showing that engine does the info strings correctly with 32 multipv in the same position

uci
isready
position fen r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq - 0 4
setoption name MultiPV value 32
go depth 10
Mk-Chan commented 6 years ago

You never gave the board to the engine. You have to do a engine.position(board) or else your multipv is running for startpos which does have 20 possible moves.

rajb245 commented 6 years ago

Ah, thanks @Mk-Chan

Apologies for the noise, closing the bug.