--- /dev/null
+\r
+// uci.c\r
+\r
+// includes\r
+\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "board.h"\r
+#include "engine.h"\r
+#include "move.h"\r
+#include "move_do.h"\r
+#include "move_legal.h"\r
+#include "option.h"\r
+#include "parse.h"\r
+#include "line.h"\r
+#include "uci.h"\r
+\r
+// constants\r
+\r
+static const bool UseDebug = FALSE;\r
+\r
+static const int StringSize = 4096;\r
+\r
+// variables\r
+\r
+uci_t Uci[1];\r
+\r
+// Hopefully the following confusion is temporary\r
+// Normally we should check for the engine name but this is a hack anyway\r
+// Some of there where provided by Marc Lacrosse\r
+\r
+const char * thread_options[]={\r
+ "number of threads", // toga\r
+ "number threads", // Deep Learning Toga\r
+ "threads", // glaurung, zappa, cyclone, grapefruit,\r
+ // Deep Shredder, Deep Junior\r
+ "core threads", // HIARCS\r
+ "max cpus", // rybka\r
+ "cpus", // Deep Sjeng, Fruit2.3.5\r
+ "maxthreads", // Naum \r
+ NULL\r
+};\r
+\r
+// prototypes\r
+\r
+static bool uci_is_ok (const uci_t * uci);\r
+\r
+static int parse_bestmove (uci_t * uci, const char string[]);\r
+static void parse_id (uci_t * uci, const char string[]);\r
+static int parse_info (uci_t * uci, const char string[]);\r
+static void parse_option (uci_t * uci, const char string[]);\r
+static void parse_score (uci_t * uci, const char string[]);\r
+\r
+static int mate_score (int dist);\r
+\r
+// functions\r
+\r
+// uci_set_threads()\r
+\r
+void uci_set_threads(uci_t * uci, int n) {\r
+ const char **thread_options_copy = thread_options;\r
+ const char *thread_option;\r
+ ASSERT(n>=1);\r
+ while((thread_option = *(thread_options_copy++))){\r
+ uci_send_option(uci,thread_option,"%d",n); // checks also for existence\r
+ }\r
+}\r
+\r
+// uci_thread_option_exists()\r
+\r
+bool uci_thread_option_exist(uci_t * uci) {\r
+ const char **thread_options_copy = thread_options;\r
+ const char *thread_option;\r
+ while((thread_option = *(thread_options_copy++))){\r
+ if(uci_option_exist(uci,thread_option)) return TRUE;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+const char * uci_thread_option(uci_t * uci){\r
+ const char **thread_options_copy = thread_options;\r
+ const char *thread_option;\r
+ int i;\r
+ while((thread_option = *(thread_options_copy++))){\r
+ i=uci_get_option(uci,thread_option);\r
+ if(i>=0){\r
+ return Uci->option[i].name;\r
+ break;\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+// uci_is_ok()\r
+\r
+static bool uci_is_ok(const uci_t * uci) {\r
+\r
+ if (uci == NULL) return FALSE;\r
+ if (uci->engine == NULL) return FALSE;\r
+ if (uci->option_nb < 0 || uci->option_nb >= OptionNb) return FALSE;\r
+\r
+ return TRUE;\r
+}\r
+\r
+// uci_open()\r
+\r
+void uci_open(uci_t * uci, engine_t * engine) {\r
+\r
+ char string[StringSize];\r
+ int event;\r
+\r
+ ASSERT(uci!=NULL);\r
+ ASSERT(engine!=NULL);\r
+\r
+ // init\r
+\r
+ uci->engine = engine;\r
+\r
+ uci->name = NULL;\r
+ my_string_set(&uci->name,"<empty>");\r
+ uci->author = NULL;\r
+ my_string_set(&uci->author,"<empty>");\r
+ uci->option_nb = 0;\r
+\r
+ uci->ready_nb = 0;\r
+ uci->searching = 0;\r
+ uci->pending_nb = 0;\r
+ uci->multipv_mode = FALSE;\r
+ board_start(uci->board);\r
+ uci_clear(uci);\r
+\r
+ // send "uci" and wait for "uciok"\r
+\r
+ engine_send(uci->engine,"uci");\r
+\r
+ do {\r
+ engine_get(uci->engine,string);\r
+ event = uci_parse(uci,string);\r
+ } while (!engine_eof(Engine) && (event & EVENT_UCI) == 0);\r
+}\r
+\r
+// uci_close()\r
+\r
+void uci_close(uci_t * uci) {\r
+\r
+ int i;\r
+ option_t * opt;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ engine_close(uci->engine);\r
+ uci->engine = NULL;\r
+ my_string_clear(&uci->name);\r
+ my_string_clear(&uci->author);\r
+\r
+ for (i = 0; i < uci->option_nb; i++) {\r
+ opt = &uci->option[i];\r
+ my_string_clear(&opt->name);\r
+ my_string_clear(&opt->default_);\r
+ }\r
+\r
+ uci->option_nb = 0;\r
+}\r
+\r
+// uci_clear()\r
+\r
+void uci_clear(uci_t * uci) {\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+\r
+ ASSERT(!uci->searching);\r
+\r
+ uci->best_move = MoveNone;\r
+ uci->ponder_move = MoveNone;\r
+\r
+ uci->score = 0;\r
+ uci->depth = 0;\r
+ uci->sel_depth = 0;\r
+ line_clear(uci->pv);\r
+\r
+ uci->best_score = 0;\r
+ uci->best_depth = 0;\r
+ uci->best_sel_depth = 0;\r
+ line_clear(uci->best_pv);\r
+\r
+ uci->node_nb = 0;\r
+ uci->time = 0.0;\r
+ uci->speed = 0.0;\r
+ uci->cpu = 0.0;\r
+ uci->hash = 0.0;\r
+ line_clear(uci->current_line);\r
+\r
+ uci->root_move = MoveNone;\r
+ uci->root_move_pos = 0;\r
+ uci->root_move_nb = board_mobility(uci->board);\r
+}\r
+\r
+// uci_send_isready()\r
+\r
+void uci_send_isready(uci_t * uci) {\r
+\r
+ ASSERT(uci!=NULL);\r
+\r
+ engine_send(uci->engine,"isready");\r
+ uci->ready_nb++;\r
+}\r
+\r
+// uci_send_isready_sync()\r
+\r
+void uci_send_isready_sync(uci_t * uci) {\r
+\r
+ char string[StringSize];\r
+ int event;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+\r
+ // send "isready" and wait for "readyok"\r
+\r
+ uci_send_isready(uci);\r
+\r
+ do {\r
+ engine_get(uci->engine,string);\r
+ event = uci_parse(uci,string);\r
+ } while (!engine_eof(Engine) && (event & EVENT_READY) == 0);\r
+}\r
+\r
+// uci_send_stop()\r
+\r
+void uci_send_stop(uci_t * uci) {\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+\r
+ ASSERT(uci->searching);\r
+ ASSERT(uci->pending_nb>=1);\r
+\r
+ engine_send(Engine,"stop");\r
+ uci->searching = FALSE;\r
+}\r
+\r
+// uci_send_stop_sync()\r
+\r
+void uci_send_stop_sync(uci_t * uci) {\r
+\r
+ char string[StringSize];\r
+ int event;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+\r
+ ASSERT(uci->searching);\r
+ ASSERT(uci->pending_nb>=1);\r
+\r
+ // send "stop" and wait for "bestmove"\r
+\r
+ uci_send_stop(uci);\r
+\r
+ do {\r
+ engine_get(uci->engine,string);\r
+ event = uci_parse(uci,string);\r
+ } while (!engine_eof(Engine) && (event & EVENT_STOP) == 0);\r
+}\r
+\r
+// uci_send_ucinewgame()\r
+\r
+void uci_send_ucinewgame(uci_t * uci) {\r
+\r
+ ASSERT(uci!=NULL);\r
+\r
+ if (option_get_int("UCIVersion") >= 2) {\r
+ engine_send(uci->engine,"ucinewgame");\r
+ }\r
+}\r
+\r
+// uci_option_exist()\r
+\r
+bool uci_option_exist(uci_t * uci, const char option[]) {\r
+\r
+ int i;\r
+ option_t * opt;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ ASSERT(option!=NULL);\r
+\r
+ // scan options\r
+\r
+ for (i = 0; i < uci->option_nb; i++) {\r
+ opt = &uci->option[i];\r
+ if (my_string_case_equal(opt->name,option)) return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+// uci_send_option()\r
+\r
+void uci_send_option(uci_t * uci, const char option[], const char format[], ...) {\r
+\r
+ va_list arg_list;\r
+ char value[StringSize];\r
+ int i;\r
+ option_t * opt;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ ASSERT(option!=NULL);\r
+ ASSERT(format!=NULL);\r
+\r
+ // format\r
+\r
+ va_start(arg_list,format);\r
+ vsprintf(value,format,arg_list);\r
+ va_end(arg_list);\r
+\r
+ if (UseDebug) my_log("POLYGLOT OPTION %s VALUE %s\n",option,value);\r
+\r
+ // scan options\r
+\r
+ for (i = 0; i < uci->option_nb; i++) {\r
+\r
+ opt = &uci->option[i];\r
+\r
+ if (my_string_case_equal(opt->name,option) && !my_string_equal(opt->default_,value)) {\r
+ engine_send(uci->engine,"setoption name %s value %s",opt->name,value);\r
+ my_string_set(&opt->default_,value);\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+// uci_parse()\r
+\r
+int uci_parse(uci_t * uci, const char string[]) {\r
+\r
+ int event;\r
+ parse_t parse[1];\r
+ char command[StringSize];\r
+ char argument[StringSize];\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ ASSERT(string!=NULL);\r
+\r
+ // init\r
+\r
+ event = EVENT_NONE;\r
+\r
+ // parse\r
+\r
+ parse_open(parse,string);\r
+\r
+ if (parse_get_word(parse,command,StringSize)) {\r
+\r
+ parse_get_string(parse,argument,StringSize);\r
+ if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" ARGUMENT \"%s\"\n",command,argument);\r
+\r
+ if (FALSE) {\r
+\r
+ } else if (my_string_equal(command,"bestmove")) {\r
+\r
+ // search end\r
+\r
+ ASSERT(uci->pending_nb>0);\r
+\r
+ if (uci->searching && uci->pending_nb == 1) {\r
+\r
+ // current search\r
+\r
+ uci->searching = FALSE;\r
+ uci->pending_nb--;\r
+\r
+ event = parse_bestmove(uci,argument); // updates uci->best_move and uci->ponder_move\r
+\r
+ } else {\r
+\r
+ // obsolete search\r
+\r
+ if (uci->pending_nb > 0) {\r
+ uci->pending_nb--;\r
+ if (uci->pending_nb == 0) event = EVENT_STOP;\r
+ }\r
+ }\r
+\r
+ } else if (my_string_equal(command,"id")) {\r
+\r
+ parse_id(uci,argument);\r
+\r
+ } else if (my_string_equal(command,"info")) {\r
+\r
+ // search information\r
+\r
+ if (uci->searching && uci->pending_nb == 1) { // current search\r
+ event = parse_info(uci,argument);\r
+ }\r
+\r
+ } else if (my_string_equal(command,"option")) {\r
+\r
+ parse_option(uci,argument);\r
+\r
+ } else if (my_string_equal(command,"readyok")) {\r
+\r
+ // engine is ready\r
+\r
+ ASSERT(uci->ready_nb>0);\r
+\r
+ if (uci->ready_nb > 0) {\r
+ uci->ready_nb--;\r
+ if (uci->ready_nb == 0) event = EVENT_READY;\r
+ }\r
+\r
+ } else if (my_string_equal(command,"uciok")) {\r
+\r
+ event = EVENT_UCI;\r
+\r
+ } else {\r
+\r
+ if (UseDebug) my_log("POLYGLOT unknown command \"%s\"\n",command);\r
+ }\r
+ }\r
+\r
+ parse_close(parse);\r
+\r
+ return event;\r
+}\r
+\r
+// parse_bestmove()\r
+\r
+static int parse_bestmove(uci_t * uci, const char string[]) {\r
+\r
+ parse_t parse[1];\r
+ char command[StringSize];\r
+ char option[StringSize];\r
+ char argument[StringSize];\r
+ board_t board[1];\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ ASSERT(string!=NULL);\r
+\r
+ // init\r
+\r
+ strcpy(command,"bestmove");\r
+\r
+ parse_open(parse,string);\r
+ parse_add_keyword(parse,"ponder");\r
+\r
+ // bestmove\r
+\r
+ if (!parse_get_string(parse,argument,StringSize)) {\r
+ my_fatal("parse_bestmove(): missing argument\n");\r
+ }\r
+\r
+ uci->best_move = move_from_can(argument,uci->board);\r
+ if (uci->best_move == MoveNone) my_fatal("parse_bestmove(): not a move \"%s\"\n",argument);\r
+\r
+ ASSERT(uci->best_move!=MoveNone);\r
+ ASSERT(move_is_legal(uci->best_move,uci->board));\r
+\r
+ // loop\r
+\r
+ while (parse_get_word(parse,option,StringSize)) {\r
+\r
+ parse_get_string(parse,argument,StringSize);\r
+\r
+ if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
+\r
+ if (FALSE) {\r
+\r
+ } else if (my_string_equal(option,"ponder")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ board_copy(board,uci->board);\r
+ move_do(board,uci->best_move);\r
+\r
+ uci->ponder_move = move_from_can(argument,board);\r
+ // if (uci->ponder_move == MoveNone) my_fatal("parse_bestmove(): not a move \"%s\"\n",argument);\r
+\r
+ ASSERT(uci->ponder_move!=MoveNone);\r
+ ASSERT(move_is_legal(uci->ponder_move,board));\r
+\r
+ } else {\r
+\r
+ my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
+ }\r
+ }\r
+\r
+ parse_close(parse);\r
+\r
+ return EVENT_MOVE;\r
+}\r
+\r
+// parse_id()\r
+\r
+static void parse_id(uci_t * uci, const char string[]) {\r
+\r
+ parse_t parse[1];\r
+ char command[StringSize];\r
+ char option[StringSize];\r
+ char argument[StringSize];\r
+\r
+ ASSERT(uci!=NULL);\r
+ ASSERT(string!=NULL);\r
+\r
+ // init\r
+\r
+ strcpy(command,"id");\r
+\r
+ parse_open(parse,string);\r
+ parse_add_keyword(parse,"author");\r
+ parse_add_keyword(parse,"name");\r
+\r
+ // loop\r
+\r
+ while (parse_get_word(parse,option,StringSize)) {\r
+\r
+ parse_get_string(parse,argument,StringSize);\r
+ if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
+\r
+ if (FALSE) {\r
+ } else if (my_string_equal(option,"author")) {\r
+ ASSERT(!my_string_empty(argument));\r
+ my_string_set(&uci->author,argument);\r
+ } else if (my_string_equal(option,"name")) {\r
+ ASSERT(!my_string_empty(argument));\r
+ my_string_set(&uci->name,argument);\r
+ } else {\r
+ my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
+ }\r
+ }\r
+\r
+ parse_close(parse);\r
+\r
+ if (UseDebug) my_log("POLYGLOT engine name \"%s\" author \"%s\"\n",uci->name,uci->author);\r
+}\r
+\r
+// parse_info()\r
+\r
+static int parse_info(uci_t * uci, const char string[]) {\r
+\r
+ int event;\r
+ parse_t parse[1];\r
+ char command[StringSize];\r
+ char option[StringSize];\r
+ char argument[StringSize];\r
+ int n;\r
+ int multipvline=0;\r
+ sint64 ln;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ ASSERT(string!=NULL);\r
+\r
+ // init\r
+\r
+ event = EVENT_NONE;\r
+\r
+ strcpy(command,"info");\r
+\r
+ parse_open(parse,string);\r
+ parse_add_keyword(parse,"cpuload");\r
+ parse_add_keyword(parse,"currline");\r
+ parse_add_keyword(parse,"currmove");\r
+ parse_add_keyword(parse,"currmovenumber");\r
+ parse_add_keyword(parse,"depth");\r
+ parse_add_keyword(parse,"hashfull");\r
+ parse_add_keyword(parse,"multipv");\r
+ parse_add_keyword(parse,"nodes");\r
+ parse_add_keyword(parse,"nps");\r
+ parse_add_keyword(parse,"pv");\r
+ parse_add_keyword(parse,"refutation");\r
+ parse_add_keyword(parse,"score");\r
+ parse_add_keyword(parse,"seldepth");\r
+ parse_add_keyword(parse,"string");\r
+ parse_add_keyword(parse,"tbhits");\r
+ parse_add_keyword(parse,"time");\r
+\r
+ // loop\r
+\r
+ while (parse_get_word(parse,option,StringSize)) {\r
+\r
+ parse_get_string(parse,argument,StringSize);\r
+\r
+ if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
+\r
+ if (FALSE) {\r
+\r
+ } else if (my_string_equal(option,"cpuload")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=0);\r
+\r
+ if (n >= 0) uci->cpu = ((double)n) / 1000.0;\r
+\r
+ } else if (my_string_equal(option,"currline")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ line_from_can(uci->current_line,uci->board,argument,LineSize);\r
+\r
+ } else if (my_string_equal(option,"currmove")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ uci->root_move = move_from_can(argument,uci->board);\r
+ ASSERT(uci->root_move!=MoveNone);\r
+\r
+ } else if (my_string_equal(option,"currmovenumber")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=1&&n<=uci->root_move_nb);\r
+\r
+ if (n >= 1 && n <= uci->root_move_nb) {\r
+ uci->root_move_pos = n - 1;\r
+ ASSERT(uci->root_move_pos>=0&&uci->root_move_pos<uci->root_move_nb);\r
+ }\r
+\r
+ } else if (my_string_equal(option,"depth")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=1);\r
+\r
+ if (n >= 0) {\r
+ if (n > uci->depth) event |= EVENT_DEPTH;\r
+ uci->depth = n;\r
+ }\r
+\r
+ } else if (my_string_equal(option,"hashfull")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=0);\r
+\r
+ if (n >= 0) uci->hash = ((double)n) / 1000.0;\r
+\r
+ } else if (my_string_equal(option,"multipv")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ if(Uci->multipv_mode) multipvline=n;\r
+ \r
+ ASSERT(n>=1);\r
+\r
+ } else if (my_string_equal(option,"nodes")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ ln = my_atoll(argument);\r
+ ASSERT(ln>=0);\r
+\r
+ if (ln >= 0) uci->node_nb = ln;\r
+\r
+ } else if (my_string_equal(option,"nps")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=0);\r
+\r
+ if (n >= 0) uci->speed = ((double)n);\r
+\r
+ } else if (my_string_equal(option,"pv")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ line_from_can(uci->pv,uci->board,argument,LineSize);\r
+ event |= EVENT_PV;\r
+\r
+ } else if (my_string_equal(option,"refutation")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ line_from_can(uci->pv,uci->board,argument,LineSize);\r
+\r
+ } else if (my_string_equal(option,"score")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ parse_score(uci,argument);\r
+\r
+ } else if (my_string_equal(option,"seldepth")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=0);\r
+\r
+ if (n >= 0) uci->sel_depth = n;\r
+\r
+ } else if (my_string_equal(option,"string")) {\r
+ if(!strncmp(argument,"DrawOffer",9))\r
+ event |= EVENT_DRAW;\r
+ if(!strncmp(argument,"Resign",6))\r
+ event |= EVENT_RESIGN;\r
+\r
+ // TODO: argument to EOS\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ } else if (my_string_equal(option,"tbhits")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ ln = my_atoll(argument);\r
+ ASSERT(ln>=0);\r
+\r
+ } else if (my_string_equal(option,"time")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n>=0);\r
+\r
+ if (n >= 0) uci->time = ((double)n) / 1000.0;\r
+\r
+ } else {\r
+\r
+ my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\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
+ 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
+ return event;\r
+}\r
+\r
+int uci_get_option(uci_t * uci, const char * name){\r
+ int i;\r
+ for(i=0;i<Uci->option_nb;i++){\r
+ if(my_string_case_equal(Uci->option[i].name,name)){\r
+ return i;\r
+ }\r
+ }\r
+ return -1;\r
+}\r
+\r
+\r
+\r
+// uci_set_option()\r
+\r
+void uci_set_option(uci_t * uci,\r
+ const char * name,\r
+ const char * default_,\r
+ const char * type,\r
+ const char * max,\r
+ const char * min,\r
+ int var_nb,\r
+ const char * var[]){\r
+ int i,j;\r
+ for(i=0;i<Uci->option_nb;i++){\r
+ if(my_string_equal(Uci->option[i].name,name)){\r
+ break;\r
+ }\r
+ }\r
+ if(i<OptionNb){\r
+ my_string_set(&(Uci->option[i].name),name);\r
+ my_string_set(&(Uci->option[i].default_),default_);\r
+ my_string_set(&(Uci->option[i].type),type);\r
+ my_string_set(&(Uci->option[i].min),min);\r
+ my_string_set(&(Uci->option[i].max),max);\r
+ Uci->option[i].var_nb=var_nb;\r
+ for(j=0;j<var_nb;j++){\r
+ my_string_set(&(Uci->option[i].var[j]),var[j]);\r
+ }\r
+ if(i==Uci->option_nb){\r
+ Uci->option_nb++;\r
+ }\r
+ }\r
+}\r
+\r
+// parse_option()\r
+\r
+static void parse_option(uci_t * uci, const char string[]) {\r
+\r
+ option_t * opt;\r
+ parse_t parse[1];\r
+ char command[StringSize];\r
+ char option[StringSize];\r
+ char argument[StringSize];\r
+\r
+ ASSERT(uci!=NULL);\r
+ ASSERT(string!=NULL);\r
+\r
+ // init\r
+\r
+ strcpy(command,"option");\r
+\r
+ if (uci->option_nb >= OptionNb) return;\r
+\r
+ opt = &uci->option[uci->option_nb];\r
+ uci->option_nb++;\r
+\r
+ opt->value=NULL;\r
+ my_string_set(&opt->value,"<empty>");\r
+ opt->mode=0;\r
+\r
+ opt->name = NULL;\r
+ my_string_set(&opt->name,"<empty>");\r
+\r
+ \r
+ opt->default_ = NULL;\r
+ my_string_set(&opt->default_,"<empty>");\r
+\r
+ opt->max = NULL;\r
+ my_string_set(&opt->max,"<empty>");\r
+\r
+ opt->min = NULL;\r
+ my_string_set(&opt->min,"<empty>");\r
+\r
+ opt->type = NULL;\r
+ my_string_set(&opt->type,"<empty>");\r
+\r
+ opt->var_nb=0;\r
+ \r
+ parse_open(parse,string);\r
+ parse_add_keyword(parse,"default");\r
+ parse_add_keyword(parse,"max");\r
+ parse_add_keyword(parse,"min");\r
+ parse_add_keyword(parse,"name");\r
+ parse_add_keyword(parse,"type");\r
+ parse_add_keyword(parse,"var");\r
+\r
+ // loop\r
+\r
+ while (parse_get_word(parse,option,StringSize)) {\r
+ parse_get_string(parse,argument,StringSize);\r
+ if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
+\r
+ if (FALSE) {\r
+\r
+ } else if (my_string_equal(option,"default")) {\r
+\r
+ // ASSERT(!my_string_empty(argument)); // HACK for Pepito\r
+\r
+ if (!my_string_empty(argument)) {\r
+ my_string_set(&opt->default_,argument);\r
+ my_string_set(&opt->value,argument);\r
+ }\r
+\r
+ } else if (my_string_equal(option,"max")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+ my_string_set(&opt->max,argument);\r
+\r
+ } else if (my_string_equal(option,"min")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+ my_string_set(&opt->min,argument);\r
+\r
+ } else if (my_string_equal(option,"name")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ if (!my_string_empty(argument)) {\r
+ my_string_set(&opt->name,argument);\r
+ }\r
+\r
+ } else if (my_string_equal(option,"type")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+ my_string_set(&opt->type,argument);\r
+\r
+ } else if (my_string_equal(option,"var")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+ my_string_set(&opt->var[opt->var_nb++],argument);\r
+ if(opt->var_nb==VarNb) break;\r
+\r
+ } else {\r
+\r
+ my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
+ }\r
+ }\r
+\r
+ parse_close(parse);\r
+\r
+ if (UseDebug) my_log("POLYGLOT option name \"%s\" default \"%s\"\n",opt->name,opt->default_);\r
+}\r
+\r
+// parse_score()\r
+\r
+static void parse_score(uci_t * uci, const char string[]) {\r
+\r
+ parse_t parse[1];\r
+ char command[StringSize];\r
+ char option[StringSize];\r
+ char argument[StringSize];\r
+ int n;\r
+\r
+ ASSERT(uci_is_ok(uci));\r
+ ASSERT(string!=NULL);\r
+\r
+ // init\r
+\r
+ strcpy(command,"score");\r
+\r
+ parse_open(parse,string);\r
+ parse_add_keyword(parse,"cp");\r
+ parse_add_keyword(parse,"lowerbound");\r
+ parse_add_keyword(parse,"mate");\r
+ parse_add_keyword(parse,"upperbound");\r
+\r
+ // loop\r
+\r
+ while (parse_get_word(parse,option,StringSize)) {\r
+\r
+ parse_get_string(parse,argument,StringSize);\r
+\r
+ if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
+\r
+ if (FALSE) {\r
+\r
+ } else if (my_string_equal(option,"cp")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+\r
+ uci->score = n;\r
+\r
+ } else if (my_string_equal(option,"lowerbound")) {\r
+\r
+ ASSERT(my_string_empty(argument));\r
+\r
+ } else if (my_string_equal(option,"mate")) {\r
+\r
+ ASSERT(!my_string_empty(argument));\r
+\r
+ n = atoi(argument);\r
+ ASSERT(n!=0);\r
+\r
+ uci->score = mate_score(n);\r
+\r
+ } else if (my_string_equal(option,"upperbound")) {\r
+\r
+ ASSERT(my_string_empty(argument));\r
+\r
+ } else {\r
+\r
+ my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
+ }\r
+ }\r
+\r
+ parse_close(parse);\r
+}\r
+\r
+// mate_score()\r
+\r
+static int mate_score(int dist) {\r
+\r
+ ASSERT(dist!=0);\r
+\r
+ if (FALSE) {\r
+ } else if (dist > 0) {\r
+ return +option_get_int("MateScore") - (+dist) * 2 + 1;\r
+ } else if (dist < 0) {\r
+ return -option_get_int("MateScore") + (-dist) * 2;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+// end of uci.cpp\r
+\r