18 #include "move_legal.h"
28 #define StringSize 4096
32 static const bool UseDebug = FALSE;
33 static const bool UseTrace = FALSE;
40 static double MaxTime;
41 static double MinTime;
43 static int DepthDelta;
46 static int FirstDepth;
47 static int FirstSelDepth;
48 static int FirstScore;
49 static double FirstTime;
50 static uint64 FirstNodeNb;
51 static move_t FirstPV[LineSize];
55 static int LastSelDepth;
57 static double LastTime;
58 static uint64 LastNodeNb;
59 static move_t LastPV[LineSize];
61 static my_timer_t Timer[1];
65 static void epd_test_file (const char file_name[]);
67 static bool is_solution (int move, const board_t * board, const char bm[], const char am[]);
68 static bool string_contain (const char string[], const char substring[]);
70 static bool engine_step ();
76 void epd_test(int argc, char * argv[]) {
79 const char * epd_file;
82 my_string_set(&epd_file,"wac.epd");
92 for (i = 1; i < argc; i++) {
96 } else if (my_string_equal(argv[i],"epd-test")) {
100 } else if (my_string_equal(argv[i],"-epd")) {
103 if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n");
105 my_string_set(&epd_file,argv[i]);
107 } else if (my_string_equal(argv[i],"-min-depth")) {
110 if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n");
112 MinDepth = atoi(argv[i]);
114 } else if (my_string_equal(argv[i],"-max-depth")) {
117 if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n");
119 MaxDepth = atoi(argv[i]);
121 } else if (my_string_equal(argv[i],"-min-time")) {
124 if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n");
126 MinTime = atof(argv[i]);
128 } else if (my_string_equal(argv[i],"-max-time")) {
131 if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n");
133 MaxTime = atof(argv[i]);
135 } else if (my_string_equal(argv[i],"-depth-delta")) {
138 if (argv[i] == NULL) my_fatal("epd_test(): missing argument\n");
140 DepthDelta = atoi(argv[i]);
144 my_fatal("epd_test(): unknown option \"%s\"\n",argv[i]);
152 epd_test_file(epd_file);
157 static void epd_test_file(const char file_name[]) {
161 char epd[StringSize];
162 char am[StringSize], bm[StringSize], id[StringSize];
164 char string[StringSize];
166 char pv_string[StringSize];
168 double depth_tot, time_tot, node_tot;
171 ASSERT(file_name!=NULL);
175 file = fopen(file_name,"r");
176 if (file == NULL) my_fatal("epd_test_file(): can't open file \"%s\": %s\n",file_name,strerror(errno));
185 printf("\nEngineName=%s\n",option_get_string(Option,"EngineName"));
187 printf("\n[Search parameters: MaxDepth=%d MaxTime=%.1f DepthDelta=%d MinDepth=%d MinTime=%.1f]\n\n",MaxDepth,MaxTime,DepthDelta,MinDepth,MinTime);
191 while (my_file_read_line(file,epd,StringSize)) {
193 if(my_string_whitespace(epd)) continue;
194 if (UseTrace) printf("%s\n",epd);
196 if (!epd_get_op(epd,"am",am,StringSize)) strcpy(am,"");
197 if (!epd_get_op(epd,"bm",bm,StringSize)) strcpy(bm,"");
198 if (!epd_get_op(epd,"id",id,StringSize)) strcpy(id,"");
200 if (my_string_empty(am) && my_string_empty(bm)) {
201 my_fatal("epd_test(): no am or bm field at line %d\n",line);
206 uci_send_ucinewgame(Uci);
207 uci_send_isready_sync(Uci);
209 ASSERT(!Uci->searching);
212 if (!board_from_fen(board,epd)) ASSERT(FALSE);
213 if (!board_to_fen(board,string,StringSize)) ASSERT(FALSE);
215 engine_send(Engine,"position fen %s",string);
219 my_timer_start(Timer); // also resets
221 // which ones of the next two alternatives is best?
222 engine_send(Engine,"go movetime %.0f depth %d",MaxTime*1000.0,MaxDepth);
223 //engine_send(Engine,"go infinite");
227 board_copy(Uci->board,board);
230 Uci->searching = TRUE;
233 FirstMove = MoveNone;
249 // parse engine output
251 while (!engine_eof(Engine) && engine_step()) {
255 // printf("Uci->time=%.2f time=%.2f\n",Uci->time,my_timer_elapsed_real(Timer));
256 if (Uci->depth > MaxDepth){
257 my_log("POLYGLOT Maximum depth %d reached\n",MaxDepth);
259 }else if(my_timer_elapsed_real(Timer) >= MaxTime){
260 my_log("POLYGLOT Maximum search time %.2fs reached\n",MaxTime);
262 }else if(Uci->depth - FirstDepth >= DepthDelta){
263 if(Uci->depth > MinDepth){
264 if(Uci->time >= MinTime){
265 if(is_solution(FirstMove,board,bm,am)){
266 my_log("POLYGLOT Solution found\n",MaxTime);
273 my_log("POLYGLOT Stopping engine\n");
274 engine_send(Engine,"stop");
280 correct = is_solution(move,board,bm,am);
286 depth_tot += ((double)FirstDepth);
287 time_tot += FirstTime;
288 node_tot += ((double)((sint64)FirstNodeNb));
291 printf("%2d: %-15s %s %4d",tot,id,correct?"OK":"--",hit);
293 if (!line_to_san(LastPV,Uci->board,pv_string,StringSize)) ASSERT(FALSE);
294 printf(" score=%+6.2f pv [D=%2d, T=%7.2fs, N=%6dk] =%s\n",((double)LastScore)/100.0,FirstDepth,FirstTime,(int)FirstNodeNb/1000,pv_string);
297 printf("\nscore=%d/%d",hit,tot);
301 depth_tot /= ((double)hit);
302 time_tot /= ((double)hit);
303 node_tot /= ((double)hit);
305 printf(" [averages on correct positions: depth=%.1f time=%.2f nodes=%.0f]",depth_tot,time_tot,node_tot);
316 static bool is_solution(int move, const board_t * board, const char bm[], const char am[]) {
318 char move_string[256];
321 ASSERT(move!=MoveNone);
325 if (!move_is_legal(move,board)) {
327 move_disp(move,board);
331 ASSERT(move_is_legal(move,board));
333 if (!move_to_san(move,board,move_string,256)) ASSERT(FALSE);
336 if (!my_string_empty(bm)) {
337 correct = string_contain(bm,move_string);
338 } else if (!my_string_empty(am)) {
339 correct = !string_contain(am,move_string);
349 bool epd_get_op(const char record[], const char opcode[], char string[], int size) {
353 const char *p_start, *p_end;
355 ASSERT(record!=NULL);
356 ASSERT(opcode!=NULL);
357 ASSERT(string!=NULL);
362 sprintf(op," %s ",opcode);
364 p_start = strstr(record,op);
365 if (p_start == NULL){
366 sprintf(op,";%s ",opcode);
367 p_start = strstr(record,op);
368 if (p_start == NULL){
375 p_start += strlen(op);
378 p_end = strchr(p_start,';');
379 if (p_end == NULL) return FALSE;
381 // calculate the length
383 len = p_end - p_start;
384 if (size < len+1) my_fatal("epd_get_op(): size < len+1\n");
386 strncpy(string,p_start,len);
394 static bool string_contain(const char string[], const char substring[]) {
396 char new_string[StringSize], *p;
398 strcpy(new_string,string); // HACK
400 for (p = strtok(new_string," "); p != NULL; p = strtok(NULL," ")) {
401 if (my_string_equal(p,substring)) return TRUE;
409 static bool engine_step() {
411 char string[StringSize];
414 engine_get(Engine,string);
415 event = uci_parse(Uci,string);
417 if ((event & EVENT_MOVE) != 0) {
422 if ((event & EVENT_PV) != 0) {
424 LastMove = Uci->best_pv[0];
425 LastDepth = Uci->best_depth;
426 LastSelDepth = Uci->best_sel_depth;
427 LastScore = Uci->best_score;
428 LastTime = Uci->time;
429 LastNodeNb = Uci->node_nb;
430 line_copy(LastPV,Uci->best_pv);
432 if (LastMove != FirstMove) {
433 FirstMove = LastMove;
434 FirstDepth = LastDepth;
435 FirstSelDepth = LastSelDepth;
436 FirstScore = LastScore;
437 FirstTime = LastTime;
438 FirstNodeNb = LastNodeNb;
439 line_copy(FirstPV,LastPV);