My engines are WB, not UCI. They only stop the search on input while pondering. I did not implement any 'move now' command.
I added that piece of code only to show how 'unbuffered_input' has to be called. What you do when you detect input is upto you.
implementing uci stop command
Moderator: Ras
-
hgm
- Posts: 28457
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
-
lucasart
- Posts: 3243
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: implementing uci stop command
You don't need multithreading for this. You just need to check whether there is something to read in stdin without actually reading it. Reading from stdin with normal I/O calls is a blocking operation (the system blocks your process, waiting for the data to arrive, if it ever does...)elcabesa wrote:I'm going to modify the command parser of my UCI engine.
My engine is not multithreaded and I don't want now to write a thread for the search and a thread for the parser.
I have some problem with the stop command, I poll during the search for a kbhit() and everything is working nicely except I lose strength.
Do you know something faster than kbhit ?? what can I do?
This is not what you want. You want to interrogate the operating system and ask if there is something to read, and obtain the reponse immediately, if negative continue, else parse the data and if it's a "stop" command then stop the search. You basically need a function like this to interrogate every now and then (every thousand node for example):
Code: Select all
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#include <conio.h>
#else // assume POSIX
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#endif
bool input_available()
{
#if defined(_WIN32) || defined(_WIN64)
static bool init = false, is_pipe;
static HANDLE stdin_h;
DWORD val;
if (!init) {
init = true;
stdin_h = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(stdin_h, &val);
}
if (stdin->_cnt > 0)
return true;
if (is_pipe)
return !PeekNamedPipe(stdin_h, NULL, 0, NULL, &val, NULL) ? true : val>0;
else
return _kbhit();
#else // assume POSIX
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
struct timeval timeout;
timeout.tv_sec = timeout.tv_usec = 0;
select(STDIN_FILENO+1, &readfds, 0, 0, &timeout);
return FD_ISSET(STDIN_FILENO, &readfds);
#endif
}Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
-
hgm
- Posts: 28457
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: implementing uci stop command
Oh, the stdin->_cnt is a trick I did not know! If stdin buffering was not switched off, this could be important. (But not for UCI stop, I guess.) The point is that when you read after detecting input, even if you read a signel character with getchar(), it reads all waiting input from the pipe, and buffers it. This is important in WB protocol, where the GUI typically sends time, otim and usermove command at once. So you cannot afford to resumepondering after receiving 'time' or 'otim', because the otim and usermove will already be in the buffer, and PeekNamedPipe will report no waiting input in the pipe. So you would ponder forever...