Closed tcl3 closed 1 year ago
ChessEngine is behaving normally.
Actually, upon further investigation, ChessEngine
is also not behaving correctly when launched in the terminal. Commands are only printed after an EOF is received (pressing Ctrl+D
the terminal). I would expect each command to be processed after a newline.
Chess (the GUI program) "wants" to talk to the pipe in a nonblocking way, because BufferedFile::can_read_line
ends up calling BufferedHelper::find_and_populate_until_any_of
, which calls BufferedHelper::populate_read_buffer
, which reads until the entire buffer is full (which is silly) OR a zero-read happens. This is a fundamental difference between the line-buffering in DeprecatedFile and InputBufferedFile (aka InputBufferedSeekable<File>
). The same thing happens in ChessEngine, which explains why you're seeing this behavior in the Console: It just tries to read 4096 bytes before even checking whether a \n
has been encountered.
That's why I changed it in 0fe29a48ad85ed592b81b77cdd51a0cddbce6c44 to O_NONBLOCK
, because surely then there's going to be some zero-reads, populate_read_buffer
can terminate early and find_and_populate_until_any_of
can decide whether it wants some more data or not (i.e. whether a \n
is in the read data).
Stupidly, I forgot that this also affects the spawned process. I only played a game against ChessEngine (but not stockfish), lost, and took that as an indication that it still works.
My best guess is that stockfish cannot handle nonblocking I/O.
I'm going to make a PR where all applications that want to use buffered I/O have to explicitly opt-in to O_NONBLOCK; i.e. the pip is created blocking, then Chess sets blocking to false just for itself, and if the spawned process wants to, it can set its I/O to be nonblocking. This sounds like the sanest option.
This also feels like slightly weird semantics of can_read_line()
, but that's a different issue.
Migration from
Core::IODevice
toCore::File
seems to be making stockfish behave strangely. A new process is being launched for each new move and it seems think the best move is to always advance a pawn one square.ChessEngine is behaving normally.
Video:
https://github.com/SerenityOS/serenity/assets/2817754/6e60e7bb-c9bc-4fd4-a908-f0b28fa4dc0c
It looks like we are hitting this
m_in->can_read_line()
condition after every set of commands is received from the engine:https://github.com/SerenityOS/serenity/blob/f7185dfa912fa0e0dae555c2d1d7fc013b50aba5/Userland/Libraries/LibChess/UCIEndpoint.cpp#L69-L73
While this would explain the new process being launched for every move I'm not sure that explains the strange move choices being made.
cc: @BenWiederhake