I am trying to get Stockfish to work in Python 3. Just to get started on my project, I tried to have Stockfish think until a depth of 20. However, the program instantly returns that Stockfish recommends 1.a3 in the starting position. After browsing these forums, I found out that the problem was that there was a missing '\n'. However, after adding it, the program still doesn't work. Can someone tell me what I did wrong?
1 Answer
Even though the best answer is to use a pre-existing module instead of reinventing the wheel, just for illustrative purposes here's a version that works using only pure Python Popen(). The key is the use of "isready" and waiting for an answer:
import time
from subprocess import Popen, PIPE
def put(p, msg):
p.stdin.write(msg+'\n')
p.stdin.flush()
def get(p, verbose=False):
put(p, 'isready')
lines = []
while True:
s = p.stdout.readline().strip()
if s == 'readyok':
break
if verbose:
print(s)
lines.append(s)
return lines
def putget(p, msg, verbose=False):
put(p, msg)
get(p, verbose)
def go(p, depth=None, t=1.0, dt=0.05, verbose=False):
depth = 'infinite' if depth is None else 'depth %d' % depth
put(p, "go %s" % depth)
t0 = time.time()
stopped = False
while True:
time.sleep(dt)
lines = get(p, verbose=verbose)
for line in lines:
if line.startswith('bestmove'):
return line
if not stopped and time.time() - t0 > t:
put(p, "stop")
stopped = True
p = Popen("stockfish-8-64", stdout=PIPE, stdin=PIPE, universal_newlines=True)
get(p, verbose=True)
putget(p, 'uci')
putget(p, 'position startpos')
bestmove = go(p, depth=20, t=3.0)
print(bestmove)