1 // uci2uci.c
2 
3 // includes
4 
5 #include <string.h>
6 #include <stdlib.h>
7 
8 #include "util.h"
9 #include "board.h"
10 #include "engine.h"
11 #include "fen.h"
12 #include "gui.h"
13 #include "move.h"
14 #include "move_do.h"
15 #include "move_legal.h"
16 #include "parse.h"
17 #include "option.h"
18 #include "book.h"
19 #include "main.h"
20 #include "uci.h"
21 
22 // defines
23 
24 #define StringSize 4096
25 
26 // variables
27 
28 static board_t UCIboard[1];
29 static bool Init=TRUE;
30 static int SavedMove=MoveNone;
31 
32 // prototypes
33 
34 static void send_uci_options();
35 
36 
37 // normalize_type()
38 
normalize_type(char * dst,const char * src)39 static void normalize_type(char *dst, const char* src){
40   if(option_get_int(Option,"UCIVersion") <=2){
41     if(IS_STRING(src)){
42       strcpy(dst,"string");
43       return;
44     }else if(IS_SPIN(src)){
45       strcpy(dst,"spin");
46     }else if(IS_BUTTON(src)){
47       strcpy(dst,"button");
48     }else{
49       strcpy(dst,src);
50     }
51   }else{
52     strcpy(dst,src);
53   }
54 }
55 
56 // parse_position()
57 
parse_position(const char string[])58 static void parse_position(const char string[]) {
59 
60 /* This is borrowed from Toga II. This code is quite hacky and will be
61    rewritten using the routines in parse.cpp.
62 */
63 
64    const char * fen;
65    char * moves;
66    const char * ptr;
67    char move_string[256];
68    int move;
69    char * string_copy;
70 
71    // init
72 
73    string_copy=my_strdup(string);
74 
75    fen = strstr(string_copy,"fen ");
76    moves = strstr(string_copy,"moves ");
77 
78    // start position
79 
80    if (fen != NULL) { // "fen" present
81 
82       if (moves != NULL) { // "moves" present
83          ASSERT(moves>fen);
84          moves[-1] = '\0'; // dirty, but so is UCI
85       }
86 
87       board_from_fen(UCIboard,fen+4); // CHANGE ME
88 
89    } else {
90 
91       // HACK: assumes startpos
92 
93       board_from_fen(UCIboard,StartFen);
94    }
95 
96    // moves
97 
98    if (moves != NULL) { // "moves" present
99 
100       ptr = moves + 6;
101 
102       while (*ptr != '\0') {
103 
104          while (*ptr == ' ') ptr++;
105 
106          move_string[0] = *ptr++;
107          move_string[1] = *ptr++;
108          move_string[2] = *ptr++;
109          move_string[3] = *ptr++;
110 
111          if (*ptr == '\0' || *ptr == ' ') {
112             move_string[4] = '\0';
113          } else { // promote
114             move_string[4] = *ptr++;
115             move_string[5] = '\0';
116          }
117          move = move_from_can(move_string,UCIboard);
118 
119          move_do(UCIboard,move);
120 
121       }
122    }
123    free(string_copy);
124 }
125 
126 
127 // send_book_move()
128 
send_book_move(int move)129 static void send_book_move(int move){
130     char move_string[256];
131     my_log("POLYGLOT *BOOK MOVE*\n");
132     move_to_can(move,UCIboard,move_string,256);
133         // bogus info lines
134     gui_send(GUI,"info depth 1 time 0 nodes 0 nps 0 cpuload 0");
135     gui_send(GUI,"bestmove %s",move_string);
136 }
137 
138 // format_uci_option_line()
139 
format_uci_option_line(char * option_line,option_t * opt)140 static void format_uci_option_line(char * option_line,option_t *opt){
141     char option_string[StringSize];
142     char type[StringSize];
143     int j;
144     strcpy(option_line,"");
145         // buffer overflow alert
146     strcat(option_line,"option name");
147     if(opt->mode&PG){
148         strcat(option_line," Polyglot");
149     }
150     sprintf(option_string," %s",opt->name);
151     strcat(option_line,option_string);
152     normalize_type(type,opt->type);
153     sprintf(option_string," type %s",type);
154     strcat(option_line,option_string);
155     if(!IS_BUTTON(opt->type)){
156         sprintf(option_string," default %s",opt->value);
157         strcat(option_line,option_string);
158     }
159     if(IS_SPIN(opt->type)){
160         sprintf(option_string," min %s",opt->min);
161         strcat(option_line,option_string);
162     }
163     if(IS_SPIN(opt->type)){
164         sprintf(option_string," max %s",opt->max);
165         strcat(option_line,option_string);
166     }
167     for(j=0;j<opt->var_nb;j++){
168         sprintf(option_string," var %s",opt->var[j]);
169         strcat(option_line,option_string);
170     }
171 }
172 
173 // send_uci_options()
174 
send_uci_options()175 static void send_uci_options() {
176 
177     option_t * opt;
178     char option_line[StringSize]="";
179     gui_send(GUI,"id name %s", Uci->name);
180     gui_send(GUI,"id author %s", Uci->author);
181     option_start_iter(Uci->option);
182     while((opt=option_next(Uci->option))){
183         format_uci_option_line(option_line,opt);
184         gui_send(GUI,"%s",option_line);
185     }
186     option_start_iter(Option);
187     while((opt=option_next(Option))){
188         if(opt->mode &UCI){
189             format_uci_option_line(option_line,opt);
190             gui_send(GUI,"%s",option_line);
191         }
192     }
193     gui_send(GUI,"uciok");
194 }
195 
196 // parse_setoption()
197 
198 
199 
parse_setoption(const char string[])200 static void parse_setoption(const char string[]) {
201     char *name;
202     char *pg_name;
203     char *value;
204     char * string_copy;
205     string_copy=my_strdup(string);
206     if(match(string_copy,"setoption name * value *")){
207         name=Star[0];
208         value=Star[1];
209         if(match(name, "Polyglot *")){
210             pg_name=Star[0];
211             polyglot_set_option(pg_name,value);
212         }else{
213             engine_send(Engine,"%s",string);
214         }
215     }else{
216         engine_send(Engine,"%s",string);
217     }
218     free(string_copy);
219 }
220 
221 
222 // uci2uci_gui_step()
223 
uci2uci_gui_step(char string[])224 void uci2uci_gui_step(char string[]) {
225     int move;
226      if(FALSE){
227      }else if(match(string,"uci")){
228          send_uci_options();
229          return;
230      }else if(match(string,"setoption *")){
231          parse_setoption(string);
232          return;
233      }else if(match(string,"position *")){
234          parse_position(string);
235          Init=FALSE;
236      }else if(match(string,"go *")){
237          if(Init){
238              board_from_fen(UCIboard,StartFen);
239              Init=FALSE;
240          }
241          SavedMove=MoveNone;
242          if(!strstr(string,"infinite")
243 	    && UCIboard->move_nb<option_get_int(Option,"BookDepth")){
244              move=book_move(UCIboard,option_get_bool(Option,"BookRandom"));
245              if (move != MoveNone && move_is_legal(move,UCIboard)) {
246                  if(strstr(string,"ponder")){
247                      SavedMove=move;
248                      return;
249                  }else{
250                      send_book_move(move);
251                      return;
252                  }
253              }
254          }
255      }else if(match(string,"ponderhit") || match(string,"stop")){
256          if(SavedMove!=MoveNone){
257          	send_book_move(SavedMove);
258          	SavedMove=MoveNone;
259          	return;
260          }
261      }else if(match(string,"quit")){
262          my_log("POLYGLOT *** \"quit\" from GUI ***\n");
263          quit();
264      }
265      engine_send(Engine,"%s",string);
266 }
267 
uci2uci_engine_step(char string[])268 void uci2uci_engine_step(char string[]) {
269     gui_send(GUI,string);
270 }
271 
272 // end of uci2uci.cpp
273