Search Interrupt

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

Search Interrupt

Postby Richard Allbert » 05 Aug 2005, 08:12

Hi,

I have seen the previous post about search interruption..

Code: Select all
if(check_for_input()) {
          handle_input_if_possible();
          if_user_ask_for_abort() {
              abort = 1;
              return 0;
          }
      }


But I am really struggling with how to make the check_for_input() function. I have tried various ways of using (cin) but it is too slow, or stops. Last night, Pradu told me about PeekNamedPipe(), but I don't really understand it, even after reviewing Microsofts website.

None of my books have any of these techniques, either :?

Can anyone help? This is the last piece of functionality I need to add (having finally managed to sort fen string parsing :wink: )

Thanks,

Richard
Richard Allbert
 
Posts: 105
Joined: 27 Sep 2004, 11:56
Location: Aschaffenburg, Germany

Re: Search Interrupt

Postby Roman Hartmann » 05 Aug 2005, 09:06

Hi Albert,
I just had the same problem two days ago but meanwhile I found something that works.

Maybe you should use strcmp() rather than what I'm doing here though.

Code: Select all
int check_input()
{
   int data, bytes;
   char input[255]="", *endc;

   data = Bioskey();
   if(data)
   {
   /* taken from Beowulf */
   /* own solution with fgets didn't work */
      do {
         bytes=read(fileno(stdin),input,255);
      } while (bytes<0);
      endc = strchr(input,'\n');
      if (endc) *endc=0;
   /* end beowulf part */
      if(input[0] == 'e' && input[1] == 'x' && input[2] == 'i')
      {
         printf("search aborted\n");
         search_time = 0;
         return 1;
      }
      if(input[0] == 's' && input[1] == 't' && input[2] == 'o')
      {
         printf("search aborted\n");
         search_time = 0;
         return 1;
      }      
      if(input[0] == '.')
      {
         post_win = TRUE;
         return 0;
      }
   }
   return 0;
}


Hope that helps.
Roman
User avatar
Roman Hartmann
 
Posts: 155
Joined: 11 Oct 2004, 14:21

Re: Search Interrupt

Postby Anonymous » 05 Aug 2005, 09:30

You can consider to use this API:

SHORT GetAsyncKeyState(int vKey);

or this one:

SHORT GetKeyState(int nVirtKey);

You can call one of this function (or both) half a second or any second, without any significative slow down.

Stefano
Anonymous
 

Re: Search Interrupt

Postby Richard Allbert » 05 Aug 2005, 10:17

:D Thank you.!

I'll try that as soon as I get home from work :wink:

Richard
Richard Allbert
 
Posts: 105
Joined: 27 Sep 2004, 11:56
Location: Aschaffenburg, Germany

Re: Search Interrupt

Postby Pallav Nawani » 05 Aug 2005, 12:12

Roman Hartmann wrote:Hi Albert,
I just had the same problem two days ago but meanwhile I found something that works.

Code: Select all
int check_input()
{
   int data, bytes;
   char input[255]="", *endc;

   data = Bioskey();
 ...


Hope that helps.
Roman

You forgot the important part, which is the Bioskey function ;)
User avatar
Pallav Nawani
 
Posts: 147
Joined: 26 Sep 2004, 20:00
Location: Dehradun, India

Re: Search Interrupt

Postby Roman Hartmann » 05 Aug 2005, 12:30

Pallav Nawani wrote:
Roman Hartmann wrote:Hi Albert,
I just had the same problem two days ago but meanwhile I found something that works.

Code: Select all
int check_input()
{
   int data, bytes;
   char input[255]="", *endc;

   data = Bioskey();
 ...


Hope that helps.
Roman

You forgot the important part, which is the Bioskey function ;)


:D True. I just assumed he had the same troubles I had which was not the bioskey part.

Roman

Below is the bioskey function I'm using.
Code: Select all
/* taken from Olithink (O. Brausch) */
int Bioskey(void)
{
   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;
   }
}
User avatar
Roman Hartmann
 
Posts: 155
Joined: 11 Oct 2004, 14:21

Re: Search Interrupt

Postby Richard Allbert » 06 Aug 2005, 11:04

OK, thanks again.

:D

Richard
Richard Allbert
 
Posts: 105
Joined: 27 Sep 2004, 11:56
Location: Aschaffenburg, Germany

