\r
#include "board.h"\r
#include "engine.h"\r
+#include "gui.h"\r
#include "move.h"\r
#include "move_do.h"\r
#include "move_legal.h"\r
#include "line.h"\r
#include "uci.h"\r
\r
+\r
// constants\r
\r
static const bool UseDebug = FALSE;\r
\r
-static const int StringSize = 4096;\r
+#define StringSize ((int)4096)\r
\r
// variables\r
\r
\r
// functions\r
\r
+\r
+// uci_adapt_UCI3()\r
+\r
+static void apply_UCI3_heuristics(option_t *opt){\r
+ if(option_get_int(Option,"UCIVersion")>2){\r
+ return;\r
+ }\r
+ if(!my_string_equal(opt->type,"string")){\r
+ return;\r
+ }\r
+ if(!strncmp(opt->name,"UCI_",4)){\r
+ return;\r
+ }\r
+ if(my_string_case_contains(opt->name,"file")){\r
+ my_string_set(&opt->type,"file");\r
+ return;\r
+ }\r
+ if(my_string_case_contains(opt->name,"path")){\r
+ my_string_set(&opt->type,"path");\r
+ return;\r
+ }\r
+}\r
+\r
// uci_set_threads()\r
\r
void uci_set_threads(uci_t * uci, int n) {\r
- ASSERT(n>=1);\r
const char *thread_option=uci_thread_option(uci);\r
+ ASSERT(n>=1);\r
if(thread_option){\r
uci_send_option(uci,thread_option,"%d",n);\r
}\r
\r
do {\r
engine_get(uci->engine,string);\r
+ // Handle the case that the engine is really a WB engine somewhat gracefully.\r
+ if((strstr(string,"Illegal") || strstr(string,"Error"))\r
+ &&strstr(string,"uci")){\r
+ my_fatal("uci_open(): Not an UCI engine.\n");\r
+ }\r
event = uci_parse(uci,string);\r
} while (!engine_eof(Engine) && (event & EVENT_UCI) == 0);\r
}\r
uci->best_depth = 0;\r
uci->best_sel_depth = 0;\r
line_clear(uci->best_pv);\r
-\r
- uci->node_nb = 0;\r
+// make the default 1 instead of 0 so that info lines can be recognized by their node number 0\r
+ uci->node_nb = 1;\r
uci->time = 0.0;\r
uci->speed = 0.0;\r
uci->cpu = 0.0;\r
uci->root_move = MoveNone;\r
uci->root_move_pos = 0;\r
uci->root_move_nb = board_mobility(uci->board);\r
+\r
+ uci->multipvSP=0;\r
}\r
\r
// uci_send_isready()\r
opt=option_find(uci->option,option);\r
if(opt){\r
found=TRUE;\r
- if(!my_string_case_equal(opt->type,"button")){\r
+ if(!IS_BUTTON(opt->type)){\r
if(!my_string_equal(opt->value,value)){\r
engine_send(uci->engine,"setoption name %s value %s",\r
opt->name,value);\r
parse_open(parse,string);\r
\r
if (parse_get_word(parse,command,StringSize)) {\r
-\r
+ \r
parse_get_string(parse,argument,StringSize);\r
if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" ARGUMENT \"%s\"\n",command,argument);\r
\r
ASSERT(!my_string_empty(argument));\r
\r
n = atoi(argument);\r
- if(Uci->multipv_mode) multipvline=n;\r
+ multipvline=n;\r
\r
ASSERT(n>=1);\r
\r
}else if(my_string_case_equal(argument,"Resign")){\r
event |= EVENT_RESIGN;\r
}else{\r
- strcpy(uci->info,argument);\r
+ snprintf(uci->info,sizeof(uci->info),"%s",argument);\r
+ uci->info[sizeof(uci->info)-1]='\0';\r
event|=EVENT_INFO;\r
}\r
// TODO: argument to EOS\r
} else {\r
\r
my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
- // this is for buggy engines; it should probably be protected\r
+ // This should probably be protected\r
// by a "WorkAround" option.\r
- strcpy(uci->info,option);\r
- strcat(uci->info," ");\r
- strcat(uci->info,argument);\r
+ snprintf(uci->info,sizeof(uci->info),"%s %s",option,argument);\r
+ uci->info[sizeof(uci->info)-1]='\0';\r
event|=EVENT_INFO;\r
}\r
}\r
\r
parse_close(parse);\r
\r
- // update display\r
- //lousy uci,filter out lower depth multipv lines that have been repeated from the engine \r
- if(multipvline>1 && uci->depth<uci->best_depth) event &= ~EVENT_PV;\r
+\r
+ // code by HGM\r
if ((event & EVENT_PV) != 0) {\r
uci->best_score = uci->score; \r
- uci->best_depth = uci->depth;\r
- if(multipvline==1)uci->depth=-1; //HACK ,clears the engine outpout window,see send_pv in adapter.cpp \r
uci->best_sel_depth = uci->sel_depth;\r
line_copy(uci->best_pv,uci->pv);\r
}\r
+ if(uci->depth < uci->best_depth){\r
+ // ignore lines of lower depth\r
+ event &= ~EVENT_PV;\r
+ } else {\r
+ if(uci->depth > uci->best_depth) {\r
+ // clear stack when we start new depth\r
+ uci->multipvSP = 0; \r
+ }\r
+ uci->best_depth = uci->depth;\r
+ if(multipvline >= 1) {\r
+ int i;\r
+ for(i=0; i<uci->multipvSP; i++) {\r
+ if(uci->score == uci->multipvScore[i] && uci->pv[0] == uci->multipvMove[i]) {\r
+ event &= ~EVENT_PV; // ignore duplicates\r
+ }\r
+ }\r
+ if(event & EVENT_PV){\r
+ // line is new, try to add to stack\r
+ if(uci->multipvSP<MultiPVStackSize){\r
+ uci->multipvMove[uci->multipvSP] = uci->pv[0];\r
+ uci->multipvScore[uci->multipvSP] = uci->score;\r
+ uci->multipvSP++;\r
+ }else{\r
+ my_fatal("parse_info(): multipv stack overflow.");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+\r
return event;\r
}\r
\r
}\r
\r
parse_close(parse);\r
+\r
+ apply_UCI3_heuristics(opt);\r
option_insert(uci->option,opt);\r
option_free(opt);\r
\r