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
*200);
317 fprintf(out
, "otim %d\n", time
*200);
318 fprintf(out
, "go\n");
320 while(fgets(buf
, 1024, in
))
323 if(!strncmp(buf
, "move ", 5))
325 sscanf ( buf
, "move %s", mv
);
326 m
= board
.move_from_string(mv
);
329 output("Got illegal move %s\n", mv
);
341 output("Result: \e[36;1m%s\e[0m\n", board
.move_to_alg(MoveStr().data(), m
));
342 for(int i
=0;i
<num_avoid
;i
++)
347 output("Test %d \e[31;1mFAILURE\e[0m, %s did not avoid the "
348 "wrong move \e[33;1m%s\e[0m (che pollo!)\n",done
, prog
,
349 board
.move_to_alg(MoveStr().data(), avoid_mv
[i
]));
351 if(num_avoid
&& !fail
&& !quiet
)
352 output("Test %d \e[32;1mSUCCESS\e[0m, %s avoided the "
353 "wrong move%s \e[33;1m%s\e[0m (teto figo!)\n",
354 done
, prog
, num_avoid
>1?"s":"", avoid
);
355 if(!fail
&& num_best
)
358 for(int i
=0;i
<num_best
;i
++)
363 output("Test %d \e[32;1mSUCCESS\e[0m, %s found the "
364 "best move \e[33;1m%s\e[0m (o se figo!)\n",
365 done
, prog
, board
.move_to_alg(MoveStr().data(), best_mv
[i
]));
369 output("Test %d \e[31;1mFAILURE\e[0m, %s missed the best "
370 "move%s (\e[33;1m%s\e[0m) (che scarso!)\n", done
, prog
,
371 num_best
>1?"s":"", best
);
379 output("Test %d %s %s! (+%d, -%d, ~%d%%)\n", done
, name
, fail
?
380 "\e[31;1mFAILED\e[0m" : "\e[32;1mPASSED\e[0m",
381 passed
, done
-passed
, passed
*100/done
);
383 output("%s", fail
? "-" : "+");
385 snprintf(str
, 40, "(%d/%d)", passed
, done
);
389 fwrite(str
, 2*l
, 1, stdout
);
395 output("Passed %d tests out of %d (%d%%)\n", passed
, done
, passed
*100/done
);
398 output("Failed are:\n");
400 for(int i
=1;i
<done
+1;i
++)
404 if(((++numsh
) % 10) == 0)
410 if(strcmp(prog
, "self"))
412 fprintf(out
, "quit\n");
421 void Engine::save_pgn(FILE *f
, const char *result1
, const char *result
)
423 for(int i
=mv_done_num
-1;i
>=0;i
--)
424 board
.undo_move(mv_done
[i
], save_buf
[--save_buf_num
]);
426 fprintf(f
, "[White \"%s\"]\n", st_computer_color
== WHITE
?
427 "RattateChess" : opponent
);
428 fprintf(f
, "[Black \"%s\"]\n", st_computer_color
== BLACK
?
429 "RattateChess" : opponent
);
430 fprintf(f
, "[WhiteELO \"%d\"]\n", w_rating
);
431 fprintf(f
, "[BlackELO \"%d\"]\n", b_rating
);
433 time_t t
= time(NULL
);
435 strftime(tbuf
, 256, "%Y.%m.%d %H:%M", localtime(&t
));
436 fprintf(f
, "[Date \"%s\"]\n", tbuf
);
437 fprintf(f
, "[Result \"%s\"]\n", result1
);
440 fprintf(f
, "[FEN \"%s\"]\n", board
.to_fen(BigStr().data()) );
442 if(board
.color_to_move
==BLACK
)
443 fprintf(f
, "%d. ... ",board
.num_moves
+1);
444 for(int i
=0;i
<mv_done_num
;i
++)
446 if(board
.color_to_move
==WHITE
)
447 fprintf(f
, "%d. ",board
.num_moves
+1);
448 fprintf(f
, "%s ", board
.move_to_alg(MoveStr().data(), mv_done
[i
]) );
449 if((i
+1)%14 == 0 && i
!=mv_done_num
-1)
451 board
.do_move(mv_done
[i
], save_buf
[save_buf_num
++]);
453 fprintf(f
, "\n%s\n\n", result
);
456 void Engine::challenge(const char* prog
, int time
, const char* file
)
463 int won
=0, draw
=0, lost
=0;
465 /* open the file with the tests */
466 f
= fopen(file
, "r");
467 log
= fopen("challenge.pgn", "w");
471 output("Error, could not open %s for reading!\n", file
);
475 start_engine(prog
, &in
, &out
);
477 while(fgets(buf
, 1024, f
))
479 uint8_t cols
[2] = {WHITE
, BLACK
};
483 bool go_done
= false;
485 //set_max_nodes(time);
486 //set_time_fixed(time);
487 set_time_control(40, time
, 0);
490 fprintf(out
, "new\n");
491 //fprintf(out, "st %d\n", time);
492 fprintf(out
, "level 40 %d:%d 0\n", time
/60, time
%60);
493 fprintf(out
, "force\n");
494 fprintf(out
, "setboard %s\n", board
.to_fen(BigStr().data()));
498 st_computer_color
= cols
[i
];
505 board.print_board();*/
507 /* print the pgn to the log file */
508 if(status
!= PLAYING
)
510 const char *result
= status
==_01
?"0-1":(status
==_10
?"1-0":"1/2-1/2");
511 const char *white
= st_computer_color
== WHITE
? "Rattatechess" : prog
;
512 const char *black
= st_computer_color
== BLACK
? "Rattatechess" : prog
;
516 for(int i
=mv_done_num
-1;i
>=0;i
--)
517 board
.undo_move(mv_done
[i
], save_buf
[--save_buf_num
]);
519 fprintf(log
, "[White \"%s\"]\n", white
);
520 fprintf(log
, "[Black \"%s\"]\n", black
);
521 fprintf(log
, "[Result \"%s\"]\n", result
);
522 fprintf(log
, "[FEN \"%s\"]\n", board
.to_fen(BigStr().data()) );
524 if(board
.color_to_move
==BLACK
)
525 fprintf(log
, "%d. ... ",board
.num_moves
+1);
526 for(int i
=0;i
<mv_done_num
;i
++)
528 if(board
.color_to_move
==WHITE
)
529 fprintf(log
, "%d. ",board
.num_moves
+1);
530 fprintf(log
, "%s ", board
.move_to_alg(MoveStr().data(), mv_done
[i
]) );
533 board
.do_move(mv_done
[i
], save_buf
[save_buf_num
++]);
535 fprintf(log
, "%s\n\n", result
);
539 if((status
==_01
&& st_computer_color
==BLACK
) ||
540 (status
==_10
&& st_computer_color
==WHITE
))
542 output("RATTA!!!\n");
558 /* think or wait for a new move */
559 if(st_computer_color
== board
.color_to_move
)
562 Move mv
= find_best_move();
563 output("%d. %s %s\n",board
.num_moves
+1,
564 board
.color_to_move
==BLACK
? "..." : "",
565 board
.move_to_alg(MoveStr().data(), mv
) );
566 fprintf( out
, "%s\n", Board::move_to_coord(MoveStr().data(), mv
));
573 fprintf( out
, "go\n");
577 while(fgets(buf
, 1024, in
))
579 /* get a move from the other engine */
580 if(!strncmp(buf
, "move ", 5))
584 sscanf( buf
, "move %s", buf2
);
585 mv
= board
.move_from_string(buf2
);
588 output("Got illegal move %s\n", buf2
);
591 output("%d. %s %s\n",board
.num_moves
+1,
592 board
.color_to_move
==BLACK
? "..." : "",
593 board
.move_to_alg(MoveStr().data(), mv
) );
597 else if(!strcmp(buf
, "resign"))
599 status
= board
.color_to_move
==WHITE
?_01
:_10
;
610 fprintf(out
, "quit\n");
616 output("\n\n%d games played (+%d =%d -%d)\n", won
+draw
+lost
, won
, draw
, lost
);