Add option to resign only without queen
[polyglot.git] / option.c
1
2 // option.c
3
4 // includes
5
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "option.h"
10 #include "util.h"
11
12
13 // defines
14
15 #define NNB { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }
16
17 // constants
18
19 static const bool UseDebug = FALSE;
20
21 // variables
22
23
24 option_list_t Option[1];
25
26 option_t DefaultOptions[] = {    
27    // options
28
29     { "SettingsFile",     "file","0","0",       "polyglot.ini", NULL,0,NNB,  PG|XBOARD|XBSEL}, 
30
31     { "SettingsDir",      "path","0","0",       "<empty>"   , NULL,0,NNB,  PG},
32
33     { "OnlyWbOptions",    "check","0","0",      "true"      , NULL,0,NNB,  PG|XBOARD},
34
35     { "EngineName",       "string","0","0",     "<empty>"   , NULL,0,NNB,  PG}, 
36     { "EngineDir",        "path","0","0",       "."         , NULL,0,NNB,  PG}, 
37     { "EngineCommand",    "string","0","0",     "<empty>"   , NULL,0,NNB,  PG}, 
38
39     { "Log",              "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD|XBSEL|UCI}, 
40     { "LogFile",          "file","0","0",       "polyglot.log", NULL,0,NNB,  PG|XBOARD|XBSEL|UCI}, 
41
42     { "UCI",              "check","0","0",      "false"     , NULL,0,NNB,  PG}, 
43
44     { "UseNice",          "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD|UCI}, 
45     { "NiceValue",        "spin", "0","20",     "5"         , NULL,0,NNB,  PG|XBOARD|UCI}, 
46
47     { "Resign",           "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD|XBSEL}, 
48     { "ResignMoves",      "spin","0","10000",    "3"        , NULL,0,NNB,  PG|XBOARD|XBSEL}, 
49     { "QueenNeverResigns","check","0","0",      "true"      , NULL,0,NNB,  PG|XBOARD|XBSEL}, 
50     { "ResignScore",      "spin","0","10000",   "600"       , NULL,0,NNB,  PG|XBOARD|XBSEL}, 
51
52     { "MateScore",        "spin","0","100000",  "10000"     , NULL,0,NNB,  PG|XBOARD}, 
53
54     { "Book",             "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD|XBSEL|UCI}, 
55     { "BookFile",         "file","0","0",       "book.bin"  , NULL,0,NNB,  PG|XBOARD|XBSEL|UCI}, 
56
57     { "BookRandom",       "check","0","0",      "true"      , NULL,0,NNB,  PG|XBOARD|XBSEL|UCI}, 
58     { "BookDepth",        "spin","0","256",     "256"       , NULL,0,NNB,  PG|XBOARD|XBSEL|UCI}, 
59     { "BookTreshold",     "spin","0","1000",    "5"         , NULL,0,NNB,  PG|XBOARD|UCI}, 
60     { "BookLearn",        "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD}, 
61
62     { "KibitzMove",       "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD}, 
63     { "KibitzPV",         "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD}, 
64
65     { "KibitzCommand",    "string","0","0",     "tellall"   , NULL,0,NNB,  PG|XBOARD}, 
66     { "KibitzDelay",      "spin","0","1000",    "5"         , NULL,0,NNB,  PG|XBOARD}, 
67     { "KibitzInterval",   "spin","0","1000",    "0"         , NULL,0,NNB,  PG|XBOARD}, 
68
69     { "ShowPonder",       "check","0","0",      "true"      , NULL,0,NNB,  PG|XBOARD}, 
70     { "ScoreWhite",       "check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD}, 
71
72     { "STFudge",          "spin","0","1000",      "20"      , NULL,0,NNB,  PG|XBOARD|XBSEL}, 
73
74    // work-arounds
75
76     { "UCIVersion",       "spin","1","2",       "2"         , NULL,0,NNB,  PG|XBOARD}, 
77     { "CanPonder",        "check","1","2",      "false"     , NULL,0,NNB,  PG|XBOARD}, 
78     { "SyncStop",         "check","1","2",      "false"     , NULL,0,NNB,  PG|XBOARD|XBSEL}, 
79     { "Affinity",         "spin","-1","32",     "-1"        , NULL,0,NNB,  PG}, 
80     { "RepeatPV",         "check","0","0",      "true"      , NULL,0,NNB,  PG|XBOARD},
81     { "PromoteWorkAround","check","0","0",      "false"     , NULL,0,NNB,  PG|XBOARD},
82
83    // internal
84
85     { "Chess960",         "check","0","0",      "false"     , NULL,0,NNB,  PG}, 
86
87    // These options flag various hacks in the source to work around
88    // WB quirks. They will eventually all be set to false. Probably
89    // in 4.5.0
90     
91     { "WbWorkArounds",    "check","0","0",      "true"      , NULL,0,NNB,  PG}, 
92     { "WbWorkArounds2",   "check","0","0",      "false"     , NULL,0,NNB,  PG}, 
93     { "WbWorkArounds3",   "check","0","0",      "true"      , NULL,0,NNB,  PG}, 
94
95     // Buttons
96
97     { "Save",             "save","0","0",       "false"     , NULL,0,NNB,  PG|XBOARD|XBSEL},
98
99     // Sentinel
100     
101     { NULL,               NULL,"0","0",         NULL        , NULL,0,NNB,  0},
102
103 };
104
105
106 // functions
107
108 // option_is_ok()
109
110 bool option_is_ok(const option_list_t *option) {
111     if(option->option_nb<0 || option->option_nb>=OptionNb){
112         return FALSE;
113     }
114     return TRUE;
115 }
116
117 // option_init_pg()
118
119 void option_init_pg() {
120
121     int i;
122     option_t *p=DefaultOptions;
123     char *home_dir;
124     char SettingsDir[StringSize];
125     
126     option_init(Option);
127     while(p){
128         if(p->name){
129             option_insert(Option,p);
130             p++;
131         }else{
132             break;
133         }
134     }
135     for(i=0;i<Option->option_nb;i++){
136         Option->options[i].value=my_strdup(Option->options[i].default_);
137     }
138 #ifndef _WIN32
139     home_dir=getenv("HOME");
140     if(!home_dir){
141         home_dir=".";
142     }
143     snprintf(SettingsDir,sizeof(SettingsDir),"%s/.polyglot",home_dir);
144     SettingsDir[sizeof(SettingsDir)-1]='\0';
145 #else
146     sprintf(SettingsDir,".\\_PG");
147 #endif
148     option_set(Option,"SettingsDir",SettingsDir);
149     option_set_default(Option,"SettingsDir",SettingsDir);
150 }
151
152 // option_init()
153
154 void option_init(option_list_t *option){
155     ASSERT(option!=NULL);
156     option->option_nb=0;
157     option->iter=0;
158     memset(option->options,0,sizeof(option->options));
159 }
160
161 // option_insert()
162
163 void option_insert(option_list_t *option, option_t *new_option){
164     int i;
165     option_t *opt;
166     ASSERT(option!=NULL);
167     ASSERT(new_option!=NULL);
168     ASSERT(new_option->name!=NULL);
169     opt=option_find(option,new_option->name);
170     if(!opt){
171         opt=&option->options[option->option_nb];
172         option->option_nb++;
173     }
174     if(option->option_nb>=OptionNb){
175         my_fatal("option_insert(): option list overflow\n");
176     }
177     if(new_option->name)     my_string_set(&opt->name,     new_option->name);
178     if(new_option->value)    my_string_set(&opt->value,    new_option->value);
179     if(new_option->min)      my_string_set(&opt->min,      new_option->min);
180     if(new_option->max)      my_string_set(&opt->max,      new_option->max);
181     if(new_option->default_) my_string_set(&opt->default_, new_option->default_);
182     if(new_option->type)     my_string_set(&opt->type,     new_option->type);
183     opt->var_nb=new_option->var_nb;
184     for(i=0;i<new_option->var_nb;i++){
185         my_string_set(&opt->var[i], new_option->var[i]);
186     }
187     opt->mode=new_option->mode;
188 }
189
190 // option_set()
191
192 bool option_set(option_list_t *option, 
193                 const char name[], 
194                 const char value[]) {
195
196    option_t * opt;
197    ASSERT(option!=NULL);
198    ASSERT(name!=NULL);
199    ASSERT(value!=NULL);
200
201    opt = option_find(option,name);
202    if (opt == NULL) return FALSE;
203
204    if(my_string_case_equal(opt->type,"check")){
205       value=(my_string_equal(value,"1")||
206              my_string_case_equal(value,"true"))?"true":"false";
207    }
208
209    my_string_set(&opt->value,value);
210
211    if (UseDebug) my_log("POLYGLOT OPTION SET \"%s\" -> \"%s\"\n",opt->name,opt->value);
212
213    return TRUE;
214 }
215
216 // option_set_default()
217
218 bool option_set_default(option_list_t *option,
219                            const char name[], 
220                            const char value[]) {
221
222    option_t * opt;
223    ASSERT(name!=NULL);
224    ASSERT(value!=NULL);
225
226    opt = option_find(option,name);
227    if (opt == NULL) return FALSE;
228
229    if(my_string_case_equal(opt->type,"check")){
230       value=(my_string_equal(value,"1")||
231              my_string_case_equal(value,"true"))?"true":"false";
232    }
233
234    my_string_set(&opt->default_,value);
235
236    if (UseDebug) my_log("POLYGLOT OPTION DEFAULT SET \"%s\" -> \"%s\"\n",opt->name,opt->default_);
237
238    return TRUE;
239 }
240
241 // option_get()
242
243 const char * option_get(option_list_t *option, const char name[]) {
244
245    option_t * opt;
246
247    ASSERT(name!=NULL);
248
249    opt = option_find(option,name);
250    if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name);
251    if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value);
252
253    return opt->value;
254 }
255
256 // option_get_default()
257
258 const char * option_get_default(option_list_t *option, const char name[]) {
259
260    option_t * opt;
261
262    ASSERT(name!=NULL);
263
264    opt = option_find(option,name);
265    if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name);
266
267    if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value);
268
269    return opt->default_;
270 }
271
272 // option_get_bool()
273
274 bool option_get_bool(option_list_t *option, const char name[]) {
275
276    const char * value;
277
278    value = option_get(option,name);
279
280    if (FALSE) {
281    } else if (my_string_case_equal(value,"true") || my_string_case_equal(value,"yes") || my_string_equal(value,"1")) {
282       return TRUE;
283    } else if (my_string_case_equal(value,"false") || my_string_case_equal(value,"no") || my_string_equal(value,"0")) {
284       return FALSE;
285    }
286
287    ASSERT(FALSE);
288
289    return FALSE;
290 }
291
292
293 // option_get_double()
294
295 double option_get_double(option_list_t *option, const char name[]) {
296
297    const char * value;
298
299    value = option_get(option,name);
300
301    return atof(value);
302 }
303
304 // option_get_int()
305
306 int option_get_int(option_list_t *option, const char name[]) {
307
308    const char * value;
309
310    value = option_get(option,name);
311
312    return atoi(value);
313 }
314
315 // option_get_string()
316
317 const char * option_get_string(option_list_t *option, const char name[]) {
318
319    const char * value;
320
321    value = option_get(option,name);
322
323    return value;
324 }
325
326 // option_find()
327
328 option_t * option_find(option_list_t *option, const char name[]) {
329
330    option_t * opt;
331    int i;
332
333    ASSERT(name!=NULL);
334    for (i=0; i<option->option_nb; i++){
335        opt=option->options+i;
336        if (my_string_case_equal(opt->name,name)){
337            return opt;
338        }
339    }
340    
341    return NULL;
342 }
343
344 // option_start_iter()
345
346 void option_start_iter(option_list_t *option){
347     option->iter=0;
348 }
349
350 // option_next()
351
352 option_t * option_next(option_list_t *option){
353     ASSERT(option->iter<=option->option_nb);
354     if(option->iter==option->option_nb){
355         return NULL;
356     }
357     return &option->options[option->iter++];
358         
359 }
360
361 void option_free(option_t *option){
362       int i;
363       my_string_clear(&option->name);
364       my_string_clear(&option->type);
365       my_string_clear(&option->min);
366       my_string_clear(&option->max);
367       my_string_clear(&option->default_);
368       my_string_clear(&option->value);
369       for(i=0;i<option->var_nb;i++){
370          my_string_clear(&option->var[i]);
371       }
372       option->var_nb=0;
373       option->mode=0;
374 }
375
376 // option_clear()
377
378 void option_clear(option_list_t *option){
379     int i;
380     for (i = 0; i < option->option_nb; i++) {
381         option_free(option->options+i);
382    }
383    option->option_nb=0;
384 }
385
386 // option_from_ini()
387
388 void option_from_ini(option_list_t *option,
389                      ini_t *ini,
390                      const char *section){
391     ini_entry_t *entry;
392     ini_start_iter(ini);
393     while((entry=ini_next(ini))){
394         option_set(option,entry->name,entry->value);
395         option_set_default(option,entry->name,entry->value);
396     }
397 }
398
399 // end of option.cpp
400