version 1.4.34b
[polyglot.git] / xboard2uci.c
index d255d6f..97c7b73 100644 (file)
@@ -108,6 +108,7 @@ static void stop_search    ();
 \r
 static void send_board     (int extra_move);\r
 static void send_pv        ();\r
+static void send_info      ();\r
 \r
 static void send_xboard_options ();\r
 \r
@@ -135,10 +136,10 @@ void xboard2uci_init() {
    my_timer_reset(State->timer);\r
 \r
    // yes there are engines that do not have the "Hash" option....\r
-   XB->has_feature_memory= uci_option_exist(Uci,"Hash");\r
-   XB->has_feature_smp = uci_thread_option_exist(Uci);\r
+   XB->has_feature_memory= (option_find(Uci->option,"Hash")!=NULL);\r
+   XB->has_feature_smp = (uci_thread_option(Uci)!=NULL);\r
    // TODO: support for other types of table bases\r
-   XB->has_feature_egt = uci_option_exist(Uci,"NalimovPath");\r
+   XB->has_feature_egt = (option_find(Uci->option,"NalimovPath")!=NULL);\r
    XB->analyse = FALSE;\r
    XB->computer = FALSE;\r
    XB->name = NULL;\r
@@ -193,7 +194,7 @@ void xboard2uci_gui_step(char string[]) {
 \r
                } else if (match(string,"bk")) {\r
 \r
-                       if (option_get_bool("Book")) {\r
+                       if (option_get_bool(Option,"Book")) {\r
                                game_get_board(Game,board);\r
                                book_disp(board);\r
                        }\r
@@ -216,7 +217,7 @@ void xboard2uci_gui_step(char string[]) {
                        XB->computer = TRUE;\r
 \r
                } else if (match(string,"draw")) {\r
-                       if(uci_option_exist(Uci,"UCI_DrawOffers")){\r
+                       if(option_find(Uci->option,"UCI_DrawOffers")){\r
                            my_log("POLYGLOT draw from XB received");\r
                                uci_send_option(Uci,"DrawOffer","%s","draw");}\r
                } else if (match(string,"easy")) {\r
@@ -266,7 +267,7 @@ void xboard2uci_gui_step(char string[]) {
 \r
                } else if (match(string,"hint")) {\r
 \r
-                       if (option_get_bool("Book")) {\r
+                       if (option_get_bool(Option,"Book")) {\r
 \r
                                game_get_board(Game,board);\r
                                move = book_move(board,FALSE);\r
@@ -302,7 +303,7 @@ void xboard2uci_gui_step(char string[]) {
             uci_send_isready(Uci);\r
                        my_log("POLYGLOT NEW GAME\n");\r
 \r
-                       option_set("Chess960","false");\r
+                       option_set(Option,"Chess960","false");\r
 \r
                        game_clear(Game);\r
 \r
@@ -371,7 +372,8 @@ void xboard2uci_gui_step(char string[]) {
                        XB->post = TRUE;\r
 \r
                } else if (match(string,"protover *")) {\r
-\r
+            XB->proto_ver = atoi(Star[0]);\r
+            ASSERT(XB->proto_ver>=2);\r
             send_xboard_options();\r
 \r
                } else if (match(string,"quit")) {\r
@@ -423,7 +425,8 @@ void xboard2uci_gui_step(char string[]) {
 \r
                                // book learning\r
 \r
-                               if (option_get_bool("Book") && option_get_bool("BookLearn")) {\r
+                               if (option_get_bool(Option,"Book") &&\r
+                    option_get_bool(Option,"BookLearn")) {\r
 \r
                                        if (FALSE) {\r
                                        } else if (my_string_equal(Star[0],"1-0")) {\r
@@ -440,7 +443,11 @@ void xboard2uci_gui_step(char string[]) {
 \r
                        gui_send(GUI,"Error (unknown command): %s",string);\r
 \r
-        } else if (match(string,"option *=*")){\r
+        } else if (match(string,"option *=*")   ||\r
+                   match(string,"option * =*") ||\r
+                   match(string,"option *= *") ||\r
+                   match(string,"option * = *")\r
+                   ){\r
             char *name=Star[0];\r
             char *value=Star[1];\r
             if(match(name, "Polyglot *")){\r
@@ -448,13 +455,18 @@ void xboard2uci_gui_step(char string[]) {
                 polyglot_set_option(pg_name,value);\r
             }else{\r
                 start_protected_command();\r
-                engine_send(Engine,"setoption name %s value %s",name,value);\r
+                if(!uci_send_option(Uci, name, "%s", value)){\r
+                    gui_send(GUI,"Error (unknown option): %s",name); \r
+                }\r
                 end_protected_command();\r
             }\r
         } else if (match(string,"option *")){\r
             char *name=Star[0];\r
             start_protected_command();\r
-            engine_send(Engine,"setoption name %s",name);\r
+                // value is ignored\r
+            if(!uci_send_option(Uci, name, "%s", "<empty>")){\r
+               gui_send(GUI,"Error (unknown option): %s",name); \r
+            }; \r
             end_protected_command();\r
         } else if (XB->has_feature_smp && match(string,"cores *")){\r
                 int cores=atoi(Star[0]);\r
@@ -490,9 +502,10 @@ void xboard2uci_gui_step(char string[]) {
             int real_memory;\r
             if(memory>=1){\r
                 // updating the available memory\r
+                option_t *opt;\r
                 my_log("POLYGLOT setting the amount of memory to %dMb\n",memory);\r
-                if(uci_get_option(Uci,"NalimovCache")>=0){\r
-                    nalimov_cache=atoi(Uci->option[uci_get_option(Uci,"NalimovCache")].value);\r
+                if((opt=option_find(Uci->option,"NalimovCache"))){\r
+                    nalimov_cache=atoi(opt->value);\r
                 }else{\r
                     nalimov_cache=0;\r
                 }\r
@@ -574,9 +587,9 @@ void xboard2uci_gui_step(char string[]) {
                } else if (match(string,"variant *")) {\r
 \r
                        if (my_string_equal(Star[0],"fischerandom")) {\r
-                               option_set("Chess960","true");\r
+                               option_set(Option,"Chess960","true");\r
                        } else {\r
-                               option_set("Chess960","false");\r
+                               option_set(Option,"Chess960","false");\r
                        }\r
 \r
                } else if (match(string,"white")) {\r
@@ -658,6 +671,7 @@ void xboard2uci_gui_step(char string[]) {
 void xboard2uci_engine_step(char string[]) {\r
 \r
        int event;\r
+    board_t board[1];\r
                event = uci_parse(Uci,string);\r
 \r
                // react to events\r
@@ -702,15 +716,33 @@ void xboard2uci_engine_step(char string[]) {
 \r
                        send_pv();\r
                }\r
+               if ((event & EVENT_INFO) != 0) {\r
+\r
+                       // the engine has sent info\r
+\r
+                       send_info();\r
+               }\r
                if((event & (EVENT_DRAW|EVENT_RESIGN))!=0){\r
                        my_log("POYGLOT draw offer/resign from engine\n");\r
-                       if(uci_option_exist(Uci,"UCI_DrawOffers")){\r
+                       if(option_find(Uci->option,"UCI_DrawOffers")){\r
                                if(event & EVENT_DRAW)\r
                                        gui_send(GUI,"offer draw");\r
                                else\r
                                        gui_send(GUI,"resign");\r
                        }\r
                }\r
+               if(((event & EVENT_ILLEGAL_MOVE)!=0) && (State->state == THINK)){\r
+            game_get_board(Game,board);\r
+            if(board->turn==White){\r
+                gui_send(GUI,"0-1 {polyglot: resign"\r
+                            " (illegal engine move white)}");\r
+            }else{\r
+                gui_send(GUI,"1-0 {polyglot: resign"\r
+                         " (illegal engine move black)}");\r
+            }\r
+            XB->result = TRUE;\r
+            mess();\r
+        }\r
 }\r
 \r
 // format_xboard_option_line\r
@@ -718,7 +750,9 @@ void xboard2uci_engine_step(char string[]) {
 void format_xboard_option_line(char * option_line, option_t *opt){\r
     int j;\r
     char option_string[StringSize];\r
+    char *tmp;\r
     strcpy(option_line,"");\r
+        // buffer overflow alert\r
     strcat(option_line,"feature option=\"");\r
     if(opt->mode&PG){\r
         strcat(option_line,"Polyglot ");\r
@@ -756,17 +790,21 @@ void format_xboard_option_line(char * option_line, option_t *opt){
         }\r
     }\r
     strcat(option_line,"\"");\r
+    if(option_get_bool(Option,"WbWorkArounds") &&\r
+       (tmp=strstr(option_line,"Draw"))){\r
+        *tmp='d';\r
+        my_log("POLYGLOT Decapitalizing \"Draw\" in option \"%s\"\n",\r
+               opt->name);\r
+    }\r
 }\r
 \r
-// send_xboard_options\r
+// send_xboard_options()\r
 \r
 static void send_xboard_options(){\r
-    int i;\r
+\r
     char option_line[StringSize]="";\r
-    option_t *p=Option;\r
     const char * name;\r
-    XB->proto_ver = atoi(Star[0]);\r
-    ASSERT(XB->proto_ver>=2);\r
+    option_t *opt;\r
     \r
     gui_send(GUI,"feature done=0");\r
     \r
@@ -774,7 +812,8 @@ static void send_xboard_options(){
     gui_send(GUI,"feature colors=0");\r
     gui_send(GUI,"feature draw=1");\r
     gui_send(GUI,"feature ics=1");\r
-    gui_send(GUI,"feature myname=\"%s\"",option_get_string("EngineName"));\r
+    gui_send(GUI,"feature myname=\"%s\"",\r
+             option_get_string(Option,"EngineName"));\r
     gui_send(GUI,"feature name=1");\r
     gui_send(GUI,"feature pause=0");\r
     gui_send(GUI,"feature ping=1");\r
@@ -803,34 +842,33 @@ static void send_xboard_options(){
         gui_send(GUI,"feature egt=\"\"");\r
     }\r
     \r
-    if (uci_option_exist(Uci,"UCI_Chess960")) {\r
+    if (option_find(Uci->option,"UCI_Chess960")) {\r
         gui_send(GUI,"feature variants=\"normal,fischerandom\"");\r
     } else {\r
         gui_send(GUI,"feature variants=\"normal\"");\r
     }\r
-    \r
-    for(i=0;i<Uci->option_nb;i++){\r
-        if(my_string_case_equal(Uci->option[i].name,"UCI_AnalyseMode")) continue;\r
-        if(my_string_case_equal(Uci->option[i].name,"Ponder")) continue;\r
-        if(my_string_case_equal(Uci->option[i].name,"Hash")) continue;\r
-        if(my_string_case_equal(Uci->option[i].name,"NalimovPath")) continue;\r
-        if((name=uci_thread_option(Uci))!=NULL && my_string_case_equal(Uci->option[i].name,name)) continue;\r
-        if(option_get_bool("WbWorkArounds") &&\r
-           strstr(Uci->option[i].name,"Draw")){\r
-            my_log("POLYGLOT Dropping option \"%s\" because it contains \"Draw\"\n",Uci->option[i].name);\r
-            continue;\r
-        }\r
-        format_xboard_option_line(option_line,Uci->option+i);\r
 \r
+    option_start_iter(Uci->option);\r
+    while((opt=option_next(Uci->option))){\r
+        if(my_string_case_equal(opt->name,"UCI_AnalyseMode")) continue;\r
+        if(my_string_case_equal(opt->name,"Ponder")) continue;\r
+        if(my_string_case_equal(opt->name,"Hash")) continue;\r
+        if(my_string_case_equal(opt->name,"NalimovPath")) continue;\r
+        if((name=uci_thread_option(Uci))!=NULL &&\r
+           my_string_case_equal(opt->name,name)) continue;\r
+        \r
+        format_xboard_option_line(option_line,opt);\r
+        \r
         gui_send(GUI,"%s",option_line);\r
-\r
     }\r
-    while(p->name){\r
-        if(p->mode &XBOARD){\r
-            format_xboard_option_line(option_line,p);\r
+\r
+\r
+    option_start_iter(Option);\r
+    while((opt=option_next(Option))){\r
+        if(opt->mode &XBOARD){\r
+            format_xboard_option_line(option_line,opt);\r
             gui_send(GUI,"%s",option_line);\r
         }\r
-        p++;\r
     }       \r
     gui_send(GUI,"feature done=1"); \r
     \r
@@ -839,7 +877,8 @@ static void send_xboard_options(){
 // report_best_score()\r
 \r
 static int report_best_score(){\r
-    if(!option_get_bool("ScoreWhite") || colour_is_white(Uci->board->turn)){\r
+    if(!option_get_bool(Option,"ScoreWhite") ||\r
+       colour_is_white(Uci->board->turn)){\r
         return Uci->best_score;\r
     }else{\r
         return -Uci->best_score;\r
@@ -858,14 +897,14 @@ static void comp_move(int move) {
    ASSERT(State->state==THINK);\r
    ASSERT(!XB->analyse);\r
 \r
-   if(option_get_bool("RepeatPV"))\r
+   if(option_get_bool(Option,"RepeatPV"))\r
           send_pv(); // to update time and nodes\r
 \r
    // send the move\r
 \r
    game_get_board(Game,board);\r
 \r
-   if (move_is_castle(move,board) && option_get_bool("Chess960")) {\r
+   if (move_is_castle(move,board) && option_get_bool(Option,"Chess960")) {\r
       if (!move_to_san(move,board,string,256)) my_fatal("comp_move(): move_to_san() failed\n"); // O-O/O-O-O\r
    } else {\r
       if (!move_to_can(move,board,string,256)) my_fatal("comp_move(): move_to_can() failed\n");\r
@@ -875,14 +914,14 @@ static void comp_move(int move) {
 \r
    // resign?\r
 \r
-   if (option_get_bool("Resign") && Uci->root_move_nb > 1) {\r
+   if (option_get_bool(Option,"Resign") && Uci->root_move_nb > 1) {\r
 \r
-      if (Uci->best_score <= -abs(option_get_int("ResignScore"))) {\r
+       if (Uci->best_score <= -abs(option_get_int(Option,"ResignScore"))) {\r
 \r
          State->resign_nb++;\r
          my_log("POLYGLOT %d move%s with resign score\n",State->resign_nb,(State->resign_nb>1)?"s":"");\r
 \r
-         if (State->resign_nb >= option_get_int("ResignMoves")) {\r
+         if (State->resign_nb >= option_get_int(Option,"ResignMoves")) {\r
             my_log("POLYGLOT *** RESIGN ***\n");\r
             gui_send(GUI,"resign");\r
          }\r
@@ -1153,11 +1192,11 @@ static void search_update() {
 \r
       // opening book\r
 \r
-      if (State->state == THINK && option_get_bool("Book")) {\r
+       if (State->state == THINK && option_get_bool(Option,"Book")) {\r
 \r
          game_get_board(Game,Uci->board);\r
 \r
-         move = book_move(Uci->board,option_get_bool("BookRandom"));\r
+         move = book_move(Uci->board,option_get_bool(Option,"BookRandom"));\r
 \r
          if (move != MoveNone && move_is_legal(move,Uci->board)) {\r
 \r
@@ -1186,9 +1225,10 @@ static void search_update() {
 \r
       // options\r
 \r
-      uci_send_option(Uci,"UCI_Chess960","%s",option_get_bool("Chess960")?"true":"false");\r
+      uci_send_option(Uci,"UCI_Chess960","%s",\r
+                      option_get_bool(Option,"Chess960")?"true":"false");\r
 \r
-      if (option_get_int("UCIVersion") >= 2) {\r
+      if (option_get_int(Option,"UCIVersion") >= 2) {\r
          uci_send_option(Uci,"UCI_Opponent","none none %s %s",(XB->computer)?"computer":"human",XB->name);\r
          uci_send_option(Uci,"UCI_AnalyseMode","%s",(XB->analyse)?"true":"false");\r
       }\r
@@ -1291,7 +1331,8 @@ static bool active() {
 \r
 static bool ponder() {\r
 \r
-   return XB->ponder && (option_get_bool("CanPonder") || uci_option_exist(Uci,"Ponder"));\r
+    return XB->ponder && (option_get_bool(Option,"CanPonder") ||\r
+                          option_find(Uci->option,"Ponder"));\r
 }\r
 // ponder_ok()\r
 \r
@@ -1319,7 +1360,7 @@ static bool ponder_ok(int move) {
 \r
    if (status != PLAYING) return FALSE; // game ended\r
 \r
-   if (option_get_bool("Book") && is_in_book(board)) {\r
+   if (option_get_bool(Option,"Book") && is_in_book(board)) {\r
       return FALSE;\r
    }\r
 \r
@@ -1342,7 +1383,7 @@ static void stop_search() {
       Uci->searching = FALSE;\r
 */\r
 \r
-      if (option_get_bool("SyncStop")) {\r
+      if (option_get_bool(Option,"SyncStop")) {\r
          uci_send_stop_sync(Uci);\r
       } else {\r
          uci_send_stop(Uci);\r
@@ -1418,6 +1459,15 @@ static void send_board(int extra_move) {
    engine_send(Engine,""); // newline\r
 }\r
 \r
+// send_info()\r
+\r
+static void send_info() {\r
+    if (XB->post) {\r
+        gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth>0?Uci->best_depth:1,\r
+                 0,0,0.0,0,Uci->info);  \r
+    }  \r
+}\r
+\r
 // send_pv()\r
 \r
 static void send_pv() {\r
@@ -1444,7 +1494,8 @@ static void send_pv() {
 \r
                 gui_send(GUI,"%d %+d %.0f "S64_FORMAT" %s",Uci->best_depth,report_best_score(),Uci->time*100.0,Uci->node_nb,pv_string);\r
 \r
-      } else if (State->state == PONDER && option_get_bool("ShowPonder")) {\r
+      } else if (State->state == PONDER &&\r
+                 option_get_bool(Option,"ShowPonder")) {\r
 \r
          game_get_board(Game,board);\r
          move = State->exp_move;\r
@@ -1459,14 +1510,16 @@ static void send_pv() {
 \r
    // kibitz\r
 \r
-   if ((Uci->searching && option_get_bool("KibitzPV") && Uci->time >= option_get_double("KibitzDelay"))\r
-    || (!Uci->searching && option_get_bool("KibitzMove"))) {\r
+   if ((Uci->searching &&\r
+        option_get_bool(Option,"KibitzPV") &&\r
+        Uci->time >= option_get_double(Option,"KibitzDelay"))\r
+       || (!Uci->searching && option_get_bool(Option,"KibitzMove"))) {\r
 \r
       if (State->state == THINK || State->state == ANALYSE) {\r
 \r
          line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize);\r
          if(kibitz_throttle(Uci->searching)){\r
-             gui_send(GUI,"%s depth=%d time=%.2f node="S64_FORMAT" speed=%.0f score=%+.2f pv=\"%s\"",option_get_string("KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,((double)report_best_score())/100.0,pv_string);\r
+             gui_send(GUI,"%s depth=%d time=%.2f node="S64_FORMAT" speed=%.0f score=%+.2f pv=\"%s\"",option_get_string(Option,"KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,((double)report_best_score())/100.0,pv_string);\r
          }\r
       } else if (State->state == PONDER) {\r
 \r
@@ -1477,7 +1530,7 @@ static void send_pv() {
             move_to_san(move,board,move_string,256);\r
             line_to_san(Uci->best_pv,Uci->board,pv_string,StringSize);\r
             if(kibitz_throttle(Uci->searching)){\r
-                gui_send(GUI,"%s depth=%d time=%.2f node="S64_FORMAT" speed=%.0f score=%+.2f pv=\"(%s) %s\"",option_get_string("KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,((double)report_best_score())/100.0,move_string,pv_string);\r
+                gui_send(GUI,"%s depth=%d time=%.2f node="S64_FORMAT" speed=%.0f score=%+.2f pv=\"(%s) %s\"",option_get_string(Option,"KibitzCommand"),Uci->best_depth,Uci->time,Uci->node_nb,Uci->speed,((double)report_best_score())/100.0,move_string,pv_string);\r
             }\r
          }\r
       }\r
@@ -1492,12 +1545,14 @@ static bool kibitz_throttle(bool searching){
     static time_t lastKibitzPV=0;\r
     curr_time = time(NULL);\r
     if(searching){   // KibitzPV\r
-        if(curr_time >= (option_get_int("KibitzInterval") + lastKibitzPV)){\r
+        if(curr_time >=\r
+           (option_get_int(Option,"KibitzInterval") + lastKibitzPV)){\r
             lastKibitzPV=curr_time;\r
             return TRUE;\r
         }\r
     }else{       // KibitzMove\r
-        if(curr_time >= (option_get_int("KibitzInterval") + lastKibitzMove)){\r
+        if(curr_time >=\r
+           (option_get_int(Option,"KibitzInterval") + lastKibitzMove)){\r
             lastKibitzPV=curr_time;\r
             lastKibitzMove=curr_time;\r
             return TRUE;\r
@@ -1555,4 +1610,4 @@ static void learn(int result) {
    book_flush();\r
 }\r
 \r
-// end of adapter.cpp\r
+// end of xboard2uci.c\r