示例#1
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;
   }
}
示例#2
0
static int full_root(list_t * list, board_t * board, int alpha, int beta, int depth, int height, int search_type) {

   int old_alpha;
   int value, best_value[MultiPVMax];
   int i, move, j;
   int new_depth;
   undo_t undo[1];
   mv_t new_pv[HeightMax];
   bool found;

   ASSERT(list_is_ok(list));
   ASSERT(board_is_ok(board));
   ASSERT(range_is_ok(alpha,beta));
   ASSERT(depth_is_ok(depth));
   ASSERT(height_is_ok(height));
   ASSERT(search_type==SearchNormal||search_type==SearchShort);

   ASSERT(list==SearchRoot->list);
   ASSERT(!LIST_IS_EMPTY(list));
   ASSERT(board==SearchCurrent->board);
   ASSERT(board_is_legal(board));
   ASSERT(depth>=1);

   // init

   SearchStack[height].best_move = MoveNone;
   SearchStack[height].move = MoveNone;
   SearchStack[height].threat_move = MoveNone;
   SearchStack[height].reduced = false;

   SearchCurrent->node_nb++;
   SearchInfo->check_nb--;

   if (SearchCurrent->multipv == 0)
	  for (i = 0; i < LIST_SIZE(list); i++) list->value[i] = ValueNone;

   old_alpha = alpha;
   best_value[SearchCurrent->multipv] = ValueNone;

   // move loop

   for (i = 0; i < LIST_SIZE(list); i++) {

      move = LIST_MOVE(list,i);

	  if (SearchCurrent->multipv > 0){
		  found = false;
		  for (j = 0; j < SearchCurrent->multipv; j++){
			  if (SearchBest[j].pv[0] == move){
				  found = true;
				  break;
			  }
		  }
		  if (found == true)
				continue;
	  }
	  SearchStack[height].move = move;

      SearchRoot->depth = depth;
      SearchRoot->move = move;
      SearchRoot->move_pos = i;
      SearchRoot->move_nb = LIST_SIZE(list);

      search_update_root();

      new_depth = full_new_depth(depth,move,board,board_is_check(board)&&LIST_SIZE(list)==1,false,true, height);

      move_do(board,move,undo);

      if (search_type == SearchShort || best_value[SearchCurrent->multipv] == ValueNone) { // first move
         value = -full_search(board,-beta,-alpha,new_depth,height+1,new_pv,NodePV);
		 if (value <= alpha){ // research
			 old_alpha = -ValueInf;
			 value = -full_search(board,-beta,ValueInf,new_depth,height+1,new_pv,NodePV);
		 }
		 else if (value >= beta){ // research
			 value = -full_search(board,-ValueInf,-alpha,new_depth,height+1,new_pv,NodePV);
		 }
			  
      } else { // other moves
         value = -full_search(board,-alpha-1,-alpha,new_depth,height+1,new_pv,NodeCut);
         if (value > alpha) { // && value < beta
            SearchRoot->change = true;
            SearchRoot->easy = false;
            SearchRoot->flag = false;
            search_update_root();
            value = -full_search(board,-beta,-alpha,new_depth,height+1,new_pv,NodePV);
         }
      }

      move_undo(board,move,undo);

      if (value <= alpha) { // upper bound
         list->value[i] = old_alpha;
      } else if (value >= beta) { // lower bound
         list->value[i] = beta;
      } else { // alpha < value < beta => exact value
         list->value[i] = value;
      }

      if (value > best_value[SearchCurrent->multipv] && (best_value[SearchCurrent->multipv] == ValueNone || value > alpha)) {

         SearchBest[SearchCurrent->multipv].move = move;
		 SearchStack[height].best_move = move;
         SearchBest[SearchCurrent->multipv].value = value;
         if (value <= alpha) { // upper bound
            SearchBest[SearchCurrent->multipv].flags = SearchUpper;
         } else if (value >= beta) { // lower bound
            SearchBest[SearchCurrent->multipv].flags = SearchLower;
         } else { // alpha < value < beta => exact value
            SearchBest[SearchCurrent->multipv].flags = SearchExact;
         }
         SearchBest[SearchCurrent->multipv].depth = depth;
         pv_cat(SearchBest[SearchCurrent->multipv].pv,new_pv,move);

         search_update_best();
      }

      if (value > best_value[SearchCurrent->multipv]) {
         best_value[SearchCurrent->multipv] = value;
         if (value > alpha) {
            if (search_type == SearchNormal) alpha = value;
            if (value >= beta) break;
         }
      }
   }

   ASSERT(value_is_ok(best_value));

   list_sort(list);

   ASSERT(SearchBest->move==LIST_MOVE(list,0));
   ASSERT(SearchBest->value==best_value);

   if (UseTrans && best_value[SearchCurrent->multipv] > old_alpha && best_value[SearchCurrent->multipv] < beta) {
      pv_fill(SearchBest[SearchCurrent->multipv].pv,board);
   }

   return best_value[SearchCurrent->multipv];
}