17 #include "move_do.h"
\r
18 #include "move_gen.h"
\r
19 #include "move_legal.h"
\r
29 static const int StringSize = 4096;
\r
35 static int BestMove;
\r
36 static int BestValue;
\r
37 static move_t BestPV[LineSize];
\r
39 static sint64 NodeNb;
\r
40 static sint64 LeafNb;
\r
49 static bool depth_is_ok (int depth);
\r
50 static void perft (const board_t * board, int depth);
\r
56 static bool depth_is_ok(int depth) {
\r
58 return depth >= 0 && depth < DepthMax;
\r
63 void search(const board_t * board, int depth_max, double time_max) {
\r
67 ASSERT(board_is_ok(board));
\r
68 ASSERT(depth_max>=1&&depth_max<DepthMax);
\r
69 ASSERT(time_max>=0.0);
\r
75 BestMove = MoveNone;
\r
89 uci_send_ucinewgame(Uci);
\r
90 uci_send_isready_sync(Uci);
\r
94 if (!board_to_fen(board,string,256)) ASSERT(false);
\r
95 engine_send(Engine,"position fen %s",string);
\r
99 engine_send_queue(Engine,"go");
\r
101 engine_send_queue(Engine," movetime %.0f",time_max*1000.0);
\r
102 engine_send_queue(Engine," depth %d",depth_max);
\r
104 engine_send(Engine,""); // newline
\r
106 // wait for feed-back
\r
108 while (!engine_eof(Engine)) {
\r
110 engine_get(Engine,string,256);
\r
114 } else if (match(string,"bestmove * ponder *")) {
\r
116 BestMove = move_from_can(Star[0],board);
\r
117 ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));
\r
121 } else if (match(string,"bestmove *")) {
\r
123 BestMove = move_from_can(Star[0],board);
\r
124 ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));
\r
135 void do_perft(int argc,char * argv[]){
\r
136 const char * fen=NULL;
\r
140 for (i = 1; i < argc; i++) {
\r
142 } else if (my_string_equal(argv[i],"perft")) {
\r
144 } else if (my_string_equal(argv[i],"-fen")) {
\r
146 if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");
\r
147 my_string_set(&fen,argv[i]);
\r
148 } else if (my_string_equal(argv[i],"-max-depth")){
\r
150 if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");
\r
151 depth=atoi(argv[i]);
\r
152 if(depth<1) my_fatal("do_perft(): illegal depth %d\n",depth);
\r
154 my_fatal("do_perft(): unknown option \"%s\"\n",argv[i]);
\r
158 my_string_set(&fen,StartFen);
\r
160 board_from_fen(board,fen);
\r
161 search_perft(board,depth);
\r
166 void search_perft(const board_t * board, int depth_max) {
\r
169 my_timer_t timer[1];
\r
170 double time, speed;
\r
171 char node_string[StringSize];
\r
172 char leafnode_string[StringSize];
\r
174 ASSERT(board_is_ok(board));
\r
175 ASSERT(depth_max>=1&&depth_max<DepthMax);
\r
181 // iterative deepening
\r
183 for (depth = 1; depth <= depth_max; depth++) {
\r
190 my_timer_reset(timer);
\r
192 my_timer_start(timer);
\r
193 perft(board,depth);
\r
194 my_timer_stop(timer);
\r
196 time = my_timer_elapsed_real(timer);//my_timer_elapsed_cpu(timer);
\r
197 speed = (time < 0.01) ? 0.0 : double(NodeNb) / time;
\r
199 snprintf(node_string,StringSize,S64_FORMAT,NodeNb);
\r
200 snprintf(leafnode_string,StringSize,S64_FORMAT,LeafNb);
\r
202 printf("depth=%2d nodes=%12s leafnodes=%12s time=%7.2fs nps=%8.0f\n",depth,node_string,leafnode_string,time,speed);
\r
209 static void perft(const board_t * board, int depth) {
\r
214 board_t new_board[1];
\r
216 ASSERT(board_is_ok(board));
\r
217 ASSERT(depth_is_ok(depth));
\r
219 ASSERT(!is_in_check(board,colour_opp(board->turn)));
\r
238 gen_moves(list,board);
\r
240 for (i = 0; i < list_size(list); i++) {
\r
242 move = list_move(list,i);
\r
244 board_copy(new_board,board);
\r
245 move_do(new_board,move);
\r
247 if (!is_in_check(new_board,me)) perft(new_board,depth-1);
\r
251 // end of search.cpp
\r