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.4k stars 526 forks source link

How to communicate with a remote chess engine? #1083

Closed flashdens closed 3 months ago

flashdens commented 4 months ago

hello,

I got a remotely running UCI chess engine (inside a docker container), however I have no idea how to communicate with it using the code snippet provided in the docs. I've read the documentation on asyncio, but I didn't manage to find out how to handle the connection, especially that engine.initalize() and engine.ping() are abstract.

how do I send, for example, 'uci', to the remote process?


import asyncio
import asyncssh
import chess
import chess.engine
import chess.variant

async def main() -> None:
    async with asyncssh.connect("bugdothouse_fairy-stockfish", username='root', password='password', known_hosts=None) as conn:
        channel, engine = await conn.create_subprocess(chess.engine.UciProtocol, "/stockfish/stockfish")
        await engine.initialize()
        await engine.ping()

    await engine.quit()

asyncio.run(main())

i'll be grateful for any help.

niklasf commented 4 months ago

It depends on the container. Maybe you can describe how you would manually interact with the engine in the container, and then python-chess might have an equivalent?

flashdens commented 4 months ago

hi! thanks for the response

I use fairy stockfish in uci mode as the engine, so the example commands i want to send to the engine are:

uci # wait for uciok...
setoption name UCI_Variant value bughouse
position startpos
go movetime 1000

...and then simply communicate with the engine. I'm wondering how to send messages and receive responses from the remote process.

Peace

niklasf commented 4 months ago

Sorry ... I mean how to you get to that point? Is it docker run -it ...? Do you SSH in?

flashdens commented 3 months ago

hello, I use docker compose, everything is local on my machine, so if I need to do anything I just docker compose exec in and so stuff manually inside the container. But I installed an SSH server inside the engine container, so I would like my application to interact with it per SSH.

niklasf commented 3 months ago

In that case your snippet above should work.

        await engine.initialize()

will send uci and wait for uciok.

        await engine.ping()

will send isready and wait for readyok.

And await engine.analyse() (similar to https://python-chess.readthedocs.io/en/latest/engine.html#analysing-and-evaluating-a-position) or await engine.analysis() (similar to https://python-chess.readthedocs.io/en/latest/engine.html#indefinite-or-infinite-analysis) should work, too.

You can enable debug logging to see what's beeing sent and received.

Please let me know if something specific does not work, and which output it creates instead.

flashdens commented 3 months ago

Hi, it works! I was greeted with a BrokenPipe error, but it's something regarding .quit(), so does not matter. Logging indeed showed everything regarding .initialize() and .ping().

Thanks alot!