1 /***************************************************************************
2 moveparse.cpp - description
4 begin : mer ott 30 2002
5 copyright : (C) 2002-2007 by Maurizio Monge
6 email : monge@linuz.sns.it
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
22 void Engine::print_moves(Move
* m
, int num
, bool nums
, bool walk_ht
)
25 if(board
.color_to_move
==BLACK
&&nums
)
26 output("%d. ...",board
.num_moves
+1);
33 if(board
.color_to_move
==WHITE
&& nums
)
34 printf(" %d.",board
.num_moves
+1);
35 output(" %s", board
.move_to_alg(MoveStr().data(), m
[i
]) );
36 board
.do_move(m
[i
], save_buf
[save_buf_num
++]);
44 HashEntry
*h
= probe_hash( board
.hash
);
45 if(!h
|| !h
->best_mv
|| h
->depth
<0)
48 /* don't follow the hash if there is draw for repetition :) */
55 hash_mv
[j
] = board
.uncompress_move( h
->best_mv
);
57 /* verify that the move in the hash is a legal move */
59 int num_tmp
= board
.find_moves(tmp
);
61 for(int q
=0;q
<num_tmp
;q
++)
62 if(tmp
[q
] == hash_mv
[j
])
74 if(board
.color_to_move
==WHITE
&& nums
)
75 output(" %d.",board
.num_moves
+1);
76 output( " %s", board
.move_to_alg(MoveStr().data(), hash_mv
[j
]) );
77 board
.do_move(hash_mv
[j
], save_buf
[save_buf_num
++]);
81 board
.undo_move(hash_mv
[j
], save_buf
[--save_buf_num
]);
85 board
.undo_move(m
[i
], save_buf
[--save_buf_num
]);
90 /* TODO: load correctly the pgn that start with a fen */
91 int Engine::load_pgn(FILE *f
)
95 board
.set_as_default();
100 if(!fgets(buf
, 1024, f
))
102 if(buf
[0]=='\n' || buf
[0]=='\r' || buf
[0]=='\t'
103 || buf
[0]==' ' || buf
[0]=='[' || buf
[0]=='#')
111 ptr
+= strspn(ptr
, ". \t\r\n");
118 char *tmp
= (ptr
+= strcspn(ptr
, ". \t\r\n"));
119 ptr
+= strspn(ptr
, ". \t\r\n");
122 /* is this the result? */
123 if(!strcmp(t
, "1-0"))
128 else if(!strcmp(t
, "0-1"))
133 else if(!strcmp(t
, "1/2-1/2") || !strcmp(t
, "*"))
139 /* is this a move number? */
145 Move mv
= board
.move_from_string(t
);
149 output("Error! \"%s\" %x\n", t
, mv
.as_int
);
150 return 0; /* error */
153 mv_done
[mv_done_num
++] = mv
;
154 board
.do_move(mv
, save_buf
[save_buf_num
++]);
157 if(!fgets(buf
, 1024, f
))
162 int Engine::run_epd_prog(const char* prog
, int time
, const char* file
, bool quiet
)
170 /* open the file with the tests */
171 f
= fopen(file
, "r");
174 output("Error, could not open %s for reading!\n", file
);
178 if(!strcmp(prog
, "self"))
182 set_time_fixed(time
);
185 start_engine(prog
, &in
, &out
);
187 /* reset passed flags */
190 for(int i
=0;i
<8000;i
++)
193 while(fgets(buf
, 1024, f
))
196 char color
[2],castle
[5],passing
[3];
199 char name
[64];// = "unknown";
209 sscanf(buf
,"%s%s%s%s",
210 brd
,color
,castle
,passing
);
211 read_board(brd
,color
,castle
,passing
,0,0);
220 //printf("%s\n", buf);
222 /* save the best moves in the best_mv array */
223 tmp
= strstr(buf
, "bm");
227 sscanf(tmp
, "bm %63[^;];", best
);
228 tok
+= strspn(best
+ tok
, " \t\r\n");
230 for(num_best
=0;num_best
<10;num_best
++)
236 int firstspace
= (tok
+= strcspn(best
+ tok
, " \t\r\n"));
237 tok
+= strspn(best
+ tok
, " \t\r\n");
238 best
[firstspace
] = 0;
240 best_mv
[num_best
] = board
.move_from_string(best
+start
);
242 if(!best_mv
[num_best
].valid())
244 output("Error, could not parse move %s in pos %d\n", best
+start
, done
);
250 /* save the avoid moves in the best_mv array */
251 tmp
= strstr(buf
, "am");
255 sscanf(tmp
, "am %63[^;];", avoid
);
256 tok
+= strspn(avoid
+ tok
, " \t\r\n");
258 for(num_avoid
=0;num_avoid
<10;num_avoid
++)
264 int firstspace
= (tok
+= strcspn(avoid
+ tok
, " \t\r\n"));
265 tok
+= strspn(avoid
+ tok
, " \t\r\n");
266 avoid
[firstspace
] = 0;
268 avoid_mv
[num_avoid
] = board
.move_from_string(avoid
+start
);
270 if(!avoid_mv
[num_avoid
].valid())
272 output("Error, could not parse move %s in pos %d\n", best
+start
, done
);
279 tmp
= strstr(buf
, "id");
281 sscanf ( tmp
, "id %63[^;];", name
);
283 strcpy( name
, "<unknown>" );
287 output(" %d - Thinking", done
);
290 output(", the best move%s\e[32;1m", num_best
>1 ? "s are" : " is");
291 for(int i
=0;i
<num_best
;i
++)
292 output(" %s", board
.move_to_alg(MoveStr().data(), best_mv
[i
]) );
297 output(", the move%s to avoid\e[31;1m", num_avoid
>1 ? "s are" : " is");
298 for(int i
=0;i
<num_avoid
;i
++)
299 output(" %s", board
.move_to_alg(MoveStr().data(), avoid_mv
[i
]) );
305 if(!strcmp(prog
, "self"))
307 st_computer_color
= board
.color_to_move
;
308 m
= find_best_move();
312 fprintf(out
, "force\n");
313 fprintf(out
, "setboard %s\n", board
.to_fen(BigStr().data()) );
314 fprintf(out
, "st %d\n", time
);
315 //fprintf(out, "level 1 %d 0\n", time);
316 //fprintf(out, "time %d\n", time*100);
317 //fprintf(out, "otim %d\n", time*100);
318 fprintf(out
, "post\n");
319 fprintf(out
, "go\n");
322 //fprintf(out, "?\n");
324 while(fgets(buf
, 1024, in
))
327 if(!strncmp(buf
, "move ", 5))
329 sscanf ( buf
, "move %s", mv
);
330 m
= board
.move_from_string(mv
);
333 output("Got illegal move %s\n", mv
);
345 output("Result: \e[36;1m%s\e[0m\n", board
.move_to_alg(MoveStr().data(), m
));
346 for(int i
=0;i
<num_avoid
;i
++)
351 output("Test %d \e[31;1mFAILURE\e[0m, %s did not avoid the "
352 "wrong move \e[33;1m%s\e[0m (che pollo!)\n",done
, prog
,
353 board
.move_to_alg(MoveStr().data(), avoid_mv
[i
]));
355 if(num_avoid
&& !fail
&& !quiet
)
356 output("Test %d \e[32;1mSUCCESS\e[0m, %s avoided the "
357 "wrong move%s \e[33;1m%s\e[0m (teto figo!)\n",
358 done
, prog
, num_avoid
>1?"s":"", avoid
);
359 if(!fail
&& num_best
)
362 for(int i
=0;i
<num_best
;i
++)
367 output("Test %d \e[32;1mSUCCESS\e[0m, %s found the "
368 "best move \e[33;1m%s\e[0m (o se figo!)\n",
369 done
, prog
, board
.move_to_alg(MoveStr().data(), best_mv
[i
]));
373 output("Test %d \e[31;1mFAILURE\e[0m, %s missed the best "
374 "move%s (\e[33;1m%s\e[0m) (che scarso!)\n", done
, prog
,
375 num_best
>1?"s":"", best
);
383 output("Test %d %s %s! (+%d, -%d, ~%d%%)\n", done
, name
, fail
?
384 "\e[31;1mFAILED\e[0m" : "\e[32;1mPASSED\e[0m",
385 passed
, done
-passed
, passed
*100/done
);
387 output("%s", fail
? "-" : "+");
389 snprintf(str
, 40, "(%d/%d)", passed
, done
);
393 fwrite(str
, 2*l
, 1, stdout
);
399 output("Passed %d tests out of %d (%d%%)\n", passed
, done
, passed
*100/done
);
402 output("Failed are:\n");
404 for(int i
=1;i
<done
+1;i
++)
408 if(((++numsh
) % 10) == 0)
414 if(strcmp(prog
, "self"))
416 fprintf(out
, "quit\n");
425 void Engine::save_pgn(FILE *f
, const char *result1
, const char *result
)
427 for(int i
=mv_done_num
-1;i
>=0;i
--)
428 board
.undo_move(mv_done
[i
], save_buf
[--save_buf_num
]);
430 fprintf(f
, "[White \"%s\"]\n", st_computer_color
== WHITE
?
431 "RattateChess" : opponent
);
432 fprintf(f
, "[Black \"%s\"]\n", st_computer_color
== BLACK
?
433 "RattateChess" : opponent
);
434 fprintf(f
, "[WhiteELO \"%d\"]\n", w_rating
);
435 fprintf(f
, "[BlackELO \"%d\"]\n", b_rating
);
437 time_t t
= time(NULL
);
439 strftime(tbuf
, 256, "%Y.%m.%d %H:%M", localtime(&t
));
440 fprintf(f
, "[Date \"%s\"]\n", tbuf
);
441 fprintf(f
, "[Result \"%s\"]\n", result1
);
444 fprintf(f
, "[FEN \"%s\"]\n", board
.to_fen(BigStr().data()) );
446 if(board
.color_to_move
==BLACK
)
447 fprintf(f
, "%d. ... ",board
.num_moves
+1);
448 for(int i
=0;i
<mv_done_num
;i
++)
450 if(board
.color_to_move
==WHITE
)
451 fprintf(f
, "%d. ",board
.num_moves
+1);
452 fprintf(f
, "%s ", board
.move_to_alg(MoveStr().data(), mv_done
[i
]) );
453 if((i
+1)%14 == 0 && i
!=mv_done_num
-1)
455 board
.do_move(mv_done
[i
], save_buf
[save_buf_num
++]);
457 fprintf(f
, "\n%s\n\n", result
);
460 void Engine::challenge(const char* prog
, int time
, const char* file
)
467 int won
=0, draw
=0, lost
=0;
469 /* open the file with the tests */
470 f
= fopen(file
, "r");
471 log
= fopen("challenge.pgn", "w");
475 output("Error, could not open %s for reading!\n", file
);
479 start_engine(prog
, &in
, &out
);
481 while(fgets(buf
, 1024, f
))
483 uint8_t cols
[2] = {WHITE
, BLACK
};
487 bool go_done
= false;
489 //set_max_nodes(time);
490 set_time_fixed(time
);
491 //set_time_control(40, time, 0);
494 fprintf(out
, "new\n");
495 fprintf(out
, "st %d\n", time
);
496 //fprintf(out, "level 40 %d:%d 0\n", time/60, time%60);
497 fprintf(out
, "force\n");
498 fprintf(out
, "setboard %s\n", board
.to_fen(BigStr().data()));
502 st_computer_color
= cols
[i
];
511 /* print the pgn to the log file */
512 if(status
!= PLAYING
)
514 const char *result
= status
==_01
?"0-1":(status
==_10
?"1-0":"1/2-1/2");
515 const char *white
= st_computer_color
== WHITE
? "Rattatechess" : prog
;
516 const char *black
= st_computer_color
== BLACK
? "Rattatechess" : prog
;
520 for(int i
=mv_done_num
-1;i
>=0;i
--)
521 board
.undo_move(mv_done
[i
], save_buf
[--save_buf_num
]);
523 fprintf(log
, "[White \"%s\"]\n", white
);
524 fprintf(log
, "[Black \"%s\"]\n", black
);
525 fprintf(log
, "[Result \"%s\"]\n", result
);
526 fprintf(log
, "[FEN \"%s\"]\n", board
.to_fen(BigStr().data()) );
528 if(board
.color_to_move
==BLACK
)
529 fprintf(log
, "%d. ... ",board
.num_moves
+1);
530 for(int i
=0;i
<mv_done_num
;i
++)
532 if(board
.color_to_move
==WHITE
)
533 fprintf(log
, "%d. ",board
.num_moves
+1);
534 fprintf(log
, "%s ", board
.move_to_alg(MoveStr().data(), mv_done
[i
]) );
537 board
.do_move(mv_done
[i
], save_buf
[save_buf_num
++]);
539 fprintf(log
, "%s\n\n", result
);
543 if((status
==_01
&& st_computer_color
==BLACK
) ||
544 (status
==_10
&& st_computer_color
==WHITE
))
546 output("RATTA!!!\n");
562 /* think or wait for a new move */
563 if(st_computer_color
== board
.color_to_move
)
566 Move mv
= find_best_move();
567 output("%d. %s %s\n",board
.num_moves
+1,
568 board
.color_to_move
==BLACK
? "..." : "",
569 board
.move_to_alg(MoveStr().data(), mv
) );
570 fprintf( out
, "%s\n", Board::move_to_coord(MoveStr().data(), mv
));
577 fprintf( out
, "go\n");
581 while(fgets(buf
, 1024, in
))
583 /* get a move from the other engine */
584 if(!strncmp(buf
, "move ", 5))
588 sscanf( buf
, "move %s", buf2
);
589 mv
= board
.move_from_string(buf2
);
592 output("Got illegal move %s\n", buf2
);
595 output("%d. %s %s\n",board
.num_moves
+1,
596 board
.color_to_move
==BLACK
? "..." : "",
597 board
.move_to_alg(MoveStr().data(), mv
) );
601 else if(!strcmp(buf
, "resign"))
603 status
= board
.color_to_move
==WHITE
?_01
:_10
;
614 fprintf(out
, "quit\n");
620 output("\n\n%d games played (+%d =%d -%d)\n", won
+draw
+lost
, won
, draw
, lost
);