19 #include "move_legal.h"
33 static move_t BestPV[LineSize];
45 static bool depth_is_ok (int depth);
46 static void perft (const board_t * board, int depth);
52 static bool depth_is_ok(int depth) {
54 return depth >= 0 && depth < DepthMax;
59 void search(const board_t * board, int depth_max, double time_max) {
63 ASSERT(board_is_ok(board));
64 ASSERT(depth_max>=1&&depth_max<DepthMax);
65 ASSERT(time_max>=0.0);
85 uci_send_ucinewgame(Uci);
86 uci_send_isready_sync(Uci);
90 if (!board_to_fen(board,string,256)) ASSERT(FALSE);
91 engine_send(Engine,"position fen %s",string);
95 engine_send_queue(Engine,"go");
97 engine_send_queue(Engine," movetime %.0f",time_max*1000.0);
98 engine_send_queue(Engine," depth %d",depth_max);
100 engine_send(Engine,""); // newline
102 // wait for feed-back
104 while (!engine_eof(Engine)) {
106 engine_get(Engine,string);
110 } else if (match(string,"bestmove * ponder *")) {
112 BestMove = move_from_can(Star[0],board);
113 ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));
117 } else if (match(string,"bestmove *")) {
119 BestMove = move_from_can(Star[0],board);
120 ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));
131 void do_perft(int argc,char * argv[]){
132 const char * fen=NULL;
136 for (i = 1; i < argc; i++) {
138 } else if (my_string_equal(argv[i],"perft")) {
140 } else if (my_string_equal(argv[i],"-fen")) {
142 if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");
143 my_string_set(&fen,argv[i]);
144 } else if (my_string_equal(argv[i],"-max-depth")){
146 if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");
148 if(depth<1) my_fatal("do_perft(): illegal depth %d\n",depth);
150 my_fatal("do_perft(): unknown option \"%s\"\n",argv[i]);
154 my_string_set(&fen,StartFen);
156 board_from_fen(board,fen);
157 search_perft(board,depth);
162 void search_perft(const board_t * board, int depth_max) {
167 char node_string[StringSize];
168 char leafnode_string[StringSize];
170 ASSERT(board_is_ok(board));
171 ASSERT(depth_max>=1&&depth_max<DepthMax);
177 // iterative deepening
179 for (depth = 1; depth <= depth_max; depth++) {
186 my_timer_reset(timer);
188 my_timer_start(timer);
190 my_timer_stop(timer);
192 time = my_timer_elapsed_real(timer);//my_timer_elapsed_cpu(timer);
193 speed = (time < 0.01) ? 0.0 : ((double)NodeNb) / time;
195 snprintf(node_string,StringSize,S64_FORMAT,NodeNb);
196 snprintf(leafnode_string,StringSize,S64_FORMAT,LeafNb);
198 printf("depth=%2d nodes=%12s leafnodes=%12s time=%7.2fs nps=%8.0f\n",depth,node_string,leafnode_string,time,speed);
205 static void perft(const board_t * board, int depth) {
210 board_t new_board[1];
212 ASSERT(board_is_ok(board));
213 ASSERT(depth_is_ok(depth));
215 ASSERT(!is_in_check(board,colour_opp(board->turn)));
234 gen_moves(list,board);
236 for (i = 0; i < list_size(list); i++) {
238 move = list_move(list,i);
240 board_copy(new_board,board);
241 move_do(new_board,move);
243 if (!is_in_check(new_board,me)) perft(new_board,depth-1);