Reputation: 31
I am trying to get the evaluations for a series of fen positions using the Python stockfish library. When the solution is mate in x, my code runs quickly. When the solution is x centipawns it runs for a very long time. How do I get stockfish to limit the amount of time it has to think about the evaluation? Here's my code:
fish = Stockfish()
evals = []
fen = 'r1bqk2r/pp1pbppp/2n1pn2/2p5/2B1N3/4PN2/PPPP1PPP/R1BQ1RK1 b kq - 1 1'
fish.set_fen_position(fen)
fish.get_evaluation()
Upvotes: 3
Views: 821
Reputation: 5034
I looked at the code and getting the score using time is not supported at the moment.
I created a function where you can control the time limit. The function will return score in cp and mate as well as the bestmove.
from stockfish import Stockfish
VALUE_MATE = 32000
def mate_to_value(mate: int) -> int:
"""
Convert mate number to value.
"""
if mate > 0:
v = VALUE_MATE - 2*mate + 1
else:
v = -VALUE_MATE - 2*mate
return v
def my_get_evaluation(fish: Stockfish, fen: str, timems: int):
"""
Evaluate the fen with fish at a given timems.
Returns a dict of score {'cp': '49', 'mate': None} and move.
"""
score = {}
bestmove = '0000'
fish.set_fen_position(fen)
fish.get_best_move_time(timems)
search_info = fish.info
bestmove = search_info.split(' pv ')[1].split()[0]
if 'score cp ' in search_info:
score_cp = search_info.split('score cp ')[1].split()[0]
score.update({'cp': int(score_cp), 'mate': None})
elif 'score mate ' in search_info:
score_mate = search_info.split('score mate ')[1].split()[0]
score_cp = mate_to_value(int(score_mate))
score.update({'cp': int(score_cp), 'mate': int(score_mate)})
return score, bestmove
def myprocess():
evals = []
only_score_cp = []
bestmoves = []
timems = 5000
fens = [
'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1',
'1k6/7Q/2K5/8/8/8/8/8 w - - 0 1',
'1k6/7Q/1K6/8/8/8/8/8 b - - 0 1'
]
fish = Stockfish(r'F:\Chess\Engines\stockfish\sf14\sf14.exe')
for fen in fens:
score, bm = my_get_evaluation(fish, fen, timems)
evals.append(score)
bestmoves.append(bm)
only_score_cp.append(score['cp'])
for e in evals:
print(e)
print()
for bm in bestmoves:
print(bm)
print()
for s in only_score_cp:
print(s)
print()
for f, m, e in zip(fens, bestmoves, evals):
print(f'fen: {f}, move: {m}, score: {e}')
# Start
myprocess()
{'cp': 49, 'mate': None}
{'cp': 31999, 'mate': 1}
{'cp': -31998, 'mate': -1}
e2e4
h7b7
b8c8
49
31999
-31998
fen: rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1, move: e2e4, score: {'cp': 49, 'mate': None}
fen: 1k6/7Q/2K5/8/8/8/8/8 w - - 0 1, move: h7b7, score: {'cp': 31999, 'mate': 1}
fen: 1k6/7Q/1K6/8/8/8/8/8 b - - 0 1, move: b8c8, score: {'cp': -31998, 'mate': -1}
Upvotes: 1
Reputation: 421
You can use the python-chess
library ($ pip instep python-chess
) and simply do that :
import chess
import chess.engine
engine = chess.engine.SimpleEngine.popen_uci("your/stockfish/path/here.exe")
fen = 'r1bqk2r/pp1pbppp/2n1pn2/2p5/2B1N3/4PN2/PPPP1PPP/R1BQ1RK1 b kq - 1 1'
board = chess.Board(fen)
evaluation = chess.engine.Limit(time=1))['score']
print(evaluation)
Upvotes: 0