Re: Search Interrupt

Postby Daniel Mehrmann » 07 Aug 2005, 11:10

Richard Allbert wrote:Hi,

I have seen the previous post about search interruption..

Code: Select all
if(check_for_input()) {
          handle_input_if_possible();
          if_user_ask_for_abort() {
              abort = 1;
              return 0;
          }
      }


But I am really struggling with how to make the check_for_input() function. I have tried various ways of using (cin) but it is too slow, or stops. Last night, Pradu told me about PeekNamedPipe(), but I don't really understand it, even after reviewing Microsofts website.

None of my books have any of these techniques, either :?

Can anyone help? This is the last piece of functionality I need to add (having finally managed to sort fen string parsing :wink: )

Thanks,

Richard


Hi Richard,

here are Homers to handle this question. You can use it for or engine if you whish :D

Code: Select all
/*
 * Chessprogram Homer
 * Copyright Daniel Mehrmann, 2003-2005
 * console.c
 */

/* WCE don't used console suff */

#include <stdio.h>

#if !defined (_WIN32_WCE) && defined (WIN32)
    #include <windows.h>

#elif !defined (_WIN32_WCE)
    /* Unix posix */
    #include <sys/time.h>
#endif

#include "homer.h"
#include "protos.h"
#include "extern.h"

/* search.c */
extern BOOL stop_search;
extern int p_depth;

/* search.h */
extern int window;

/* wb.c */
extern int ping, pong;

/* wb.c */
extern char UserMove[STD_BUFF];

/* Dummy replace for WCE: return even TRUE */
BOOL
CheckInPut(void)
{
/* Windows */
#if !defined (_WIN32_WCE) && defined (WIN32)
    static BOOL init = FALSE, pipe;
    static HANDLE StdinHandle;
    DWORD value, LastError;

    /* MS: CRT file handles */
    if (init && stdin->_cnt > 0)
        return TRUE;

    if (!init) {
        init = TRUE;
        StdinHandle = GetStdHandle(STD_INPUT_HANDLE);

        if (StdinHandle == NULL || StdinHandle == INVALID_HANDLE_VALUE) {
            #ifdef _WIN32 /* >= Win2000 */
                LastError = GetLastError();
                MessageHandle("GetStdHandle() failed" , (int)LastError);
            #else
                MessageHandle("GetStdHandle() failed" , 0);
            #endif
        }
        pipe = !GetConsoleMode(StdinHandle, &value);
        if (!pipe) {
            SetConsoleMode(StdinHandle,value &~ (ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT));
            FlushConsoleInputBuffer(StdinHandle);
        }
    }

    if (pipe) {
        if (!PeekNamedPipe(StdinHandle, NULL, 0, NULL, &value, NULL)) {
            #ifdef _WIN32 /* >= Win2000 */
                LastError = GetLastError();
                MessageHandle("PeekNamedPipe stdin failed" , (int)LastError);
            #else
                MessageHandle("PeekNamedPipe stdin failed" , 0);
            #endif
        }
        return value > 0;
   } else {
        GetNumberOfConsoleInputEvents(StdinHandle, &value);
        return value > 1;
   }
   return FALSE;

/* UNIX */
#elif !defined (_WIN32_WCE)
   fd_set rfd;
   struct timeval timeval;
   timeval.tv_sec = timeval.tv_usec = 0;
   FD_ZERO(&rfd);
   FD_SET(0, &rfd);

   return select(1, &rfd, NULL, NULL, &timeval) > 0;
#endif

/* dummy _WIN32_WCE */
#if defined (_WIN32_WCE)
   return TRUE;
#endif
}
greetings
Daniel
User avatar
Daniel Mehrmann
 
Posts: 127
Joined: 02 Oct 2004, 06:10
Location: Germany

Re: Search Interrupt

Postby Richard Allbert » 07 Aug 2005, 12:02

Thanks Daniel :)

Chat soon.

Richard
Richard Allbert
 
Posts: 105
Joined: 27 Sep 2004, 11:56
Location: Aschaffenburg, Germany

Re: Search Interrupt

Postby Anonymous » 07 Aug 2005, 19:54

Daniel, you use a function "MessageHandle()". I can neither find it in my Windows programming book, nor on msdn.microsoft.com.

