Check in polyglot-1.4w10UCIb15
[polyglot.git] / uci.cpp
1 \r
2 // uci.cpp\r
3 \r
4 // includes\r
5 \r
6 #include <cstdarg>\r
7 #include <cstdio>\r
8 #include <cstdlib>\r
9 #include <cstring>\r
10 \r
11 #include "board.h"\r
12 #include "engine.h"\r
13 #include "move.h"\r
14 #include "move_do.h"\r
15 #include "move_legal.h"\r
16 #include "option.h"\r
17 #include "parse.h"\r
18 #include "line.h"\r
19 #include "uci.h"\r
20 \r
21 // constants\r
22 \r
23 static const bool UseDebug = false;\r
24 \r
25 static const int StringSize = 4096;\r
26 \r
27 // variables\r
28 \r
29 uci_t Uci[1];\r
30 \r
31 // Hopefully the following confusion is temporary\r
32 // Normally we should check for the engine name but this is a hack anyway\r
33 // Some of there where provided by Marc Lacrosse\r
34 \r
35 const char * thread_options[]={\r
36   "number of threads",        // toga\r
37   "number threads",           // Deep Learning Toga\r
38   "threads",                  // glaurung, zappa, cyclone, grapefruit,\r
39                               // Deep Shredder, Deep Junior\r
40   "core threads",             // HIARCS\r
41   "max cpus",                 // rybka\r
42   "cpus",                     // Deep Sjeng, Fruit2.3.5\r
43   "maxthreads",               // Naum \r
44   NULL\r
45 };\r
46 \r
47 // prototypes\r
48 \r
49 static bool uci_is_ok      (const uci_t * uci);\r
50 \r
51 static int  parse_bestmove (uci_t * uci, const char string[]);\r
52 static void parse_id       (uci_t * uci, const char string[]);\r
53 static int  parse_info     (uci_t * uci, const char string[]);\r
54 static void parse_option   (uci_t * uci, const char string[]);\r
55 static void parse_score    (uci_t * uci, const char string[]);\r
56 \r
57 static int  mate_score     (int dist);\r
58 \r
59 // functions\r
60 \r
61 // uci_set_threads()\r
62 \r
63 void uci_set_threads(uci_t * uci, int n) {\r
64     const char **thread_options_copy = thread_options;\r
65     const char *thread_option;\r
66     ASSERT(n>=1);\r
67     while((thread_option = *(thread_options_copy++))){\r
68         uci_send_option(uci,thread_option,"%d",n); // checks also for existence\r
69     }\r
70 }\r
71 \r
72 // uci_thread_option_exists()\r
73 \r
74 bool uci_thread_option_exist(uci_t * uci) {\r
75     const char **thread_options_copy = thread_options;\r
76     const char *thread_option;\r
77     while((thread_option = *(thread_options_copy++))){\r
78         if(uci_option_exist(uci,thread_option)) return true;\r
79     }\r
80     return false;\r
81 }\r
82 \r
83 // uci_is_ok()\r
84 \r
85 static bool uci_is_ok(const uci_t * uci) {\r
86 \r
87    if (uci == NULL) return false;\r
88    if (uci->engine == NULL) return false;\r
89    if (uci->option_nb < 0 || uci->option_nb >= OptionNb) return false;\r
90 \r
91    return true;\r
92 }\r
93 \r
94 // uci_open()\r
95 \r
96 void uci_open(uci_t * uci, engine_t * engine) {\r
97 \r
98    char string[StringSize];\r
99    int event;\r
100 \r
101    ASSERT(uci!=NULL);\r
102    ASSERT(engine!=NULL);\r
103 \r
104    // init\r
105 \r
106    uci->engine = engine;\r
107 \r
108    uci->name = NULL;\r
109    my_string_set(&uci->name,"<empty>");\r
110    uci->author = NULL;\r
111    my_string_set(&uci->author,"<empty>");\r
112    uci->option_nb = 0;\r
113 \r
114    uci->ready_nb = 0;\r
115    uci->searching = 0;\r
116    uci->pending_nb = 0;\r
117    uci->multipv_mode = false;\r
118    board_start(uci->board);\r
119    uci_clear(uci);\r
120 \r
121    // send "uci" and wait for "uciok"\r
122 \r
123    engine_send(uci->engine,"uci");\r
124 \r
125    do {\r
126       engine_get(uci->engine,string,StringSize);\r
127       event = uci_parse(uci,string);\r
128    } while ((event & EVENT_UCI) == 0);\r
129 }\r
130 \r
131 // uci_close()\r
132 \r
133 void uci_close(uci_t * uci) {\r
134 \r
135    int i;\r
136    option_t * opt;\r
137 \r
138    ASSERT(uci_is_ok(uci));\r
139    engine_close(uci->engine);\r
140    uci->engine = NULL;\r
141    my_string_clear(&uci->name);\r
142    my_string_clear(&uci->author);\r
143 \r
144    for (i = 0; i < uci->option_nb; i++) {\r
145       opt = &uci->option[i];\r
146       my_string_clear(&opt->name);\r
147       my_string_clear(&opt->value);\r
148    }\r
149 \r
150    uci->option_nb = 0;\r
151 }\r
152 \r
153 // uci_clear()\r
154 \r
155 void uci_clear(uci_t * uci) {\r
156 \r
157    ASSERT(uci_is_ok(uci));\r
158 \r
159    ASSERT(!uci->searching);\r
160 \r
161    uci->best_move = MoveNone;\r
162    uci->ponder_move = MoveNone;\r
163 \r
164    uci->score = 0;\r
165    uci->depth = 0;\r
166    uci->sel_depth = 0;\r
167    line_clear(uci->pv);\r
168 \r
169    uci->best_score = 0;\r
170    uci->best_depth = 0;\r
171    uci->best_sel_depth = 0;\r
172    line_clear(uci->best_pv);\r
173 \r
174    uci->node_nb = 0;\r
175    uci->time = 0.0;\r
176    uci->speed = 0.0;\r
177    uci->cpu = 0.0;\r
178    uci->hash = 0.0;\r
179    line_clear(uci->current_line);\r
180 \r
181    uci->root_move = MoveNone;\r
182    uci->root_move_pos = 0;\r
183    uci->root_move_nb = board_mobility(uci->board);\r
184 }\r
185 \r
186 // uci_send_isready()\r
187 \r
188 void uci_send_isready(uci_t * uci) {\r
189 \r
190    ASSERT(uci!=NULL);\r
191 \r
192    engine_send(uci->engine,"isready");\r
193    uci->ready_nb++;\r
194 }\r
195 \r
196 // uci_send_isready_sync()\r
197 \r
198 void uci_send_isready_sync(uci_t * uci) {\r
199 \r
200    char string[StringSize];\r
201    int event;\r
202 \r
203    ASSERT(uci_is_ok(uci));\r
204 \r
205    // send "isready" and wait for "readyok"\r
206 \r
207    uci_send_isready(uci);\r
208 \r
209    do {\r
210       engine_get(uci->engine,string,StringSize);\r
211       event = uci_parse(uci,string);\r
212    } while ((event & EVENT_READY) == 0);\r
213 }\r
214 \r
215 // uci_send_stop()\r
216 \r
217 void uci_send_stop(uci_t * uci) {\r
218 \r
219    ASSERT(uci_is_ok(uci));\r
220 \r
221    ASSERT(uci->searching);\r
222    ASSERT(uci->pending_nb>=1);\r
223 \r
224    engine_send(Engine,"stop");\r
225    uci->searching = false;\r
226 }\r
227 \r
228 // uci_send_stop_sync()\r
229 \r
230 void uci_send_stop_sync(uci_t * uci) {\r
231 \r
232    char string[StringSize];\r
233    int event;\r
234 \r
235    ASSERT(uci_is_ok(uci));\r
236 \r
237    ASSERT(uci->searching);\r
238    ASSERT(uci->pending_nb>=1);\r
239 \r
240    // send "stop" and wait for "bestmove"\r
241 \r
242    uci_send_stop(uci);\r
243 \r
244    do {\r
245       engine_get(uci->engine,string,StringSize);\r
246       event = uci_parse(uci,string);\r
247    } while ((event & EVENT_STOP) == 0);\r
248 }\r
249 \r
250 // uci_send_ucinewgame()\r
251 \r
252 void uci_send_ucinewgame(uci_t * uci) {\r
253 \r
254    ASSERT(uci!=NULL);\r
255 \r
256    if (option_get_int("UCIVersion") >= 2) {\r
257       engine_send(uci->engine,"ucinewgame");\r
258    }\r
259 }\r
260 \r
261 // uci_option_exist()\r
262 \r
263 bool uci_option_exist(uci_t * uci, const char option[]) {\r
264 \r
265    int i;\r
266    option_t * opt;\r
267 \r
268    ASSERT(uci_is_ok(uci));\r
269    ASSERT(option!=NULL);\r
270 \r
271    // scan options\r
272 \r
273    for (i = 0; i < uci->option_nb; i++) {\r
274       opt = &uci->option[i];\r
275       if (my_string_case_equal(opt->name,option)) return true;\r
276    }\r
277 \r
278    return false;\r
279 }\r
280 \r
281 // uci_send_option()\r
282 \r
283 void uci_send_option(uci_t * uci, const char option[], const char format[], ...) {\r
284 \r
285    va_list arg_list;\r
286    char value[StringSize];\r
287    int i;\r
288    option_t * opt;\r
289 \r
290    ASSERT(uci_is_ok(uci));\r
291    ASSERT(option!=NULL);\r
292    ASSERT(format!=NULL);\r
293 \r
294    // format\r
295 \r
296    va_start(arg_list,format);\r
297    vsprintf(value,format,arg_list);\r
298    va_end(arg_list);\r
299 \r
300    if (UseDebug) my_log("POLYGLOT OPTION %s VALUE %s\n",option,value);\r
301 \r
302    // scan options\r
303 \r
304    for (i = 0; i < uci->option_nb; i++) {\r
305 \r
306       opt = &uci->option[i];\r
307 \r
308       if (my_string_case_equal(opt->name,option) && !my_string_equal(opt->value,value)) {\r
309          engine_send(uci->engine,"setoption name %s value %s",opt->name,value);\r
310          my_string_set(&opt->value,value);\r
311          break;\r
312       }\r
313    }\r
314 }\r
315 \r
316 // uci_parse()\r
317 \r
318 int uci_parse(uci_t * uci, const char string[]) {\r
319 \r
320    int event;\r
321    parse_t parse[1];\r
322    char command[StringSize];\r
323    char argument[StringSize];\r
324 \r
325    ASSERT(uci_is_ok(uci));\r
326    ASSERT(string!=NULL);\r
327 \r
328    // init\r
329 \r
330    event = EVENT_NONE;\r
331 \r
332    // parse\r
333 \r
334    parse_open(parse,string);\r
335 \r
336    if (parse_get_word(parse,command,StringSize)) {\r
337 \r
338       parse_get_string(parse,argument,StringSize);\r
339       if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" ARGUMENT \"%s\"\n",command,argument);\r
340 \r
341       if (false) {\r
342 \r
343       } else if (my_string_equal(command,"bestmove")) {\r
344 \r
345          // search end\r
346 \r
347          ASSERT(uci->pending_nb>0);\r
348 \r
349          if (uci->searching && uci->pending_nb == 1) {\r
350 \r
351             // current search\r
352 \r
353             uci->searching = false;\r
354             uci->pending_nb--;\r
355 \r
356             event = parse_bestmove(uci,argument); // updates uci->best_move and uci->ponder_move\r
357 \r
358          } else {\r
359 \r
360             // obsolete search\r
361 \r
362             if (uci->pending_nb > 0) {\r
363                uci->pending_nb--;\r
364                if (uci->pending_nb == 0) event = EVENT_STOP;\r
365             }\r
366          }\r
367 \r
368       } else if (my_string_equal(command,"id")) {\r
369 \r
370          parse_id(uci,argument);\r
371 \r
372       } else if (my_string_equal(command,"info")) {\r
373 \r
374          // search information\r
375 \r
376          if (uci->searching && uci->pending_nb == 1) { // current search\r
377             event = parse_info(uci,argument);\r
378          }\r
379 \r
380       } else if (my_string_equal(command,"option")) {\r
381 \r
382          parse_option(uci,argument);\r
383 \r
384       } else if (my_string_equal(command,"readyok")) {\r
385 \r
386          // engine is ready\r
387 \r
388          ASSERT(uci->ready_nb>0);\r
389 \r
390          if (uci->ready_nb > 0) {\r
391             uci->ready_nb--;\r
392             if (uci->ready_nb == 0) event = EVENT_READY;\r
393          }\r
394 \r
395       } else if (my_string_equal(command,"uciok")) {\r
396 \r
397          event = EVENT_UCI;\r
398 \r
399       } else {\r
400 \r
401          if (UseDebug) my_log("POLYGLOT unknown command \"%s\"\n",command);\r
402       }\r
403    }\r
404 \r
405    parse_close(parse);\r
406 \r
407    return event;\r
408 }\r
409 \r
410 // parse_bestmove()\r
411 \r
412 static int parse_bestmove(uci_t * uci, const char string[]) {\r
413 \r
414    parse_t parse[1];\r
415    char command[StringSize];\r
416    char option[StringSize];\r
417    char argument[StringSize];\r
418    board_t board[1];\r
419 \r
420    ASSERT(uci_is_ok(uci));\r
421    ASSERT(string!=NULL);\r
422 \r
423    // init\r
424 \r
425    strcpy(command,"bestmove");\r
426 \r
427    parse_open(parse,string);\r
428    parse_add_keyword(parse,"ponder");\r
429 \r
430    // bestmove\r
431 \r
432    if (!parse_get_string(parse,argument,StringSize)) {\r
433       my_fatal("parse_bestmove(): missing argument\n");\r
434    }\r
435 \r
436    uci->best_move = move_from_can(argument,uci->board);\r
437    if (uci->best_move == MoveNone) my_fatal("parse_bestmove(): not a move \"%s\"\n",argument);\r
438 \r
439    ASSERT(uci->best_move!=MoveNone);\r
440    ASSERT(move_is_legal(uci->best_move,uci->board));\r
441 \r
442    // loop\r
443 \r
444    while (parse_get_word(parse,option,StringSize)) {\r
445 \r
446       parse_get_string(parse,argument,StringSize);\r
447 \r
448       if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
449 \r
450       if (false) {\r
451 \r
452       } else if (my_string_equal(option,"ponder")) {\r
453 \r
454          ASSERT(!my_string_empty(argument));\r
455 \r
456          board_copy(board,uci->board);\r
457          move_do(board,uci->best_move);\r
458 \r
459          uci->ponder_move = move_from_can(argument,board);\r
460          // if (uci->ponder_move == MoveNone) my_fatal("parse_bestmove(): not a move \"%s\"\n",argument);\r
461 \r
462          ASSERT(uci->ponder_move!=MoveNone);\r
463          ASSERT(move_is_legal(uci->ponder_move,board));\r
464 \r
465       } else {\r
466 \r
467          my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
468       }\r
469    }\r
470 \r
471    parse_close(parse);\r
472 \r
473    return EVENT_MOVE;\r
474 }\r
475 \r
476 // parse_id()\r
477 \r
478 static void parse_id(uci_t * uci, const char string[]) {\r
479 \r
480    parse_t parse[1];\r
481    char command[StringSize];\r
482    char option[StringSize];\r
483    char argument[StringSize];\r
484 \r
485    ASSERT(uci!=NULL);\r
486    ASSERT(string!=NULL);\r
487 \r
488    // init\r
489 \r
490    strcpy(command,"id");\r
491 \r
492    parse_open(parse,string);\r
493    parse_add_keyword(parse,"author");\r
494    parse_add_keyword(parse,"name");\r
495 \r
496    // loop\r
497 \r
498    while (parse_get_word(parse,option,StringSize)) {\r
499 \r
500       parse_get_string(parse,argument,StringSize);\r
501       if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
502 \r
503       if (false) {\r
504       } else if (my_string_equal(option,"author")) {\r
505          ASSERT(!my_string_empty(argument));\r
506          my_string_set(&uci->author,argument);\r
507       } else if (my_string_equal(option,"name")) {\r
508          ASSERT(!my_string_empty(argument));\r
509          my_string_set(&uci->name,argument);\r
510       } else {\r
511          my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
512       }\r
513    }\r
514 \r
515    parse_close(parse);\r
516 \r
517    if (UseDebug) my_log("POLYGLOT engine name \"%s\" author \"%s\"\n",uci->name,uci->author);\r
518 }\r
519 \r
520 // parse_info()\r
521 \r
522 static int parse_info(uci_t * uci, const char string[]) {\r
523 \r
524    int event;\r
525    parse_t parse[1];\r
526    char command[StringSize];\r
527    char option[StringSize];\r
528    char argument[StringSize];\r
529    int n;\r
530    int multipvline=0;\r
531    sint64 ln;\r
532 \r
533    ASSERT(uci_is_ok(uci));\r
534    ASSERT(string!=NULL);\r
535 \r
536    // init\r
537 \r
538    event = EVENT_NONE;\r
539 \r
540    strcpy(command,"info");\r
541 \r
542    parse_open(parse,string);\r
543    parse_add_keyword(parse,"cpuload");\r
544    parse_add_keyword(parse,"currline");\r
545    parse_add_keyword(parse,"currmove");\r
546    parse_add_keyword(parse,"currmovenumber");\r
547    parse_add_keyword(parse,"depth");\r
548    parse_add_keyword(parse,"hashfull");\r
549    parse_add_keyword(parse,"multipv");\r
550    parse_add_keyword(parse,"nodes");\r
551    parse_add_keyword(parse,"nps");\r
552    parse_add_keyword(parse,"pv");\r
553    parse_add_keyword(parse,"refutation");\r
554    parse_add_keyword(parse,"score");\r
555    parse_add_keyword(parse,"seldepth");\r
556    parse_add_keyword(parse,"string");\r
557    parse_add_keyword(parse,"tbhits");\r
558    parse_add_keyword(parse,"time");\r
559 \r
560    // loop\r
561 \r
562    while (parse_get_word(parse,option,StringSize)) {\r
563 \r
564       parse_get_string(parse,argument,StringSize);\r
565 \r
566       if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
567 \r
568       if (false) {\r
569 \r
570       } else if (my_string_equal(option,"cpuload")) {\r
571 \r
572          ASSERT(!my_string_empty(argument));\r
573 \r
574          n = atoi(argument);\r
575          ASSERT(n>=0);\r
576 \r
577          if (n >= 0) uci->cpu = double(n) / 1000.0;\r
578 \r
579       } else if (my_string_equal(option,"currline")) {\r
580 \r
581          ASSERT(!my_string_empty(argument));\r
582 \r
583          line_from_can(uci->current_line,uci->board,argument,LineSize);\r
584 \r
585       } else if (my_string_equal(option,"currmove")) {\r
586 \r
587          ASSERT(!my_string_empty(argument));\r
588 \r
589          uci->root_move = move_from_can(argument,uci->board);\r
590          ASSERT(uci->root_move!=MoveNone);\r
591 \r
592       } else if (my_string_equal(option,"currmovenumber")) {\r
593 \r
594          ASSERT(!my_string_empty(argument));\r
595 \r
596          n = atoi(argument);\r
597          ASSERT(n>=1&&n<=uci->root_move_nb);\r
598 \r
599          if (n >= 1 && n <= uci->root_move_nb) {\r
600             uci->root_move_pos = n - 1;\r
601             ASSERT(uci->root_move_pos>=0&&uci->root_move_pos<uci->root_move_nb);\r
602          }\r
603 \r
604       } else if (my_string_equal(option,"depth")) {\r
605 \r
606          ASSERT(!my_string_empty(argument));\r
607 \r
608          n = atoi(argument);\r
609          ASSERT(n>=1);\r
610 \r
611          if (n >= 0) {\r
612             if (n > uci->depth) event |= EVENT_DEPTH;\r
613             uci->depth = n;\r
614          }\r
615 \r
616       } else if (my_string_equal(option,"hashfull")) {\r
617 \r
618          ASSERT(!my_string_empty(argument));\r
619 \r
620          n = atoi(argument);\r
621          ASSERT(n>=0);\r
622 \r
623          if (n >= 0) uci->hash = double(n) / 1000.0;\r
624 \r
625       } else if (my_string_equal(option,"multipv")) {\r
626 \r
627          ASSERT(!my_string_empty(argument));\r
628 \r
629          n = atoi(argument);\r
630                  if(Uci->multipv_mode) multipvline=n;\r
631         \r
632          ASSERT(n>=1);\r
633 \r
634       } else if (my_string_equal(option,"nodes")) {\r
635 \r
636          ASSERT(!my_string_empty(argument));\r
637 \r
638          ln = my_atoll(argument);\r
639          ASSERT(ln>=0);\r
640 \r
641          if (ln >= 0) uci->node_nb = ln;\r
642 \r
643       } else if (my_string_equal(option,"nps")) {\r
644 \r
645          ASSERT(!my_string_empty(argument));\r
646 \r
647          n = atoi(argument);\r
648          ASSERT(n>=0);\r
649 \r
650          if (n >= 0) uci->speed = double(n);\r
651 \r
652       } else if (my_string_equal(option,"pv")) {\r
653 \r
654          ASSERT(!my_string_empty(argument));\r
655 \r
656          line_from_can(uci->pv,uci->board,argument,LineSize);\r
657          event |= EVENT_PV;\r
658 \r
659       } else if (my_string_equal(option,"refutation")) {\r
660 \r
661          ASSERT(!my_string_empty(argument));\r
662 \r
663          line_from_can(uci->pv,uci->board,argument,LineSize);\r
664 \r
665       } else if (my_string_equal(option,"score")) {\r
666 \r
667          ASSERT(!my_string_empty(argument));\r
668 \r
669          parse_score(uci,argument);\r
670 \r
671       } else if (my_string_equal(option,"seldepth")) {\r
672 \r
673          ASSERT(!my_string_empty(argument));\r
674 \r
675          n = atoi(argument);\r
676          ASSERT(n>=0);\r
677 \r
678          if (n >= 0) uci->sel_depth = n;\r
679 \r
680       } else if (my_string_equal(option,"string")) {\r
681                   if(!strncmp(argument,"DrawOffer",9))\r
682                           event |= EVENT_DRAW;\r
683                   if(!strncmp(argument,"Resign",6))\r
684                           event |= EVENT_RESIGN;\r
685 \r
686          // TODO: argument to EOS\r
687 \r
688          ASSERT(!my_string_empty(argument));\r
689 \r
690       } else if (my_string_equal(option,"tbhits")) {\r
691 \r
692          ASSERT(!my_string_empty(argument));\r
693 \r
694          ln = my_atoll(argument);\r
695          ASSERT(ln>=0);\r
696 \r
697       } else if (my_string_equal(option,"time")) {\r
698 \r
699          ASSERT(!my_string_empty(argument));\r
700 \r
701          n = atoi(argument);\r
702          ASSERT(n>=0);\r
703 \r
704          if (n >= 0) uci->time = double(n) / 1000.0;\r
705 \r
706       } else {\r
707 \r
708          my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
709       }\r
710    }\r
711 \r
712    parse_close(parse);\r
713 \r
714    // update display\r
715    //lousy uci,filter out lower depth multipv lines that have been repeated from the engine \r
716    if(multipvline>1 && uci->depth<uci->best_depth) event &= ~EVENT_PV;\r
717    if ((event & EVENT_PV) != 0) {\r
718       uci->best_score = uci->score; \r
719           uci->best_depth = uci->depth;\r
720           if(multipvline==1)uci->depth=-1; //HACK ,clears the engine outpout window,see send_pv in adapter.cpp \r
721       uci->best_sel_depth = uci->sel_depth;\r
722       line_copy(uci->best_pv,uci->pv);\r
723    }\r
724    return event;\r
725 }\r
726 \r
727 int uci_get_option(uci_t * uci, const char * name){\r
728     int i;\r
729     for(i=0;i<Uci->option_nb;i++){\r
730         if(my_string_case_equal(Uci->option[i].name,name)){\r
731             return i;\r
732         }\r
733     }\r
734     return -1;\r
735 }\r
736 \r
737 \r
738 \r
739 // uci_set_option()\r
740 \r
741 void uci_set_option(uci_t * uci,\r
742                     const char * name,\r
743                     const char * value,\r
744                     const char * type,\r
745                     const char * max,\r
746                     const char * min,\r
747                     const char * var){\r
748     int i;\r
749     for(i=0;i<Uci->option_nb;i++){\r
750         if(my_string_equal(Uci->option[i].name,name)){\r
751             break;\r
752        }\r
753    }\r
754    if(i<OptionNb){\r
755        my_string_set(&(Uci->option[i].name),name);\r
756        my_string_set(&(Uci->option[i].value),value);\r
757        my_string_set(&(Uci->option[i].type),type);\r
758        my_string_set(&(Uci->option[i].min),min);\r
759        my_string_set(&(Uci->option[i].max),max);\r
760        my_string_set(&(Uci->option[i].var),var);\r
761        if(i==Uci->option_nb){\r
762            Uci->option_nb++;\r
763        }\r
764    }\r
765 }\r
766 \r
767 // parse_option()\r
768 \r
769 static void parse_option(uci_t * uci, const char string[]) {\r
770 \r
771    option_t * opt;\r
772    parse_t parse[1];\r
773    char command[StringSize];\r
774    char option[StringSize];\r
775    char argument[StringSize];\r
776 \r
777    ASSERT(uci!=NULL);\r
778    ASSERT(string!=NULL);\r
779 \r
780    // init\r
781 \r
782    strcpy(command,"option");\r
783 \r
784    if (uci->option_nb >= OptionNb) return;\r
785 \r
786    opt = &uci->option[uci->option_nb];\r
787    uci->option_nb++;\r
788 \r
789    opt->name = NULL;\r
790    my_string_set(&opt->name,"<empty>");\r
791 \r
792    opt->value = NULL;\r
793    my_string_set(&opt->value,"<empty>");\r
794 \r
795    opt->max = NULL;\r
796    my_string_set(&opt->max,"<empty>");\r
797 \r
798    opt->min = NULL;\r
799    my_string_set(&opt->min,"<empty>");\r
800 \r
801    opt->type = NULL;\r
802    my_string_set(&opt->type,"<empty>");\r
803 \r
804    opt->var = NULL;\r
805    my_string_set(&opt->var,"<empty>");\r
806 \r
807    parse_open(parse,string);\r
808    parse_add_keyword(parse,"default");\r
809    parse_add_keyword(parse,"max");\r
810    parse_add_keyword(parse,"min");\r
811    parse_add_keyword(parse,"name");\r
812    parse_add_keyword(parse,"type");\r
813    parse_add_keyword(parse,"var");\r
814 \r
815    // loop\r
816 \r
817    while (parse_get_word(parse,option,StringSize)) {\r
818 \r
819       parse_get_string(parse,argument,StringSize);\r
820       if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
821 \r
822       if (false) {\r
823 \r
824       } else if (my_string_equal(option,"default")) {\r
825 \r
826          // ASSERT(!my_string_empty(argument)); // HACK for Pepito\r
827 \r
828          if (!my_string_empty(argument)) {\r
829             my_string_set(&opt->value,argument);\r
830          }\r
831 \r
832       } else if (my_string_equal(option,"max")) {\r
833 \r
834          ASSERT(!my_string_empty(argument));\r
835          my_string_set(&opt->max,argument);\r
836 \r
837       } else if (my_string_equal(option,"min")) {\r
838 \r
839          ASSERT(!my_string_empty(argument));\r
840          my_string_set(&opt->min,argument);\r
841 \r
842       } else if (my_string_equal(option,"name")) {\r
843 \r
844          ASSERT(!my_string_empty(argument));\r
845 \r
846          if (!my_string_empty(argument)) {\r
847             my_string_set(&opt->name,argument);\r
848          }\r
849 \r
850       } else if (my_string_equal(option,"type")) {\r
851 \r
852          ASSERT(!my_string_empty(argument));\r
853          my_string_set(&opt->type,argument);\r
854 \r
855       } else if (my_string_equal(option,"var")) {\r
856 \r
857          ASSERT(!my_string_empty(argument));\r
858          my_string_set(&opt->var,argument);\r
859 \r
860       } else {\r
861 \r
862          my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
863       }\r
864    }\r
865 \r
866    parse_close(parse);\r
867 \r
868    if (UseDebug) my_log("POLYGLOT option name \"%s\" value \"%s\"\n",opt->name,opt->value);\r
869 }\r
870 \r
871 // parse_score()\r
872 \r
873 static void parse_score(uci_t * uci, const char string[]) {\r
874 \r
875    parse_t parse[1];\r
876    char command[StringSize];\r
877    char option[StringSize];\r
878    char argument[StringSize];\r
879    int n;\r
880 \r
881    ASSERT(uci_is_ok(uci));\r
882    ASSERT(string!=NULL);\r
883 \r
884    // init\r
885 \r
886    strcpy(command,"score");\r
887 \r
888    parse_open(parse,string);\r
889    parse_add_keyword(parse,"cp");\r
890    parse_add_keyword(parse,"lowerbound");\r
891    parse_add_keyword(parse,"mate");\r
892    parse_add_keyword(parse,"upperbound");\r
893 \r
894    // loop\r
895 \r
896    while (parse_get_word(parse,option,StringSize)) {\r
897 \r
898       parse_get_string(parse,argument,StringSize);\r
899 \r
900       if (UseDebug) my_log("POLYGLOT COMMAND \"%s\" OPTION \"%s\" ARGUMENT \"%s\"\n",command,option,argument);\r
901 \r
902       if (false) {\r
903 \r
904       } else if (my_string_equal(option,"cp")) {\r
905 \r
906          ASSERT(!my_string_empty(argument));\r
907 \r
908          n = atoi(argument);\r
909 \r
910          uci->score = n;\r
911 \r
912       } else if (my_string_equal(option,"lowerbound")) {\r
913 \r
914          ASSERT(my_string_empty(argument));\r
915 \r
916       } else if (my_string_equal(option,"mate")) {\r
917 \r
918          ASSERT(!my_string_empty(argument));\r
919 \r
920          n = atoi(argument);\r
921          ASSERT(n!=0);\r
922 \r
923          uci->score = mate_score(n);\r
924 \r
925       } else if (my_string_equal(option,"upperbound")) {\r
926 \r
927          ASSERT(my_string_empty(argument));\r
928 \r
929       } else {\r
930 \r
931          my_log("POLYGLOT unknown option \"%s\" for command \"%s\"\n",option,command);\r
932       }\r
933    }\r
934 \r
935    parse_close(parse);\r
936 }\r
937 \r
938 // mate_score()\r
939 \r
940 static int mate_score(int dist) {\r
941 \r
942    ASSERT(dist!=0);\r
943 \r
944    if (false) {\r
945    } else if (dist > 0) {\r
946       return +option_get_int("MateScore") - (+dist) * 2 + 1;\r
947    } else if (dist < 0) {\r
948       return -option_get_int("MateScore") + (-dist) * 2;\r
949    }\r
950 \r
951    return 0;\r
952 }\r
953 \r
954 // end of uci.cpp\r
955 \r