-// search.c\r
-\r
-// includes\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include "attack.h"\r
-#include "board.h"\r
-#include "colour.h"\r
-#include "engine.h"\r
-#include "fen.h"\r
-#include "line.h"\r
-#include "list.h"\r
-#include "move.h"\r
-#include "move_do.h"\r
-#include "move_gen.h"\r
-#include "move_legal.h"\r
-#include "option.h"\r
-#include "parse.h"\r
-#include "san.h"\r
-#include "search.h"\r
-#include "uci.h"\r
-#include "util.h"\r
-\r
-// constants\r
-\r
-static const int StringSize = 4096;\r
-\r
-// variables\r
-\r
-static int Depth;\r
-\r
-static int BestMove;\r
-static int BestValue;\r
-static move_t BestPV[LineSize];\r
-\r
-static sint64 NodeNb;\r
-static sint64 LeafNb;\r
-static double Time;\r
-\r
-static int Move;\r
-static int MovePos;\r
-static int MoveNb;\r
-\r
-// prototypes\r
-\r
-static bool depth_is_ok (int depth);\r
-static void perft (const board_t * board, int depth);\r
-\r
-// functions\r
-\r
-// depth_is_ok()\r
-\r
-static bool depth_is_ok(int depth) {\r
-\r
- return depth >= 0 && depth < DepthMax;\r
-}\r
-\r
-// search()\r
-\r
-void search(const board_t * board, int depth_max, double time_max) {\r
-\r
- char string[256];\r
-\r
- ASSERT(board_is_ok(board));\r
- ASSERT(depth_max>=1&&depth_max<DepthMax);\r
- ASSERT(time_max>=0.0);\r
-\r
- // engine\r
-\r
- Depth = 0;\r
-\r
- BestMove = MoveNone;\r
- BestValue = 0;\r
- line_clear(BestPV);\r
-\r
- NodeNb = 0;\r
- LeafNb = 0;\r
- Time = 0.0;\r
-\r
- Move = MoveNone;\r
- MovePos = 0;\r
- MoveNb = 0;\r
-\r
- // init\r
-\r
- uci_send_ucinewgame(Uci);\r
- uci_send_isready_sync(Uci);\r
-\r
- // position\r
-\r
- if (!board_to_fen(board,string,256)) ASSERT(FALSE);\r
- engine_send(Engine,"position fen %s",string);\r
-\r
- // search\r
-\r
- engine_send_queue(Engine,"go");\r
-\r
- engine_send_queue(Engine," movetime %.0f",time_max*1000.0);\r
- engine_send_queue(Engine," depth %d",depth_max);\r
-\r
- engine_send(Engine,""); // newline\r
-\r
- // wait for feed-back\r
-\r
- while (!engine_eof(Engine)) {\r
-\r
- engine_get(Engine,string);\r
-\r
- if (FALSE) {\r
-\r
- } else if (match(string,"bestmove * ponder *")) {\r
-\r
- BestMove = move_from_can(Star[0],board);\r
- ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));\r
-\r
- break;\r
-\r
- } else if (match(string,"bestmove *")) {\r
-\r
- BestMove = move_from_can(Star[0],board);\r
- ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));\r
-\r
- break;\r
- }\r
- }\r
-\r
- printf("\n");\r
-}\r
-\r
-// do_perft()\r
-\r
-void do_perft(int argc,char * argv[]){\r
- const char * fen=NULL;\r
- int depth=1;\r
- board_t board[1];\r
- int i;\r
- for (i = 1; i < argc; i++) {\r
- if (FALSE) {\r
- } else if (my_string_equal(argv[i],"perft")) {\r
- // skip\r
- } else if (my_string_equal(argv[i],"-fen")) {\r
- i++;\r
- if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");\r
- my_string_set(&fen,argv[i]);\r
- } else if (my_string_equal(argv[i],"-max-depth")){\r
- i++;\r
- if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");\r
- depth=atoi(argv[i]);\r
- if(depth<1) my_fatal("do_perft(): illegal depth %d\n",depth);\r
- } else {\r
- my_fatal("do_perft(): unknown option \"%s\"\n",argv[i]);\r
- }\r
- }\r
- if(fen==NULL){\r
- my_string_set(&fen,StartFen);\r
- }\r
- board_from_fen(board,fen);\r
- search_perft(board,depth);\r
-}\r
-\r
-// search_perft()\r
-\r
-void search_perft(const board_t * board, int depth_max) {\r
-\r
- int depth;\r
- my_timer_t timer[1];\r
- double time, speed;\r
- char node_string[StringSize];\r
- char leafnode_string[StringSize];\r
-\r
- ASSERT(board_is_ok(board));\r
- ASSERT(depth_max>=1&&depth_max<DepthMax);\r
-\r
- // init\r
-\r
- board_disp(board);\r
-\r
- // iterative deepening\r
-\r
- for (depth = 1; depth <= depth_max; depth++) {\r
-\r
- // init\r
-\r
- NodeNb = 0;\r
- LeafNb = 0;\r
-\r
- my_timer_reset(timer);\r
-\r
- my_timer_start(timer);\r
- perft(board,depth);\r
- my_timer_stop(timer);\r
-\r
- time = my_timer_elapsed_real(timer);//my_timer_elapsed_cpu(timer);\r
- speed = (time < 0.01) ? 0.0 : ((double)NodeNb) / time;\r
-\r
- snprintf(node_string,StringSize,S64_FORMAT,NodeNb);\r
- snprintf(leafnode_string,StringSize,S64_FORMAT,LeafNb);\r
-\r
- printf("depth=%2d nodes=%12s leafnodes=%12s time=%7.2fs nps=%8.0f\n",depth,node_string,leafnode_string,time,speed);\r
- }\r
-\r
-}\r
-\r
-// perft()\r
-\r
-static void perft(const board_t * board, int depth) {\r
-\r
- int me;\r
- list_t list[1];\r
- int i, move;\r
- board_t new_board[1];\r
-\r
- ASSERT(board_is_ok(board));\r
- ASSERT(depth_is_ok(depth));\r
-\r
- ASSERT(!is_in_check(board,colour_opp(board->turn)));\r
-\r
- // init\r
-\r
- NodeNb++;\r
-\r
- // leaf\r
-\r
- if (depth == 0) {\r
- LeafNb++;\r
- return;\r
- }\r
-\r
- // more init\r
-\r
- me = board->turn;\r
-\r
- // move loop\r
-\r
- gen_moves(list,board);\r
-\r
- for (i = 0; i < list_size(list); i++) {\r
-\r
- move = list_move(list,i);\r
-\r
- board_copy(new_board,board);\r
- move_do(new_board,move);\r
-\r
- if (!is_in_check(new_board,me)) perft(new_board,depth-1);\r
- }\r
-}\r
-\r
-// end of search.cpp\r
-\r
+// search.c
+
+// includes
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "attack.h"
+#include "board.h"
+#include "colour.h"
+#include "engine.h"
+#include "fen.h"
+#include "line.h"
+#include "list.h"
+#include "move.h"
+#include "move_do.h"
+#include "move_gen.h"
+#include "move_legal.h"
+#include "option.h"
+#include "parse.h"
+#include "san.h"
+#include "search.h"
+#include "uci.h"
+#include "util.h"
+
+// variables
+
+static int Depth;
+
+static int BestMove;
+static int BestValue;
+static move_t BestPV[LineSize];
+
+static sint64 NodeNb;
+static sint64 LeafNb;
+static double Time;
+
+static int Move;
+static int MovePos;
+static int MoveNb;
+
+// prototypes
+
+static bool depth_is_ok (int depth);
+static void perft (const board_t * board, int depth);
+
+// functions
+
+// depth_is_ok()
+
+static bool depth_is_ok(int depth) {
+
+ return depth >= 0 && depth < DepthMax;
+}
+
+// search()
+
+void search(const board_t * board, int depth_max, double time_max) {
+
+ char string[256];
+
+ ASSERT(board_is_ok(board));
+ ASSERT(depth_max>=1&&depth_max<DepthMax);
+ ASSERT(time_max>=0.0);
+
+ // engine
+
+ Depth = 0;
+
+ BestMove = MoveNone;
+ BestValue = 0;
+ line_clear(BestPV);
+
+ NodeNb = 0;
+ LeafNb = 0;
+ Time = 0.0;
+
+ Move = MoveNone;
+ MovePos = 0;
+ MoveNb = 0;
+
+ // init
+
+ uci_send_ucinewgame(Uci);
+ uci_send_isready_sync(Uci);
+
+ // position
+
+ if (!board_to_fen(board,string,256)) ASSERT(FALSE);
+ engine_send(Engine,"position fen %s",string);
+
+ // search
+
+ engine_send_queue(Engine,"go");
+
+ engine_send_queue(Engine," movetime %.0f",time_max*1000.0);
+ engine_send_queue(Engine," depth %d",depth_max);
+
+ engine_send(Engine,""); // newline
+
+ // wait for feed-back
+
+ while (!engine_eof(Engine)) {
+
+ engine_get(Engine,string);
+
+ if (FALSE) {
+
+ } else if (match(string,"bestmove * ponder *")) {
+
+ BestMove = move_from_can(Star[0],board);
+ ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));
+
+ break;
+
+ } else if (match(string,"bestmove *")) {
+
+ BestMove = move_from_can(Star[0],board);
+ ASSERT(BestMove!=MoveNone&&move_is_legal(BestMove,board));
+
+ break;
+ }
+ }
+
+ printf("\n");
+}
+
+// do_perft()
+
+void do_perft(int argc,char * argv[]){
+ const char * fen=NULL;
+ int depth=1;
+ board_t board[1];
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (FALSE) {
+ } else if (my_string_equal(argv[i],"perft")) {
+ // skip
+ } else if (my_string_equal(argv[i],"-fen")) {
+ i++;
+ if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");
+ my_string_set(&fen,argv[i]);
+ } else if (my_string_equal(argv[i],"-max-depth")){
+ i++;
+ if (argv[i] == NULL) my_fatal("do_perft(): missing argument\n");
+ depth=atoi(argv[i]);
+ if(depth<1) my_fatal("do_perft(): illegal depth %d\n",depth);
+ } else {
+ my_fatal("do_perft(): unknown option \"%s\"\n",argv[i]);
+ }
+ }
+ if(fen==NULL){
+ my_string_set(&fen,StartFen);
+ }
+ board_from_fen(board,fen);
+ search_perft(board,depth);
+}
+
+// search_perft()
+
+void search_perft(const board_t * board, int depth_max) {
+
+ int depth;
+ my_timer_t timer[1];
+ double time, speed;
+ char node_string[StringSize];
+ char leafnode_string[StringSize];
+
+ ASSERT(board_is_ok(board));
+ ASSERT(depth_max>=1&&depth_max<DepthMax);
+
+ // init
+
+ board_disp(board);
+
+ // iterative deepening
+
+ for (depth = 1; depth <= depth_max; depth++) {
+
+ // init
+
+ NodeNb = 0;
+ LeafNb = 0;
+
+ my_timer_reset(timer);
+
+ my_timer_start(timer);
+ perft(board,depth);
+ my_timer_stop(timer);
+
+ time = my_timer_elapsed_real(timer);//my_timer_elapsed_cpu(timer);
+ speed = (time < 0.01) ? 0.0 : ((double)NodeNb) / time;
+
+ snprintf(node_string,StringSize,S64_FORMAT,NodeNb);
+ snprintf(leafnode_string,StringSize,S64_FORMAT,LeafNb);
+
+ printf("depth=%2d nodes=%12s leafnodes=%12s time=%7.2fs nps=%8.0f\n",depth,node_string,leafnode_string,time,speed);
+ }
+
+}
+
+// perft()
+
+static void perft(const board_t * board, int depth) {
+
+ int me;
+ list_t list[1];
+ int i, move;
+ board_t new_board[1];
+
+ ASSERT(board_is_ok(board));
+ ASSERT(depth_is_ok(depth));
+
+ ASSERT(!is_in_check(board,colour_opp(board->turn)));
+
+ // init
+
+ NodeNb++;
+
+ // leaf
+
+ if (depth == 0) {
+ LeafNb++;
+ return;
+ }
+
+ // more init
+
+ me = board->turn;
+
+ // move loop
+
+ gen_moves(list,board);
+
+ for (i = 0; i < list_size(list); i++) {
+
+ move = list_move(list,i);
+
+ board_copy(new_board,board);
+ move_do(new_board,move);
+
+ if (!is_in_check(new_board,me)) perft(new_board,depth-1);
+ }
+}
+
+// end of search.cpp
+