You use the stdin->_cnt check at the outer level of your function. This has the disadvantage, that you probably cannot use input redirection efficiently anymore. Asumme you store something like:

st 10
setboard somefen
go
quit

in a file input.txt. Now it can be handy to start an engine by

engine < input.txt

(It can be very useful for debugging/testing). Your function will probably return true during the search and stop the search (The "quit" is already available).

Not checking for stdin->_cnt is also not reliable in my experience, when using Standard C i/o functions (it will work when using low level Unixish _read()). So the check should be inside the if (pipe), I think.

BTW. Some compilers do not support indented #if etc. Indenting with the spaces after the "#" will work everywhere.

Code: Select all
#  ifdef SOMETHING /* Will work practically everywhere */
#  endif

  #ifdef SOMETHING /* Some c90 compilers will refuse to compile this */
  #endif


Cheers,
Dieter
Anonymous
 

Re: Search Interrupt

Postby Anonymous » 07 Aug 2005, 20:25

I fear it was me, who posted some code years ago, that has the stdin->_cnt check outside the if (pipe) ...

It is actually not that trivial to get it correct and well working under all circumstances. I think we can see three different situations:

a) under GUI with input redirected (the "pipe situation")
b) manually operated in "console mode"
c) input redirected from the command line

All three cases should be handled well. My suggestion under Windows: For a) use the stdin->_cnt and then the PeekNamedPipe stuff. For b) and c) old _kbhit() should do (#include <console.h>).

Ooops,
Dieter
Anonymous
 

Re: Search Interrupt

Postby Alessandro Scotti » 07 Aug 2005, 20:44

On my site (WWW button below) there is a free library that can handle input under Windows and Unix (so far tested on Linux and Mac OS X) and works fairly well.
User avatar
Alessandro Scotti
 
Posts: 306
Joined: 20 Nov 2004, 00:10
Location: Rome, Italy

Re: Search Interrupt

Postby Daniel Mehrmann » 07 Aug 2005, 21:13

Dieter B?r?ner wrote:Daniel, you use a function "MessageHandle()". I can neither find it in my Windows programming book, nor on msdn.microsoft.com.

You use the stdin->_cnt check at the outer level of your function. This has the disadvantage, that you probably cannot use input redirection efficiently anymore. Asumme you store something like:

st 10
setboard somefen
go
quit

in a file input.txt. Now it can be handy to start an engine by

engine < input.txt

(It can be very useful for debugging/testing). Your function will probably return true during the search and stop the search (The "quit" is already available).

Not checking for stdin->_cnt is also not reliable in my experience, when using Standard C i/o functions (it will work when using low level Unixish _read()). So the check should be inside the if (pipe), I think.

BTW. Some compilers do not support indented #if etc. Indenting with the spaces after the "#" will work everywhere.

Code: Select all
#  ifdef SOMETHING /* Will work practically everywhere */
#  endif

  #ifdef SOMETHING /* Some c90 compilers will refuse to compile this */
  #endif


Cheers,
Dieter


Hi Dieter,

well, MessageHandle is a function of my own :)

Code: Select all
void
MessageHandle(char *message, int ReturnCode)
{
    char SendOut[8 * STD_BUFF];

    printf("\n");

   /* non UCI */
    if (gameData.output < 3)
        sprintf(SendOut, "info %s,  rc = %d \n", message, ReturnCode);
   /* UCI */
    else
        sprintf(SendOut, "info string %s,  rc = %d \n", message, ReturnCode);


    LogOutPut(SendOut);

    printf(SendOut);
    fflush(stdout);
}


I have no problems with my macros. My gcc, MSVC and Intel CC has no problems with it.

Best,
Daniel
User avatar
Daniel Mehrmann
 
Posts: 127
Joined: 02 Oct 2004, 06:10
Location: Germany

Re: Search Interrupt

Postby Richard Allbert » 08 Aug 2005, 17:21

Thank you, thank you, thank you, all, for the replies :D :D :D

Finally, Lime's search can be interrupted.

I have used an adapted version of Homer's code - the search simply returns 0 for any keypress/input :wink:

I am really grateful for the replies - now UCI can be implemented!!

Richard
Richard Allbert
 
Posts: 105
Joined: 27 Sep 2004, 11:56
Location: Aschaffenburg, Germany


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 12 guests