version 1.4.63b
[polyglot.git] / search.c
index a67fbbc..075cc81 100644 (file)
--- a/search.c
+++ b/search.c
-// 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
-#define StringSize ((int)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
+