Today I've finally managed to connect my javascript chess engine running in nodejs via UCI to arena GUI.
The problem is I can't figure out how properly to read keyboard buffer to be able to stop engine from searching on demand ('quit' or 'stop')
I know I can use child process and interact via messages but this assumes that engine would be in separate file from the uci loop one
and I don't want that, so I'm trying to implement good all schema when every 2047 nodes communicate() fires and within that function
we read keyboard input.
Here's code in C that works for me:
Code: Select all
int input_waiting()
{
#ifndef WIN32
fd_set readfds;
struct timeval tv;
FD_ZERO (&readfds);
FD_SET (fileno(stdin), &readfds);
tv.tv_sec=0; tv.tv_usec=0;
select(16, &readfds, 0, 0, &tv);
return (FD_ISSET(fileno(stdin), &readfds));
#else
static int init = 0, pipe;
static HANDLE inh;
DWORD dw;
if (!init)
{
init = 1;
inh = GetStdHandle(STD_INPUT_HANDLE);
pipe = !GetConsoleMode(inh, &dw);
if (!pipe)
{
SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT));
FlushConsoleInputBuffer(inh);
}
}
if (pipe)
{
if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;
return dw;
}
else
{
GetNumberOfConsoleInputEvents(inh, &dw);
return dw <= 1 ? 0 : dw;
}
#endif
}
"keypress" module that restores old nodejs binding and I can actually listen on keypresses assuming that console is set to the raw mode.
Now my issue is that I can't "listen" on keypress when my communicate() fires - all the keypresses are getting handled but only after search
(in my case I'm testing it with perft, but that doesn't matter) is finished. So here's the code:
Code: Select all
function communicate() {
//console.log('communicate');
readKeyboard();
}
function readKeyboard() {
console.log('read keyboard')
// listen for the "keypress" event
process.stdin.on('keypress', function (ch, key) {
console.log('got "keypress"', key);
if (key && key.ctrl && key.name == 'c') {
process.exit();
}
});
process.stdin.setRawMode(true);
process.stdin.resume();
}
process.stdin.on('keypress',...) gets handled only after perft is finished.
So my question is: how can I read single key presses during communicate() ?