From: H.G.Muller Date: Thu, 6 Mar 2014 16:43:19 +0000 (+0100) Subject: Continue search on ponder hit X-Git-Url: http://winboard.nl/cgi-bin?p=gnushogi.git;a=commitdiff_plain;h=21a60b5aae737b538480c4d8beee575b3d9a8e35 Continue search on ponder hit The usermove command is now examined during ponder search, commparing the move with the hint move (stored in a new static variable for the purpose). If there is a ponder hit, the ponder search, which was started in BACKGROUND_MODE, is switched to FOREGROUND_MODE, and a ResponseTime is calculated, so that it will pay attention to the clock, and play a move once it times out. This is recognized by setting the hint-move text to "hit", which then suppresses retraction of the hint move. The if-statement at the top of InputMove is now turned into a 'while', so that a move produced after a ponder hit will immediately be followed by pondering over the next move. A ponder miss (or non-move command) will terminate this loop, through backlogging the command (as will a failure to produce a hint move). The way the thinking time is calculated after a ponder hit might have to be revised. For now SetTimeControl is called after a ponder hit when the computer has zero moves left. --- diff --git a/gnushogi/commondsp.c b/gnushogi/commondsp.c index 1790e5f..4c6dfa4 100644 --- a/gnushogi/commondsp.c +++ b/gnushogi/commondsp.c @@ -1618,8 +1618,8 @@ InputCommand(char *command, int root) #endif short ok, done, is_move = false; unsigned short mv; - char s[200], sx[200]; - static char backlog[200]; + char s[200], sx[200], s2[200]; + static char backlog[200], ponderString[20]; ok = flag.quit = done = false; player = opponent; @@ -1629,7 +1629,7 @@ InputCommand(char *command, int root) ZeroTTable(); #endif - if ((hint > 0) && !flag.easy && !flag.force && !command && !backlog[0] && root) + while ((hint > 0) && !flag.easy && !flag.force && !command && !backlog[0] && root) { /* * A hint move for the player is available. Compute a move for the @@ -1640,13 +1640,13 @@ InputCommand(char *command, int root) ft = time0; /* Save reference time for the player. */ fflush(stdout); algbr((short) hint >> 8, (short) hint & 0xff, false); - strcpy(s, mvstr[0]); + strcpy(ponderString, mvstr[0]); if (flag.post) dsp->GiveHint(); /* do the hint move */ - if (VerifyMove(s, VERIFY_AND_TRY_MODE, &mv)) + if (VerifyMove(ponderString, VERIFY_AND_TRY_MODE, &mv)) { Sdepth = 0; @@ -1681,12 +1681,27 @@ InputCommand(char *command, int root) } #endif - /* undo the hint and carry on */ - VerifyMove(s, UNMAKE_MODE, &mv); + if (strcmp(ponderString, "hit")) + { /* undo the hint and carry on */ + VerifyMove(ponderString, UNMAKE_MODE, &mv); + } + else + { /* otherwise SelectMove will have played the computer's reply */ + /* update ponder-move stats, which was skipped in TRY_MODE */ + GameList[GameCnt-1].depth = GameList[GameCnt].score = 0; + GameList[GameCnt-1].nodes = 0; + ElapsedTime(COMPUTE_AND_INIT_MODE); + GameList[GameCnt-1].time = (short) (et + 50)/100; /* FIXME: this is wrong */ + + if(TCflag && TimeControl.moves[computer] == 0) + SetTimeControl(); /* add time for next session */ + } Sdepth = 0; } time0 = ft; /* Restore reference time for the player. */ + ponderString[0] = '\0'; + /* on a ponder miss or other command, loop terminates because of backlog */ } while(!(ok || flag.quit || done)) @@ -1723,9 +1738,26 @@ InputCommand(char *command, int root) } /* extract first word */ - if (sscanf(sx, "%s", s) < 1) + if (sscanf(sx, "%s %s", s, s2) < 1) continue; + if (!root && (strcmp(s, "usermove") == 0) + && (strcmp(s2, ponderString) == 0)) + { /* ponder hit; switch to normal search */ + background = false; + hint = 0; + if (TCflag) + { /* account opponent time and moves */ + TimeControl.clock[opponent] -= et; + timeopp[oppptr] = et; + --TimeControl.moves[opponent]; + if(TimeControl.moves[computer] == 0) SetTimeControl(); + } + SetResponseTime(computer); + strcpy(ponderString, "hit"); + return false; /* no search abort */ + } + if (!root && strcmp(s, ".") && strcmp(s, "time") && strcmp(s, "otim")) { /* during search most commands can only be done after abort */ strcpy(backlog, sx); /* backlog the command */ diff --git a/gnushogi/gnushogi.h b/gnushogi/gnushogi.h index d40c3ac..fd6b022 100644 --- a/gnushogi/gnushogi.h +++ b/gnushogi/gnushogi.h @@ -852,9 +852,7 @@ typedef struct hashval drop_hashcode_array[2][NO_PIECES][NO_SQUARES]; extern hashcode_array *hashcode; extern drop_hashcode_array *drop_hashcode; -#ifdef QUIETBACKGROUND extern short background; -#endif /* QUIETBACKGROUND */ #if ttblsz extern short use_ttable; diff --git a/gnushogi/search.c b/gnushogi/search.c index 7272095..ee7b402 100644 --- a/gnushogi/search.c +++ b/gnushogi/search.c @@ -403,7 +403,7 @@ SelectMove(short side, SelectMove_mode iop) /********************** end of main loop ***************************/ /* background mode */ - if (iop == BACKGROUND_MODE) + if (background) /* originally: if (iop == BACKGROUND_MODE) */ return; if (rpt >= 3) diff --git a/gnushogi/tcontrl.c b/gnushogi/tcontrl.c index 2ce4416..539cb7f 100644 --- a/gnushogi/tcontrl.c +++ b/gnushogi/tcontrl.c @@ -295,7 +295,7 @@ void SetResponseTime(short side) TCcount = MAXTCCOUNTX; } #endif - +printf("# %2d. moves=%d,%d time=%d,%d ResponseTime=%d+%d\n",GameCnt,TimeControl.moves[computer],TimeControl.moves[opponent],TimeControl.clock[computer],TimeControl.clock[opponent],ResponseTime,TCleft); assert(TCcount <= MAXTCCOUNTX); }