Alter version number to 2.0.4
[polyglot.git] / xboard2uci.c
index 4f019a9..4ddb72e 100644 (file)
@@ -56,6 +56,7 @@ typedef struct {
     bool has_feature_smp;
     bool has_feature_egt_nalimov;
     bool has_feature_egt_gaviota;
+    bool has_feature_egt_syzygy;
     bool analyse;
     bool computer;
     const char * name;
@@ -150,6 +151,7 @@ void xboard2uci_init() {
    // This is a quick hack. 
    XB->has_feature_egt_nalimov = (option_find(Uci->option,"NalimovPath")!=NULL);
    XB->has_feature_egt_gaviota = (option_find(Uci->option,"GaviotaTbPath")!=NULL);
+   XB->has_feature_egt_syzygy  = (option_find(Uci->option,"SyzygyPath")!=NULL);
    XB->analyse = FALSE;
    XB->computer = FALSE;
    XB->name = NULL;
@@ -213,22 +215,21 @@ void xboard2uci_gui_step(char string[]) {
                                game_get_board(Game,board);
                                book_disp(board);
                        } else { // [HGM] without book, print all legal moves
-                               int i;
+                               int i, gen=!list_size(move_list);
                                game_get_board(Game,board);
-                               gen_legal_moves(move_list,board);
+                               if(gen) gen_legal_moves(move_list,board);
                                for(i=0; i<list_size(move_list); i++){
-                                       move_list->value[i] = 0;
+                                       if(gen) move_list->value[i] = 0;
                                        move_to_san(move_list->move[i],board,move_string,256);
-                                       printf(" %6s\n",move_string);
+                                       printf(" %s%6s\n", move_list->value[i]? "* " : "", move_string);
                                }
                                // this is necessary by the xboard protocol
                                printf("\n");
                        }
 
-               } else if (match(string,"kill *") || match(string,"option Polyglot exclude move=*")) { // [HGM] 
+               } else if (match(string,"exclude *") || match(string,"option Polyglot exclude move=*")) { // [HGM] 
 
-                       if (XB->analyse) {
-                               int i;
+                               int i, all = !strcmp(Star[0], "all"), change=FALSE, cnt=0;
                                game_get_board(Game,board);
                                if(!list_size(move_list)) {
                                        gen_legal_moves(move_list,board);
@@ -239,10 +240,23 @@ void xboard2uci_gui_step(char string[]) {
                                move = move_from_san(Star[0],board);
 
                                for(i=0; i<list_size(move_list); i++){
-                                       if(move_list->move[i] == move) move_list->value[i] = 1;
+                                       if(all || move_list->move[i] == move)
+                                               change |= !move_list->value[i], move_list->value[i] = 1;
+                                       cnt += !move_list->value[i];
                                }
-                               mess();
+                               if(change && cnt) mess(); // do not relay to engine if no change or no moves left
+
+               } else if (match(string,"include *")) { // [HGM] 
+
+                       int i, all = !strcmp(Star[0], "all"), change = FALSE;
+                       game_get_board(Game,board);
+                       move = move_from_san(Star[0],board);
+
+                       for(i=0; i<list_size(move_list); i++){
+                               if(all || move_list->move[i] == move)
+                                       change |= move_list->value[i], move_list->value[i] = 0;
                        }
+                       if(change) mess();
 
                } else if (match(string,"black")) {
 
@@ -360,6 +374,8 @@ void xboard2uci_gui_step(char string[]) {
 
                        game_clear(Game);
 
+                       move_list->size = 0; // [HGM] clear all exclude moves
+
                        if (XB->analyse) {
                                State->computer[White] = FALSE;
                                State->computer[Black] = FALSE;
@@ -375,6 +391,9 @@ void xboard2uci_gui_step(char string[]) {
 
                        XB->depth_limit = FALSE;
             XB->node_rate=-1;
+            if (option_find(Uci->option,"UCI_PlayByNodes")) {
+                uci_send_option(Uci,"UCI_PlayByNodes","%d",0);
+            }
 
                        XB->computer = FALSE;
                        my_string_set(&XB->name,"<empty>");
@@ -412,7 +431,12 @@ void xboard2uci_gui_step(char string[]) {
                                gui_send(GUI,"pong %s",Star[0]);
                        }
         } else if (match(string,"nps *")) {
-            
+
+            if (Star[0] > 0 && option_find(Uci->option,"UCI_PlayByNodes")) {
+
+                uci_send_option(Uci,"UCI_PlayByNodes","%d",Star[0]);
+
+            } else
                 // fake WB play-by-nodes mode
             XB->node_rate = atoi(Star[0]);
                } else if (match(string,"playother")) {
@@ -569,6 +593,12 @@ void xboard2uci_gui_step(char string[]) {
                        start_protected_command();
                        uci_send_option(Uci,"GaviotaTbPath","%s",path);
                        end_protected_command();
+                   }else if(my_string_case_equal(type,"syzygy") && XB->has_feature_egt_syzygy){
+                       // updating SyzygyPath
+                       my_log("POLYGLOT setting the Syzygy path to %s\n",path);
+                       start_protected_command();
+                       uci_send_option(Uci,"SyzygyPath","%s",path);
+                       end_protected_command();
                    }else{
                        // refuse
                        gui_send(GUI,"Error (unsupported table base format): %s",string);
@@ -581,17 +611,22 @@ void xboard2uci_gui_step(char string[]) {
             if(memory>=1){
                 // updating the available memory
                 option_t *opt;
+               int h;
                 my_log("POLYGLOT setting the amount of memory to %dMb\n",memory);
+                egt_cache=0;
                 if(XB->has_feature_egt_nalimov && (opt=option_find(Uci->option,"NalimovCache"))){
-                    egt_cache=atoi(opt->value);
-                }else if(XB->has_feature_egt_gaviota && 
+                   h=atoi(opt->value);
+                    if(h>egt_cache)egt_cache=h;
+                }
+               if(XB->has_feature_egt_gaviota && 
                         (opt=option_find(Uci->option,"GaviotaTbCache"))){
-                   egt_cache=atoi(opt->value);
-               }else{
-                    egt_cache=0;
+                   h=atoi(opt->value);
+                    if(h>egt_cache)egt_cache=h;
                 }
                 my_log("POLYGLOT EGTB Cache is %dMb\n",egt_cache);
                 real_memory=memory-egt_cache;
+               opt=option_find(Uci->option,"Hash");
+               if(opt && real_memory > atoi(opt->max)) real_memory = atoi(opt->max); // [HGM] top off
                 if(real_memory>0){
                     start_protected_command();
                     uci_send_option(Uci,"Hash", "%d", real_memory);
@@ -613,6 +648,8 @@ void xboard2uci_gui_step(char string[]) {
 
                        if (!game_init(Game,Star[0])) my_fatal("xboard_step(): bad FEN \"%s\"\n",Star[0]);
 
+                       move_list->size = 0; // [HGM] clear all exclude moves
+
                        State->computer[White] = FALSE;
                        State->computer[Black] = FALSE;
 
@@ -956,8 +993,15 @@ static void send_xboard_options(){
        if(tbs>0){
            strncat(egtfeature,",",StringSize-strlen(egtfeature));
        }
+       tbs++;
        strncat(egtfeature,"gaviota",StringSize-strlen(egtfeature));
     }
+    if (XB->has_feature_egt_syzygy){
+       if(tbs>0){
+           strncat(egtfeature,",",StringSize-strlen(egtfeature));
+       }
+       strncat(egtfeature,"syzygy",StringSize-strlen(egtfeature));
+    }
     strncat(egtfeature,"\"",StringSize-strlen(egtfeature));
     egtfeature[StringSize-1]='\0';
     gui_send(GUI,egtfeature);
@@ -986,10 +1030,12 @@ void xboard2uci_send_options(){
     if(my_string_case_equal(opt->name,"UCI_ShredderbasesPath")) continue;
     if(my_string_case_equal(opt->name,"UCI_SetPositionValue")) continue;
     if(my_string_case_equal(opt->name,"UCI_DrawOffers")) continue;
+    if(my_string_case_equal(opt->name,"UCI_PlayByNodes")) continue;
     if(my_string_case_equal(opt->name,"Ponder")) continue;
     if(my_string_case_equal(opt->name,"Hash")) continue;
     if(my_string_case_equal(opt->name,"NalimovPath")) continue;
     if(my_string_case_equal(opt->name,"GaviotaTbPath")) continue;
+    if(my_string_case_equal(opt->name,"SyzygyPath")) continue;
     if((name=uci_thread_option(Uci))!=NULL &&
        my_string_case_equal(opt->name,name)) continue;
     format_xboard_option_line(option_line,opt);
@@ -1672,12 +1718,16 @@ static void send_info() {
     }else{
         min_depth=1;
     }
+    if(!strncmp(Uci->info, "xboard ", 7)) gui_send(GUI,"%s",Uci->info+7); else // kludge to allow UCI engines to use WB protocol
     gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth>min_depth?Uci->best_depth:min_depth,
             0,0.0,U64(0),Uci->info);  
 }
 
 // send_pv()
 
+//define EXT_INFO_FORMAT  "{%d,%.0f,"S64_FORMAT"} "
+#define EXT_INFO_FORMAT  " %2d %4.0f "S64_FORMAT"\t"
+
 static void send_pv() {
 
    char pv_string[StringSize];
@@ -1699,8 +1749,11 @@ static void send_pv() {
 
                 if(Uci->depth==-1) //hack to clear the engine output window
              gui_send(GUI,"%d %+d %.0f "S64_FORMAT" ",0,report_best_score(),Uci->time*100.0,Uci->node_nb);
-
-                gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,pv_string);
+               if(option_get_bool(Option,"ShowTbHits"))
+                gui_send(GUI,"%d %+d %.0f "S64_FORMAT EXT_INFO_FORMAT"%s%c",Uci->best_depth,report_best_score(),
+                       Uci->time*100.0,Uci->node_nb,Uci->sel_depth,Uci->speed/1e3,Uci->tbhit_nb,pv_string,Uci->bound_type);
+               else
+                gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s%c",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,pv_string,Uci->bound_type);
 
       } else if (State->state == PONDER &&
                  option_get_bool(Option,"ShowPonder")) {
@@ -1711,7 +1764,12 @@ static void send_pv() {
          if (move != MoveNone && move_is_legal(move,board)) {
             move_to_san(move,board,move_string,256);
             line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize);
-            gui_send(GUI,"%d %+d %.0f "S64_FORMAT" (%s) %s",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,move_string,pv_string);
+           if(option_get_bool(Option,"ShowTbHits"))
+                gui_send(GUI,"%d %+d %.0f "S64_FORMAT EXT_INFO_FORMAT"(%s) %s%c",Uci->best_depth,report_best_score(),
+                       Uci->time*100.0,Uci->node_nb,Uci->sel_depth,Uci->speed/1e3,Uci->tbhit_nb,move_string,pv_string,Uci->bound_type);
+           else
+               gui_send(GUI,"%d %+d %.0f "S64_FORMAT" (%s) %s%c",Uci->best_depth,report_best_score(),
+                       Uci->time*100.0,Uci->node_nb,move_string,pv_string,Uci->bound_type);
          }
       }
    }