Ponder
Moderators: hgm, Rebel, chrisw
-
- Posts: 226
- Joined: Sun Mar 08, 2009 3:08 pm
- Location: Canada
Ponder
Hi all. I've been running "Faile" for a while now and would like to add a ponder feature. I've tried looking at other code, including Sjeng (7.0) but I can't see how it's been implemented (or where). I can't find any instructions online or examples of code for how to do this. I imagine it should be fairly simple once I know what I need to add where. Could anyone please provide some examples or guidance here? I had a look at crafty which has great code, but Im finding it difficult to follow the different parameters back to really get the grasp of it. Maybe there is some fairly simple code I can add somewhere to allow the engine to do this? Any help would be appreciated! Thanks .
outAtime
-
- Posts: 226
- Joined: Sun Mar 08, 2009 3:08 pm
- Location: Canada
Re: Ponder
Just to sort of update where Im at:
I have found these: extern char ponder_input[STR_BUFF];
extern bool is_pondering;
and also in another part:
I have found these: extern char ponder_input[STR_BUFF];
extern bool is_pondering;
and also in another part:
Code: Select all
if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0;
return 1;
outAtime
-
- Posts: 27822
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Ponder
For pondering it must be possible to abort the (ponder) search. The simplest way to do that is mae a global abort flag, and test it after UnMake(), and return immediately when it is set, so your search unwinds. (You could also use that to implement a move-now command, or put an emergency brake in the engine's time management, so that it would not have to use large safety margins when allocating time.)
Once you have that, you must monitor for input during the search. On Windows this can be done with the call PeekNamedPipe(). You don't want to check that in every node, because that would mean a significant burdon, but you could check it, say, every 1000 nodes. So you would put in your Search() something like:
where during initialization you would have done:
Then you could start up a search with infinite time limit just before you start reading the input. (Supposing pondering has been switched on.) Arrival of input would cause the search to abort, so you would read and process the input as you would have done when you were not pondering.
Don't forget to clear 'abort' afterwards. That's realy all there is to it.
Once you have that, you must monitor for input during the search. On Windows this can be done with the call PeekNamedPipe(). You don't want to check that in every node, because that would mean a significant burdon, but you could check it, say, every 1000 nodes. So you would put in your Search() something like:
Code: Select all
if(delay-- < 0) {
DWORD cnt;
delay = 1000;
if(!PeekNamedPipe(inp, NULL, 0, NULL, &cnt, NULL) || cnt != 0) abort = 1;
}
Code: Select all
inp = GetStdHandle(STD_INPUT_HANDLE);
Don't forget to clear 'abort' afterwards. That's realy all there is to it.
-
- Posts: 226
- Joined: Sun Mar 08, 2009 3:08 pm
- Location: Canada
Re: Ponder
Code: Select all
int interrupt(void)
{
int c;
#ifdef HAVE_SELECT
FD_ZERO(&read_fds);
FD_SET(0,&read_fds);
timeout.tv_sec = timeout.tv_usec = 0;
select(1,&read_fds,NULL,NULL,&timeout);
if(FD_ISSET(0,&read_fds))
{
c = getc(stdin);
if (c == '?') /*Move now*/
{
return 1;
}
else if (c == '.') /* Stat request */
{
getc(stdin);
post_stat_thinking();
return 0;
}
ungetc(c, stdin);
if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0;
return 1;
}
else return 0;
#else
static int init = 0, pipe;
static HANDLE inh;
DWORD dw;
if(xb_mode) { // winboard interrupt code taken from crafty
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);
FlushConsoleInputBuffer(inh);
}
}
if(pipe) {
if(!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL))
{
c = getc(stdin);
if (c == '?') /*Move now*/
{
return 1;
}
else if (c == '.') /* Stat request */
{
getc(stdin);
post_stat_thinking();
return 0;
}
ungetc(c, stdin);
if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0;
return 1;
}
if (dw)
{
c = getc(stdin);
if (c == '?') /*Move now*/
{
return 1;
}
else if (c == '.') /* Stat request */
{
getc(stdin);
post_stat_thinking();
return 0;
}
ungetc(c, stdin);
if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0;
return 1;
}
else return 0;
} else {
GetNumberOfConsoleInputEvents(inh, &dw);
if (dw <= 1)
{
return 0;
}
else
{
c = getc(stdin);
if (c == '?') /*Move now*/
{
return 1;
}
else if (c == '.') /* Stat request */
{
getc(stdin);
post_stat_thinking();
return 0;
}
ungetc(c, stdin);
if (!is_pondering && (Variant == Bughouse || Variant == Crazyhouse)) return 0;
return 1;
};
}
}
#endif
outAtime
-
- Posts: 1243
- Joined: Sat Dec 13, 2008 7:00 pm
Re: Ponder
The code is a bit more complicated than needed because:
1) It supports both Unix and Windows (#ifdef HAVE_SELECT...#else...#endif)
2) It duplicates some code needlessly.
3) It handles move immediate (! command in winboard)
4) It handles analysis mode (. command in winboard)
To handle the latter 2, the code gets the first character, checks for a match, and then "ungets" the character so the normal winboard processing code can take care of it.
1) It supports both Unix and Windows (#ifdef HAVE_SELECT...#else...#endif)
2) It duplicates some code needlessly.
3) It handles move immediate (! command in winboard)
4) It handles analysis mode (. command in winboard)
To handle the latter 2, the code gets the first character, checks for a match, and then "ungets" the character so the normal winboard processing code can take care of it.
-
- Posts: 226
- Joined: Sun Mar 08, 2009 3:08 pm
- Location: Canada
Re: Ponder
Great! All I'm trying to do is get old Faile to ponder. Aside from adding the
(extern char ponder_input[STR_BUFF]; extern bool is_pondering;) to .extvars do you think I will need to add any of the !is_pondering stuff to search anywhere? Im hoping I wont and that it will work with just the mods to .utils and .extvars.
(extern char ponder_input[STR_BUFF]; extern bool is_pondering;) to .extvars do you think I will need to add any of the !is_pondering stuff to search anywhere? Im hoping I wont and that it will work with just the mods to .utils and .extvars.
outAtime
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Ponder
? commandGian-Carlo Pascutto wrote:3) It handles move immediate (! command in winboard)
Sven
-
- Posts: 226
- Joined: Sun Mar 08, 2009 3:08 pm
- Location: Canada
Re: Ponder
OK, I have it compiled fixed a couple errors, but I'm not getting any information about what its pondering...how to output the ponder moves like regular search? I will have a look around and see what I can dig up...
Basically it detects ponder, but I need some way to confirm its working, like some data on the screen
Basically it detects ponder, but I need some way to confirm its working, like some data on the screen
outAtime
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Ponder
5) It combines several purposes in one function, while I think it would be better to separate the pure detection of input being available from processing that input.Gian-Carlo Pascutto wrote:The code is a bit more complicated than needed because:
1) It supports both Unix and Windows (#ifdef HAVE_SELECT...#else...#endif)
2) It duplicates some code needlessly.
3) It handles move immediate (! command in winboard)
4) It handles analysis mode (. command in winboard)
To handle the latter 2, the code gets the first character, checks for a match, and then "ungets" the character so the normal winboard processing code can take care of it.
6) As an implication of 5), it works with engines based on the WB protocol only.
7) It depends on several global variables and constants (read_fds, timeout, xb_mode, is_pondering, Variant, Bughouse, Crazyhouse) and also calls at least one engine-specific function (post_stat_thinking()) so it is not easy to port it to a different engine.
Sven
-
- Posts: 226
- Joined: Sun Mar 08, 2009 3:08 pm
- Location: Canada