switch to new tbhits protocol
authorH.G. Muller <h.g.muller@hccnet.nl>
Wed, 15 Jan 2014 19:43:55 +0000 (20:43 +0100)
committerH.G. Muller <h.g.muller@hccnet.nl>
Sat, 18 Jan 2014 23:01:48 +0000 (00:01 +0100)
The extended info is now expected as 3 bare integers, the last one
separated from the PV by at least one tab character.
The protocol extension is described in the CECP specs document.

engine-intf.html
engineoutput.c

index 1546cc8..8d5e700 100644 (file)
@@ -1799,11 +1799,31 @@ output should be in the following format:
 <tr><td>score</td><td>Integer giving current evaluation in centipawns.</td></tr>\r
 <tr><td>time</td><td>Current search time in centiseconds (ex:1028 = 10.28 seconds).</td></tr>\r
 <tr><td>nodes</td><td>Nodes searched.</td></tr>\r
+<tr><td>*selective depth</td><td>Maximium length of any branch in the current search.</td></tr>\r
+<tr><td>*speed</td><td>Nodes per second in last measured time interval.</td></tr>\r
+<tr><td>*</td><td>Reserved for future extensions.</td></tr>\r
+<tr><td>*tbhits</td><td>Number of tablebase probes made in the current search.</td></tr>\r
 <tr><td>pv</td><td>Freeform text giving current "best" line.\r
 You can continue the pv onto another line if you start each\r
 continuation line with at least four space characters.</td></tr>\r
 </table>\r
 \r
+<p class="version47">\r
+The items marked with * are optional.\r
+If any of these items is present, the <b>pv</b> field must be preceeded directly by a tab character;\r
+if no tab character preceeds the first non-integer token,\r
+the <b>pv</b> field will start at the first non-blank character after <b>nodes</b>.\r
+Otherwise it will start after the last tab that is not behind any non-integer token.\r
+Of all integers between <b>nodes</b> and <b>pv</b> the last one is intepreted as <b>tbhits</b>.\r
+Of any remaining ones the first is interpreted as <b>selective depth</b>,\r
+and a second as <b>speed</b>.\r
+More infos could be added to this in the future.\r
+Note that older interfaces might consider the optional infos to be part of the <b>pv</b> field,\r
+and display them exactly as sent.\r
+It is therefore encouraged that engines use tabs or spaces to format this optional info\r
+so that it will display nicely in (not too wide) columns.\r
+</p>\r
+\r
 <p>\r
 Example:\r
 </p>\r
index 714873d..75e1f8d 100644 (file)
@@ -30,6 +30,7 @@
 #include "config.h"
 
 #include <stdio.h>
+#include <ctype.h>
 
 #if STDC_HEADERS
 # include <stdlib.h>
@@ -457,6 +458,7 @@ UpdateControls (EngineOutputData *ed)
     char s_label[MAX_NAME_LENGTH + 32];
     int h;
     char * name = ed->name;
+    char *q, *pvStart = ed->pv;
 
     /* Label */
     if( name == 0 || *name == '\0' ) {
@@ -466,6 +468,14 @@ UpdateControls (EngineOutputData *ed)
     strncpy( s_label, name, MAX_NAME_LENGTH );
     s_label[ MAX_NAME_LENGTH-1 ] = '\0';
 
+    if(pvStart) { // [HGM] tbhits: plit up old PV into extra infos and real PV
+        while(strchr(pvStart, '\t')) { // locate last tab before non-int (real PV starts after that)
+            for(q=pvStart; isdigit(*q) || *q == ' '; q++);
+            if(*q != '\t') break;
+            pvStart = q + 1;
+        }
+    }
+
 #ifdef SHOW_PONDERING
     if( IsEnginePondering( ed->which ) ) {
         char buf[12];
@@ -476,18 +486,17 @@ UpdateControls (EngineOutputData *ed)
             strncpy( buf, ed->hint, sizeof(buf) );
             buf[sizeof(buf)-1] = '\0';
         }
-        else if( ed->pv != 0 && *ed->pv != '\0' ) {
-            char * sep, *startPV = ed->pv, c;
+        else if( pvStart != 0 && *pvStart != '\0' ) {
+            char * sep;
             int buflen = sizeof(buf);
 
-            if(sscanf(ed->pv, "{%*d,%*d,%*d}%c", &c) && c == ' ') startPV = strchr(ed->pv, '}') + 2; // [HGM] tbhits
-            sep = strchr( startPV, ' ' );
+            sep = strchr( pvStart, ' ' );
             if( sep != NULL ) {
-                buflen = sep - startPV + 1;
+                buflen = sep - pvStart + 1;
                 if( buflen > sizeof(buf) ) buflen = sizeof(buf);
             }
 
-            strncpy( buf, startPV, buflen );
+            strncpy( buf, pvStart, buflen );
             buf[ buflen-1 ] = '\0';
         }
 
@@ -539,15 +548,15 @@ UpdateControls (EngineOutputData *ed)
     DoSetWindowText( ed->which, nLabelNPS, s_label );
 
     /* Memo */
-    if( ed->pv != 0 && *ed->pv != '\0' ) {
+    if( pvStart != 0 && *pvStart != '\0' ) {
         char s_nodes[24];
         char s_score[16];
         char s_time[24];
         char s_hits[24];
         char s_seld[24];
         char s_knps[24];
-        char buf[256], *pvStart = ed->pv, fail;
-        int buflen, hits, seldep, knps, extra;
+        char buf[256], fail;
+        int buflen, hits, i, params[5], extra;
         int time_secs = ed->time / 100;
         int time_cent = ed->time % 100;
 
@@ -563,11 +572,16 @@ UpdateControls (EngineOutputData *ed)
         }
 
         /* TB Hits etc. */
-        hits = knps = seldep = 0; extra = sscanf(ed->pv, "{%d,%d,%d", &seldep, &knps, &hits);
-        Format(s_seld, seldep); Format(s_knps, knps); Format(s_hits, hits); 
-        if(extra) { // strip extended info from PV
-            if((pvStart = strstr(ed->pv, "} "))) pvStart += 2; else pvStart = ed->pv;
+        for(i=hits=0; i<5; i++) params[i] = 0;
+//fprintf(stderr, "%s\n%s\n", ed->pv, pvStart);
+        if(pvStart != ed->pv) { // check if numbers before PV
+            strncpy(buf, ed->pv, 256); buf[pvStart - ed->pv] = NULLCHAR;
+            extra = sscanf(buf, "%d %d %d %d %d", params, params+1, params+2, params+3, params+4);
+//fprintf(stderr, "extra=%d len=%d\n", extra, pvStart - ed->pv);
+            if(extra) hits = params[extra-1], params[extra-1] = 0; // last one is tbhits
         }
+        Format(s_seld, params[0]); Format(s_knps, params[1]); Format(s_hits, hits); 
+
         fail = ed->pv[strlen(ed->pv)-1];
        if(fail != '?' && fail != '!') fail = ' ';