Wie Kommunizieren mit einer Schach-engine in Python?

auf win 7 kann ich die Kommunikation mit einer Schach-engine per Kommandozeile. Kleines Beispiel-Sitzung mit Stockfisch auf Win 7:

C:\run\Stockfish>stockfish-x64.exe
Stockfish 2.2.2 JA SSE42 by Tord Romstad, Marco Costalba and Joona Kiiski
quit

C:\run\Stockfish>

Die erste Zeile ausgegeben wurde, die durch den Motor und die "beenden" - war, was ich tippte, beenden Sie den Motor (Es gibt andere Dinge, die ich tun kann, aber das ist mir klar).

Nun möchte ich die Kommunikation mit der engine von python:

import subprocess
engine = subprocess.Popen(
    'stockfish-x64.exe',
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
for line in engine.stdout:
    print(line.strip())
engine.stdin.write('quit\n')

bekommen und habe

C:\run\Stockfish>communicate.py
b'Stockfish 2.2.2 JA SSE42 by Tord Romstad, Marco Costalba and Joona Kiiski'

aber es nicht beenden Sie den Motor (kein C:\run\Stockfish> - Eingabeaufforderung), es hält auf eine Eingabe wartet. Ich habe das Fenster zu schließen per hand. Es scheint nicht, um meine quit-Nachricht (die Letzte Zeile des python-Skript) geschrieben stdin.

In anderen Worten: ich kann Lesen von stdout aber wenn ich schreiben auf stdin nichts passiert.

Was mache ich falsch und wie es richtig zu machen?


Edit: ok, Dank larsmans Hilfe habe ich es gelöst:

Beispiel-Python-script:

import subprocess, time

engine = subprocess.Popen(
    'stockfish-x64.exe',
    universal_newlines=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
)

def put(command):
    print('\nyou:\n\t'+command)
    engine.stdin.write(command+'\n')

def get():
    # using the 'isready' command (engine has to answer 'readyok')
    # to indicate current last line of stdout
    engine.stdin.write('isready\n')
    print('\nengine:')
    while True:
        text = engine.stdout.readline().strip()
        if text == 'readyok':
            break
        if text !='':
            print('\t'+text)

get()
put('uci')
get()
put('setoption name Hash value 128')
get()
put('ucinewgame')
get()
put('position startpos moves e2e4 e7e5 f2f4')
get()
put('go infinite')
time.sleep(3)
get()
put('stop')
get()
put('quit')

Ausgabe:

C:\run\Stockfish>1-communicate.py

engine:
        Stockfish 2.2.2 JA SSE42 by Tord Romstad, Marco Costalba and Joona Kiiski

you:
        uci

engine:
        id name Stockfish 2.2.2 JA SSE42
        id author Tord Romstad, Marco Costalba and Joona Kiiski
        option name Use Search Log type check default false
        option name Search Log Filename type string default SearchLog.txt
        ... etc ...
        uciok

you:
        setoption name Hash value 128

engine:

you:
        ucinewgame

engine:

you:
        position startpos moves e2e4 e7e5 f2f4

engine:

you:
        go infinite

engine:
        info depth 1 seldepth 1 score cp 56 nodes 62 nps 1675 time 37 multipv 1 pv e5f4
        info depth 2 seldepth 2 score cp 48 nodes 804 nps 21157 time 38 multipv 1 pv b8c6 g1h3
        info depth 3 seldepth 3 score cp 64 nodes 1409 nps 37078 time 38 multipv 1 pv b8c6 b1c3 e5f4
        ... etc ...

you:
        stop

engine:
        bestmove e5f4 ponder g1f3

you:
        quit

C:\run\Stockfish>
  • Die C:\run\Stockfish> prompt wird von Ihrer shell aus, warum würden Sie erwarten, dass ein Teilprozess, um es zu drucken?
  • Erwarten Sie, um zu sehen, dass mein python-Skript ist fertig.
  • Das war sehr hilfreich, danke für das teilen!
  • Code hat bei mir nicht funktioniert, bis ich fügte hinzu, ein zusätzliches argument zu Popen: ..., bufsize=1, ...
InformationsquelleAutor Nils | 2012-09-09
Schreibe einen Kommentar