예제 #1
0
void search_update_root() {

   int move, move_pos, move_nb;
   double time;
   sint64 node_nb;
   char move_string[256];

   if (DispRoot) {

      search_update_current();

      if (SearchCurrent->time >= 1.0) {

         move = SearchRoot->move;
         move_pos = SearchRoot->move_pos;
         move_nb = SearchRoot->move_nb;

         time = SearchCurrent->time;
         node_nb = SearchCurrent->node_nb;

         move_to_string(move,move_string,256);

         send("info currmove %s currmovenumber %d",move_string,move_pos+1);
      }
   }
}
예제 #2
0
static void search_send_stat() {

	search_update_current();

	if (DispStat && SearchCurrent->time >= SearchInfo->last_time + 1.0) { // at least one-second gap
		SearchInfo->last_time = SearchCurrent->time;

		const double time = SearchCurrent->time, speed = SearchCurrent->speed, cpu = SearchCurrent->cpu;
		const S64 node_nb = SearchCurrent->node_nb;

		send("info time %.0f nodes " S64_FORMAT " nps %.0f cpuload %.0f", time * 1000.0, node_nb, speed, cpu * 1000.0);

		trans_stats(Trans);
	}
}
예제 #3
0
void search_update_root() {

	if (DispRoot) {

		search_update_current();

		if (SearchCurrent->time >= 1.0) {
			const U16 move = SearchRoot->move, move_pos = SearchRoot->move_pos;//, move_nb = SearchRoot->move_nb;
			//double time = SearchCurrent->time;
			//S64 node_nb = SearchCurrent->node_nb;
			char move_string[256];

			move_to_string(move, move_string, 256);

			send("info currmove %s currmovenumber %d", move_string, move_pos + 1);
		}
	}
}
예제 #4
0
static void parse_go(char string[]) {

   const char * ptr;
   bool infinite, ponder;
   int depth, mate, movestogo;
   sint64 nodes;
   double binc, btime, movetime, winc, wtime;
   double time, inc;
   double time_max, alloc;

   // init

   infinite = false;
   ponder = false;

   depth = -1;
   mate = -1;
   movestogo = -1;

   nodes = -1;

   binc = -1.0;
   btime = -1.0;
   movetime = -1.0;
   winc = -1.0;
   wtime = -1.0;

   // parse

   ptr = strtok(string," "); // skip "go"

   for (ptr = strtok(NULL," "); ptr != NULL; ptr = strtok(NULL," ")) {

      if (false) {

      } else if (string_equal(ptr,"binc")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         binc = double(atoi(ptr)) / 1000.0;
         ASSERT(binc>=0.0);

      } else if (string_equal(ptr,"btime")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         btime = double(atoi(ptr)) / 1000.0;
         ASSERT(btime>=0.0);

      } else if (string_equal(ptr,"depth")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         depth = atoi(ptr);
         ASSERT(depth>=0);

      } else if (string_equal(ptr,"infinite")) {

         infinite = true;

      } else if (string_equal(ptr,"mate")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         mate = atoi(ptr);
         ASSERT(mate>=0);

      } else if (string_equal(ptr,"movestogo")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         movestogo = atoi(ptr);
         ASSERT(movestogo>=0);

      } else if (string_equal(ptr,"movetime")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         movetime = double(atoi(ptr)) / 1000.0;
         ASSERT(movetime>=0.0);

      } else if (string_equal(ptr,"nodes")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         nodes = my_atoll(ptr);
         ASSERT(nodes>=0);

      } else if (string_equal(ptr,"ponder")) {

         ponder = true;

      } else if (string_equal(ptr,"searchmoves")) {

         // dummy

      } else if (string_equal(ptr,"winc")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         winc = double(atoi(ptr)) / 1000.0;
         ASSERT(winc>=0.0);

      } else if (string_equal(ptr,"wtime")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         wtime = double(atoi(ptr)) / 1000.0;
         ASSERT(wtime>=0.0);
      }
   }

   // init

   search_clear();

   // depth limit

   // JAS
   int option_depth = 0;
   option_depth = option_get_int("Search Depth");
   if (option_depth > 0) {
   	  depth = option_depth;
   }
   // JAS end

   if (depth >= 0) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = depth;
   } else if (mate >= 0) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = mate * 2 - 1; // HACK: move -> ply
   }

   // time limit

   if (COLOUR_IS_WHITE(SearchInput->board->turn)) {
      time = wtime;
      inc = winc;
   } else {
      time = btime;
      inc = binc;
   }

   if (movestogo <= 0 || movestogo > 30) movestogo = 20; // HACK was 30
   if (inc < 0.0) inc = 0.0;

   // JAS
   int option_movetime = 0;
   option_movetime = option_get_int("Search Time");
   if (option_movetime > 0) {
   	  movetime = option_movetime;
   }
   // JAS end

   if (movetime >= 0.0) {

      // fixed time

      SearchInput->time_is_limited = true;
      SearchInput->time_limit_1 = movetime * 5.0; // HACK to avoid early exit
      SearchInput->time_limit_2 = movetime;

   } else if (time >= 0.0) {

      // dynamic allocation

      time_max = time * 0.95 - 1.0;
      if (time_max < 0.0) time_max = 0.0;

      SearchInput->time_is_limited = true;

      alloc = (time_max + inc * double(movestogo-1)) / double(movestogo);
      alloc *= (option_get_bool("Ponder") ? PonderRatio : NormalRatio);
      if (alloc > time_max) alloc = time_max;
      SearchInput->time_limit_1 = alloc;

      alloc = (time_max + inc * double(movestogo-1)) * 0.5;
      if (alloc < SearchInput->time_limit_1) alloc = SearchInput->time_limit_1;
      if (alloc > time_max) alloc = time_max;
      SearchInput->time_limit_2 = alloc;
   }

   if (infinite || ponder) SearchInput->infinite = true;

   // search

   ASSERT(!Searching);
   ASSERT(!Delay);

   Searching = true;
   Infinite = infinite || ponder;
   Delay = false;

   search();
   search_update_current();

   ASSERT(Searching);
   ASSERT(!Delay);

   Searching = false;
   Delay = Infinite;

   if (!Delay) send_best_move();
}
예제 #5
0
void search_update_best() {

   int move, value, flags, depth, max_depth;
   const mv_t * pv;
   double time;
   sint64 node_nb;
   int mate, i, z;
   bool found;
   char move_string[256], pv_string[512];
      
   search_update_current();

   if (DispBest) {

      move = SearchBest[SearchCurrent->multipv].move;
      value = SearchBest[SearchCurrent->multipv].value;
      flags = SearchBest[SearchCurrent->multipv].flags;
      depth = SearchBest[SearchCurrent->multipv].depth;
      pv = SearchBest[SearchCurrent->multipv].pv;

      max_depth = SearchCurrent->max_depth;
      time = SearchCurrent->time;
      node_nb = SearchCurrent->node_nb;

      move_to_string(move,move_string,256);
      pv_to_string(pv,pv_string,512);

	  mate = value_to_mate(value);

	  if (SearchCurrent->multipv == 0){
		  save_multipv[SearchCurrent->multipv].mate = mate;
		  save_multipv[SearchCurrent->multipv].depth = depth;
		  save_multipv[SearchCurrent->multipv].max_depth = max_depth;
		  save_multipv[SearchCurrent->multipv].value = value;
		  save_multipv[SearchCurrent->multipv].time = time*1000.0;
		  save_multipv[SearchCurrent->multipv].node_nb = node_nb;
		  strcpy(save_multipv[SearchCurrent->multipv].pv_string,pv_string); 
	  }
	  else{
		  found = false;
		  for (i = 0; i < SearchCurrent->multipv; i++){
			  if (save_multipv[i].value < value){
				  found = true;
				  break;
			  }
		  }
		  if (found){

			  for (z = SearchCurrent->multipv; z > i; z--){
				  save_multipv[z].mate = save_multipv[z-1].mate;
				  save_multipv[z].depth = save_multipv[z-1].depth;
				  save_multipv[z].max_depth = save_multipv[z-1].max_depth;
				  save_multipv[z].value = save_multipv[z-1].value;
				  save_multipv[z].time = save_multipv[z-1].time;
				  save_multipv[z].node_nb = save_multipv[z-1].node_nb;
				  strcpy(save_multipv[z].pv_string,save_multipv[z-1].pv_string); 
			  }
			  
			  save_multipv[i].mate = mate;
		      save_multipv[i].depth = depth;
		      save_multipv[i].max_depth = max_depth;
		      save_multipv[i].value = value;
		      save_multipv[i].time = time*1000.0;
		      save_multipv[i].node_nb = node_nb;
		      strcpy(save_multipv[i].pv_string,pv_string); 
			  
		  }
		  else{
			  save_multipv[SearchCurrent->multipv].mate = mate;
			  save_multipv[SearchCurrent->multipv].depth = depth;
			  save_multipv[SearchCurrent->multipv].max_depth = max_depth;
			  save_multipv[SearchCurrent->multipv].value = value;
			  save_multipv[SearchCurrent->multipv].time = time*1000.0;
			  save_multipv[SearchCurrent->multipv].node_nb = node_nb;
			  strcpy(save_multipv[SearchCurrent->multipv].pv_string,pv_string); 
		  }
	  }
	  
      if (depth > 1 || (depth == 1 && SearchCurrent->multipv == SearchInput->multipv)){
		  for (i = 0; i <= SearchInput->multipv; i++){

			  if (save_multipv[i].mate == 0) {

				 // normal evaluation

			  if (false) {
				 } else if (flags == SearchExact) {
					send("info multipv %d depth %d seldepth %d score cp %d time %.0f nodes " S64_FORMAT " pv %s",i+1,save_multipv[i].depth,save_multipv[i].max_depth,save_multipv[i].value,save_multipv[i].time,save_multipv[i].node_nb,save_multipv[i].pv_string);
				 } else if (flags == SearchLower) {
					send("info multipv %d depth %d seldepth %d score cp %d lowerbound time %.0f nodes " S64_FORMAT " pv %s",i+1,save_multipv[i].depth,save_multipv[i].max_depth,save_multipv[i].value,save_multipv[i].time,save_multipv[i].node_nb,save_multipv[i].pv_string);
				 } else if (flags == SearchUpper) {
					send("info multipv %d depth %d seldepth %d score cp %d upperbound time %.0f nodes " S64_FORMAT " pv %s",i+1,save_multipv[i].depth,save_multipv[i].max_depth,save_multipv[i].value,save_multipv[i].time,save_multipv[i].node_nb,save_multipv[i].pv_string);
				 }

			  } else {

				 // mate announcement

				 if (false) {
				 } else if (flags == SearchExact) {
					send("info multipv %d depth %d seldepth %d score mate %d time %.0f nodes " S64_FORMAT " pv %s",i+1,save_multipv[i].depth,save_multipv[i].max_depth,save_multipv[i].mate,save_multipv[i].time,save_multipv[i].node_nb,save_multipv[i].pv_string);
				 } else if (flags == SearchLower) {
					send("info multipv %d depth %d seldepth %d score mate %d lowerbound time %.0f nodes " S64_FORMAT " pv %s",i+1,save_multipv[i].depth,save_multipv[i].max_depth,save_multipv[i].mate,save_multipv[i].time,save_multipv[i].node_nb,save_multipv[i].pv_string);
				 } else if (flags == SearchUpper) {
					send("info multipv %d depth %d seldepth %d score mate %d upperbound time %.0f nodes " S64_FORMAT " pv %s",i+1,save_multipv[i].depth,save_multipv[i].max_depth,save_multipv[i].mate,save_multipv[i].time,save_multipv[i].node_nb,save_multipv[i].pv_string);
				 }
			  }
		  }
	  }
   }

   // update time-management info

   if (SearchBest[SearchCurrent->multipv].depth > 1) {
      if (SearchBest[SearchCurrent->multipv].value <= SearchRoot->last_value - BadThreshold) {
         SearchRoot->bad_1 = true;
         SearchRoot->easy = false;
         SearchRoot->flag = false;
      } else {
         SearchRoot->bad_1 = false;
      }
   }
}
예제 #6
0
void search() {

   int move;
   int depth;
   int i;
   bool search_ready;

     
   for (i = 0; i < MultiPVMax; i++){
	  save_multipv[SearchCurrent->multipv].mate = 0;
	  save_multipv[SearchCurrent->multipv].depth = 0;
	  save_multipv[SearchCurrent->multipv].max_depth = 0;
	  save_multipv[SearchCurrent->multipv].value = 0;
	  save_multipv[SearchCurrent->multipv].time = 0;
	  save_multipv[SearchCurrent->multipv].node_nb = 0;
	  strcpy(save_multipv[SearchCurrent->multipv].pv_string,""); 
   }
  
   SearchInput->multipv = option_get_int("MultiPV")-1;
   SearchCurrent->multipv = 0;
   
   
   ASSERT(board_is_ok(SearchInput->board));

   // opening book

   if (option_get_bool("OwnBook") && !SearchInput->infinite) {

      move = book_move(SearchInput->board);

      if (move != MoveNone) {

         // play book move

         SearchBest[SearchCurrent->multipv].move = move;
         SearchBest[SearchCurrent->multipv].value = 1;
         SearchBest[SearchCurrent->multipv].flags = SearchExact;
         SearchBest[SearchCurrent->multipv].depth = 1;
         SearchBest[SearchCurrent->multipv].pv[0] = move;
         SearchBest[SearchCurrent->multipv].pv[1] = MoveNone;

         search_update_best();

         return;
      }
   }

   // SearchInput

   gen_legal_moves(SearchInput->list,SearchInput->board);

   if (LIST_SIZE(SearchInput->list) < SearchInput->multipv+1){ 
	  SearchInput->multipv = LIST_SIZE(SearchInput->list)-1;
   }

   if (LIST_SIZE(SearchInput->list) <= 1) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = 4; // was 1
   }

   // SearchInfo

   if (setjmp(SearchInfo->buf) != 0) {
      ASSERT(SearchInfo->can_stop);
      ASSERT(SearchBest->move!=MoveNone);
      search_update_current();
      return;
   }

   // SearchRoot

   list_copy(SearchRoot->list,SearchInput->list);

   // SearchCurrent

   board_copy(SearchCurrent->board,SearchInput->board);
   my_timer_reset(SearchCurrent->timer);
   my_timer_start(SearchCurrent->timer);

   // init

   trans_inc_date(Trans);

   sort_init();
   search_full_init(SearchRoot->list,SearchCurrent->board);

   // analyze game for evaluation
   
   if (SearchCurrent->board->piece_size[White] < 3 && SearchCurrent->board->piece_size[Black] < 3){
	   trans_endgame = true;
   }
   else{
	   trans_endgame = false;
   }

   
   // iterative deepening

   search_ready = false;

   for (depth = 1; depth < DepthMax; depth++) {
	   for (SearchCurrent->multipv = 0; SearchCurrent->multipv <= SearchInput->multipv; SearchCurrent->multipv++){

		  if (DispDepthStart && SearchCurrent->multipv == 0) send("info depth %d",depth);

		  SearchCurrent->max_extensions = depth * 10;
		  SearchRoot->bad_1 = false;
		  SearchRoot->change = false;

		  board_copy(SearchCurrent->board,SearchInput->board);

		  if (UseShortSearch && depth <= ShortSearchDepth) {
			 search_full_root(SearchRoot->list,SearchCurrent->board,depth,SearchShort);
		  } else {
			 search_full_root(SearchRoot->list,SearchCurrent->board,depth,SearchNormal);
		  }

		  search_update_current();

		  if (DispDepthEnd && SearchCurrent->multipv == SearchInput->multipv) {
			 send("info depth %d seldepth %d time %.0f nodes " S64_FORMAT " nps %.0f",depth,SearchCurrent->max_depth,SearchCurrent->time*1000.0,SearchCurrent->node_nb,SearchCurrent->speed);
		  }

		  // update search info

		  if (depth >= 1) SearchInfo->can_stop = true;

		  if (depth == 1
		   && LIST_SIZE(SearchRoot->list) >= 2
		   && LIST_VALUE(SearchRoot->list,0) >= LIST_VALUE(SearchRoot->list,1) + EasyThreshold) {
			 SearchRoot->easy = true;
		  }

		  if (depth > 1) {
			 SearchRoot->bad_2 = SearchRoot->bad_1;
			 SearchRoot->bad_1 = false;
			 ASSERT(SearchRoot->bad_2==(SearchBest->value<=SearchRoot->last_value-BadThreshold));
		  }

		  SearchRoot->last_value = SearchBest[SearchCurrent->multipv].value;

		  // stop search?

		  if (SearchInput->depth_is_limited && SearchCurrent->multipv >= SearchInput->multipv
		   && depth >= SearchInput->depth_limit) {
			 SearchRoot->flag = true;
		  }

		  if (SearchInput->time_is_limited
		   && SearchCurrent->time * 2 >= SearchInput->time_limit_1
		   && !SearchRoot->bad_2) {
			 SearchRoot->flag = true;
		  }

		  if (SearchInput->time_is_limited
		   && SearchCurrent->time >= SearchInput->time_limit_1 * EasyRatio
		   && SearchRoot->easy) {
			 ASSERT(!SearchRoot->bad_2);
			 ASSERT(!SearchRoot->change);
			 SearchRoot->flag = true;
		  }

		  if (SearchInput->time_is_limited
		   && SearchCurrent->time >= SearchInput->time_limit_1 * EarlyRatio
		   && !SearchRoot->bad_2
		   && !SearchRoot->change) {
			 SearchRoot->flag = true;
		  }

		  if (SearchInfo->can_stop 
		   && (SearchInfo->stop || (SearchRoot->flag && !SearchInput->infinite))) {
			  search_ready = true;
			  break;
		  }
	   }
	   if (search_ready)
		   break;
   }
}
예제 #7
0
static void parse_go(char string[]) {

   const char * ptr;
   bool infinite, ponder;
   int depth, mate, movestogo;
   sint64 nodes;
   double binc, btime, movetime, winc, wtime;
   double time, inc;

   // init

   infinite = false;
   ponder = false;

   depth = -1;
   mate = -1;
   movestogo = -1;

   nodes = -1;

   binc = -1.0;
   btime = -1.0;
   movetime = -1.0;
   winc = -1.0;
   wtime = -1.0;

   // parse

   ptr = strtok(string," "); // skip "go"

   for (ptr = strtok(NULL," "); ptr != NULL; ptr = strtok(NULL," ")) {

      if (false) {

      } else if (string_equal(ptr,"binc")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         binc = double(atoi(ptr)) / 1000.0;
         ASSERT(binc>=0.0);

      } else if (string_equal(ptr,"btime")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         btime = double(atoi(ptr)) / 1000.0;
         ASSERT(btime>=0.0);

      } else if (string_equal(ptr,"depth")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         depth = atoi(ptr);
         ASSERT(depth>=0);

      } else if (string_equal(ptr,"infinite")) {

         infinite = true;

      } else if (string_equal(ptr,"mate")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         mate = atoi(ptr);
         ASSERT(mate>=0);

      } else if (string_equal(ptr,"movestogo")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         movestogo = atoi(ptr);
         ASSERT(movestogo>=0);

      } else if (string_equal(ptr,"movetime")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         movetime = double(atoi(ptr)) / 1000.0;
         ASSERT(movetime>=0.0);

      } else if (string_equal(ptr,"nodes")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         nodes = my_atoll(ptr);
         ASSERT(nodes>=0);

      } else if (string_equal(ptr,"ponder")) {

         ponder = true;

      } else if (string_equal(ptr,"searchmoves")) {

         // dummy

      } else if (string_equal(ptr,"winc")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         winc = double(atoi(ptr)) / 1000.0;
         ASSERT(winc>=0.0);

      } else if (string_equal(ptr,"wtime")) {

         ptr = strtok(NULL," ");
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");

         wtime = double(atoi(ptr)) / 1000.0;
         ASSERT(wtime>=0.0);
      }
   }

   // init

   search_clear();
   tb_clear();
   egbb_clear();

   eval_init_options();

   // depth limit

   if (depth >= 0) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = depth;
   } else if (mate >= 0) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = mate * 2 - 1; // HACK: move -> ply
   }

   // nodes limit

   if (nodes > 0) {
      if (nodes < 1000) nodes = 1000;
      SearchInput->nodes_is_limited = true;
      SearchInput->nodes = nodes;
   }

   // time limit

   if (COLOUR_IS_WHITE(SearchInput->board->turn)) {
      time = wtime;
      inc = winc;
   } else {
      time = btime;
      inc = binc;
   }

   if (movestogo <= 0 || movestogo > 30) movestogo = 30; // HACK
   if (inc < 0.0) inc = 0.0;

   if (movetime >= 0.0) {

      // fixed time

      SearchInput->time_is_limited = true;
      SearchInput->time_limit_1 = movetime * 5.0; // HACK to avoid early exit
      SearchInput->time_limit_2 = movetime;

   } else if (time >= 0.0) {

      SearchInput->time_is_limited = true;
      time_allocation(time,inc,movestogo);
   }

   if (infinite || ponder) SearchInput->infinite = true;

   // search

   ASSERT(!Searching);
   ASSERT(!Delay);

   Searching = true;
   Infinite = infinite || ponder;
   Delay = false;

   search();
   search_update_current();

   ASSERT(Searching);
   ASSERT(!Delay);

   Searching = false;
   Delay = Infinite;

   if (!Delay) send_best_move();
}