Beispiel #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;
   }
}
static void search_update() {

   int move;
   int move_nb;
   board_t board[1];

   ASSERT(!Uci->searching);

   // launch a new search if needed

   if (State->state == THINK || State->state == PONDER || State->state == ANALYSE) {

      // opening book

      if (State->state == THINK && option_get_bool("Book")) {

         game_get_board(Game,Uci->board);

         move = book_move(Uci->board,option_get_bool("BookRandom"));

         if (move != MoveNone && move_is_legal(move,Uci->board)) {

            my_log("POLYGLOT *BOOK MOVE*\n");

            search_clear(); // clears Uci->ponder_move
            Uci->best_move = move;

            board_copy(board,Uci->board);
            move_do(board,move);
            Uci->ponder_move = book_move(board,false); // expected move = best book move

            Uci->best_pv[0] = Uci->best_move;
            Uci->best_pv[1] = Uci->ponder_move; // can be MoveNone
            Uci->best_pv[2] = MoveNone;

            comp_move(Uci->best_move);

            return;
         }
      }

      // engine search

      my_log("POLYGLOT START SEARCH\n");

      // options

      uci_send_option(Uci,"UCI_Chess960","%s",option_get_bool("Chess960")?"true":"false");

      if (option_get_int("UCIVersion") >= 2) {
         uci_send_option(Uci,"UCI_Opponent","none none %s %s",(XB->computer)?"computer":"human",XB->name);
         uci_send_option(Uci,"UCI_AnalyseMode","%s",(XB->analyse)?"true":"false");
      }

      uci_send_option(Uci,"Ponder","%s",ponder()?"true":"false");

      // position

      move = (State->state == PONDER) ? State->exp_move : MoveNone;
      send_board(move); // updates Uci->board global variable

      // search

      if (State->state == THINK || State->state == PONDER) {

         engine_send_queue(Engine,"go");

         if (XB->time_limit) {

            // fixed time per move

            engine_send_queue(Engine," movetime %.0f",XB->time_max*1000.0);

         } else {

            // time controls

            if (colour_is_white(Uci->board->turn)) {
               engine_send_queue(Engine," wtime %.0f btime %.0f",XB->my_time*1000.0,XB->opp_time*1000.0);
            } else {
               engine_send_queue(Engine," wtime %.0f btime %.0f",XB->opp_time*1000.0,XB->my_time*1000.0);
            }

            if (XB->inc != 0.0) engine_send_queue(Engine," winc %.0f binc %.0f",XB->inc*1000.0,XB->inc*1000.0);

            if (XB->mps != 0) {

               move_nb = XB->mps - (Uci->board->move_nb % XB->mps);
               ASSERT(move_nb>=1&&move_nb<=XB->mps);

               engine_send_queue(Engine," movestogo %d",move_nb);
            }
         }

         if (XB->depth_limit) engine_send_queue(Engine," depth %d",XB->depth_max);

         if (State->state == PONDER) engine_send_queue(Engine," ponder");

         engine_send(Engine,""); // newline

      } else if (State->state == ANALYSE) {

         engine_send(Engine,"go infinite");

      } else {

         ASSERT(false);
      }

      // init search info

      ASSERT(!Uci->searching);

      search_clear();

      Uci->searching = true;
      Uci->pending_nb++;
   }
}
Beispiel #3
0
void xboard2uci_gui_step(char string[]) {

	int move;
	char move_string[256];
	board_t board[1];

		if (FALSE) {
         
		} else if (match(string,"accepted *")) {

			// ignore

		} else if (match(string,"analyze")) {

			State->computer[White] = FALSE;
			State->computer[Black] = FALSE;

			XB->analyse = TRUE;
			XB->new_hack = FALSE;
			ASSERT(!XB->result);
			XB->result = FALSE;

			mess();

		} else if (match(string,"bk")) {

			if (option_get_bool(Option,"Book")) {
				game_get_board(Game,board);
				book_disp(board);
			}

		} else if (match(string,"black")) {

			if (colour_is_black(game_turn(Game))) {

				State->computer[White] = TRUE;
				State->computer[Black] = FALSE;

				XB->new_hack = TRUE;
				XB->result = FALSE;

				mess();
			}

		} else if (match(string,"computer")) {

			XB->computer = TRUE;

		} else if (match(string,"draw")) {
			if(option_find(Uci->option,"UCI_DrawOffers")){
			    my_log("POLYGLOT draw from XB received");
				uci_send_option(Uci,"DrawOffer","%s","draw");}
		} else if (match(string,"easy")) {

			XB->ponder = FALSE;

			mess();

		} else if (match(string,"edit")) {

			// refuse

			gui_send(GUI,"Error (unknown command): %s",string);

		} else if (match(string,"exit")) {

			State->computer[White] = FALSE;
			State->computer[Black] = FALSE;

			XB->analyse = FALSE;

			mess();

		} else if (match(string,"force")) {

			State->computer[White] = FALSE;
			State->computer[Black] = FALSE;

			mess();

		} else if (match(string,"go")) {

			State->computer[game_turn(Game)] = TRUE;
			State->computer[colour_opp(game_turn(Game))] = FALSE;

			XB->new_hack = FALSE;
			ASSERT(!XB->result);
			XB->result = FALSE;

			mess();

		} else if (match(string,"hard")) {

			XB->ponder = TRUE;

			mess();

		} else if (match(string,"hint")) {
		    
		        move=MoveNone;
			game_get_board(Game,board);
			if (option_get_bool(Option,"Book")) {

				move = book_move(board,FALSE);
			}
			if(move==MoveNone && State->hint_move!=MoveNone){
			    move=State->hint_move;
			    
			}
			if (move != MoveNone && move_is_legal(move,board)) {
			    move_to_san(move,board,move_string,256);
			    gui_send(GUI,"Hint: %s",move_string);
			}

		} else if (match(string,"ics *")) {

			XB->ics = TRUE;

		} else if (match(string,"level * *:* *")) {

			XB->mps  = atoi(Star[0]);
			XB->base = ((double)atoi(Star[1])) * 60.0 + ((double)atoi(Star[2]));
			XB->inc  = ((double)atoi(Star[3]));

		} else if (match(string,"level * * *")) {

			XB->mps  = atoi(Star[0]);
			XB->base = ((double)atoi(Star[1])) * 60.0;
			XB->inc  = ((double)atoi(Star[2]));

		} else if (match(string,"name *")) {

			my_string_set(&XB->name,Star[0]);

		} else if (match(string,"new")) {

		    uci_send_isready_sync(Uci);
			my_log("POLYGLOT NEW GAME\n");

			option_set(Option,"3Check","false");
			option_set(Option,"Chess960","false");
			option_set(Option,"Atomic","false");
			option_set(Option,"Horde","false");

			game_clear(Game);

			if (XB->analyse) {
				State->computer[White] = FALSE;
				State->computer[Black] = FALSE;
			} else {
				State->computer[White] = FALSE;
				State->computer[Black] = TRUE;
			}

			XB->new_hack = TRUE;
			XB->result = FALSE;

			XB->depth_limit = FALSE;
            XB->node_rate=-1;

			XB->computer = FALSE;
			my_string_set(&XB->name,"<empty>");

			board_update();
			mess();

			uci_send_ucinewgame(Uci);

		} else if (match(string,"nopost")) {

			XB->post = FALSE;

		} else if (match(string,"otim *")) {

			XB->opp_time = ((double)atoi(Star[0])) / 100.0;
			if (XB->opp_time < 0.0) XB->opp_time = 0.0;

		} else if (match(string,"pause")) {

			// refuse

			gui_send(GUI,"Error (unknown command): %s",string);

		} else if (match(string,"ping *")) {

			// HACK; TODO: answer only after an engine move

			if (DelayPong) {
				if (XB->ping >= 0) gui_send(GUI,"pong %d",XB->ping); // HACK: get rid of old ping
				XB->ping = atoi(Star[0]);
				uci_send_isready_sync(Uci);
			} else {
				ASSERT(XB->ping==-1);
				gui_send(GUI,"pong %s",Star[0]);
			}
        } else if (match(string,"nps *")) {
            
                // fake WB play-by-nodes mode
            XB->node_rate = atoi(Star[0]);
		} else if (match(string,"playother")) {

			State->computer[game_turn(Game)] = FALSE;
			State->computer[colour_opp(game_turn(Game))] = TRUE;

			XB->new_hack = FALSE;
			ASSERT(!XB->result);
			XB->result = FALSE;

			mess();

		} else if (match(string,"post")) {

			XB->post = TRUE;

		} else if (match(string,"protover *")) {
            XB->proto_ver = atoi(Star[0]);
            ASSERT(XB->proto_ver>=2);
            send_xboard_options();

		} else if (match(string,"quit")) {
			my_log("POLYGLOT *** \"quit\" from GUI ***\n");
			quit();
		} else if (match(string,"random")) {

			// ignore

		} else if (match(string,"rating * *")) {

			// ignore

		} else if (match(string,"remove")) {

			if (game_pos(Game) >= 2) {

				game_goto(Game,game_pos(Game)-2);

				ASSERT(!XB->new_hack);
				XB->new_hack = FALSE; // HACK?
				XB->result = FALSE;

				board_update();
				mess();
			}

		} else if (match(string,"rejected *")) {

			// ignore

		} else if (match(string,"reset")) { // protover 3?

			// refuse

			gui_send(GUI,"Error (unknown command): %s",string);

		} else if (FALSE
			|| match(string,"result * {*}")
			|| match(string,"result * {* }")
			|| match(string,"result * { *}")
			|| match(string,"result * { * }")) {

				my_log("POLYGLOT GAME END\n");

				XB->result = TRUE;

				mess();

				// book learning

				if (FALSE && option_get_bool(Option,"Book") &&
                    option_get_bool(Option,"BookLearn")) {

					if (FALSE) {
					} else if (my_string_equal(Star[0],"1-0")) {
						learn(+1);
					} else if (my_string_equal(Star[0],"0-1")) {
						learn(-1);
					} else if (my_string_equal(Star[0],"1/2-1/2")) {
						learn(0);
					}
				}
		} else if (match(string,"resume")) {

			// refuse

			gui_send(GUI,"Error (unknown command): %s",string);

        } else if (match(string,"option *=*")   ||
                   match(string,"option * =*") ||
                   match(string,"option *= *") ||
                   match(string,"option * = *")
                   ){
            char *name=Star[0];
            char *value=Star[1];
            if(match(name, "Polyglot *")){
                char *pg_name=Star[0];
                polyglot_set_option(pg_name,value);
            }else{
                option_t *opt=option_find(Uci->option,name);
                if(opt){
                    if(my_string_case_equal(opt->type,"check")){
                       value=my_string_equal(value,"1")?"true":"false";
                    }
                    start_protected_command();
                    uci_send_option(Uci, name, "%s", value);
                    end_protected_command();
                }else{
                    gui_send(GUI,"Error (unknown option): %s",name); 
                }
            }
        } else if (match(string,"option *")){
            char *name=Star[0];
             if(match(name, "Polyglot *")){
                char *pg_name=Star[0];
                polyglot_set_option(pg_name,"<empty>");
	     }else{           
	       start_protected_command();
                // value is ignored
	       if(!uci_send_option(Uci, name, "%s", "<empty>")){
		 gui_send(GUI,"Error (unknown option): %s",name); 
	       }; 
	       end_protected_command();
	     }
        } else if (XB->has_feature_smp && match(string,"cores *")){
                int cores=atoi(Star[0]);
                if(cores>=1){
                    // updating the number of cores
                    my_log("POLYGLOT setting the number of cores to %d\n",cores);
                    start_protected_command();
                    uci_set_threads(Uci,cores); 
                    end_protected_command();
                } else{
                   // refuse
                    gui_send(GUI,"Error (unknown command): %s",string);
                }
        } else if (match(string,"egtpath * *")){
                char *type=Star[0];
                char *path=Star[1];
                if(my_string_empty(path)){
                    // refuse
                    gui_send(GUI,"Error (unknown command): %s",string);
                }else{
		    if(my_string_case_equal(type,"nalimov") && XB->has_feature_egt_nalimov){
			// updating NalimovPath
			my_log("POLYGLOT setting the Nalimov path to %s\n",path);
			start_protected_command();
			uci_send_option(Uci,"NalimovPath","%s",path);
			end_protected_command();
		    }else if(my_string_case_equal(type,"gaviota") && XB->has_feature_egt_gaviota){
			// updating GaviotaPath
			my_log("POLYGLOT setting the Gaviota path to %s\n",path);
			start_protected_command();
			uci_send_option(Uci,"GaviotaTbPath","%s",path);
			end_protected_command();
		    }else{
			// refuse
			gui_send(GUI,"Error (unsupported table base format): %s",string);
		    }
                }
        } else if (XB->has_feature_memory && match(string,"memory *")){
            int memory = atoi(Star[0]);
            int egt_cache;
            int real_memory;
            if(memory>=1){
                // updating the available memory
                option_t *opt;
                my_log("POLYGLOT setting the amount of memory to %dMb\n",memory);
                if(XB->has_feature_egt_nalimov && (opt=option_find(Uci->option,"NalimovCache"))){
                    egt_cache=atoi(opt->value);
                }else if(XB->has_feature_egt_gaviota && 
			 (opt=option_find(Uci->option,"GaviotaTbCache"))){
		    egt_cache=atoi(opt->value);
		}else{
                    egt_cache=0;
                }
                my_log("POLYGLOT EGTB Cache is %dMb\n",egt_cache);
                real_memory=memory-egt_cache;
                if(real_memory>0){
                    start_protected_command();
                    uci_send_option(Uci,"Hash", "%d", real_memory);
                    end_protected_command();
                }
            }else{
                // refuse
                gui_send(GUI,"Error (unknown command): %s",string);
            }

		} else if (match(string,"sd *")) {

			XB->depth_limit = TRUE;
			XB->depth_max = atoi(Star[0]);

		} else if (match(string,"setboard *")) {

			my_log("POLYGLOT FEN %s\n",Star[0]);

			if (!game_init(Game,Star[0])) my_fatal("xboard_step(): bad FEN \"%s\"\n",Star[0]);

			State->computer[White] = FALSE;
			State->computer[Black] = FALSE;

			XB->new_hack = TRUE; // HACK?
			XB->result = FALSE;

			board_update();
			mess();

		} else if (match(string,"st *")) {

			XB->time_limit = TRUE;
			XB->time_max = ((double)atoi(Star[0]));

		} else if (match(string,"time *")) {

			XB->my_time = ((double)atoi(Star[0])) / 100.0;
			if (XB->my_time < 0.0) XB->my_time = 0.0;

		} else if (match(string,"undo")) {

			if (game_pos(Game) >= 1) {

				game_goto(Game,game_pos(Game)-1);

				ASSERT(!XB->new_hack);
				XB->new_hack = FALSE; // HACK?
				XB->result = FALSE;

				board_update();
				mess();
			}

		} else if (match(string,"usermove *")) {

			game_get_board(Game,board);
			move = move_from_san(Star[0],board);

			if (move != MoveNone && move_is_legal(move,board)) {

				XB->new_hack = FALSE;
				ASSERT(!XB->result);
				XB->result = FALSE;

				move_step(move);
				no_mess(move);

			} else {

				gui_send(GUI,"Illegal move: %s",Star[0]);
			}

		} else if (match(string,"variant *")) {

			if (my_string_equal(Star[0],"3check")) {
				option_set(Option,"3Check","true");
			} else {
				option_set(Option,"3Check","false");
			}
			if (my_string_equal(Star[0],"fischerandom")) {
				option_set(Option,"Chess960","true");
			} else {
				option_set(Option,"Chess960","false");
			}
			if (my_string_equal(Star[0],"atomic")) {
				option_set(Option,"Atomic","true");
			} else {
				option_set(Option,"Atomic","false");
			}
			if (my_string_equal(Star[0],"horde")) {
				option_set(Option,"Horde","true");
				game_init(Game,StartFenHorde);
				//gui_send(GUI,"setup %s",StartFenHorde);
			} else {
				option_set(Option,"Horde","false");
			}

		} else if (match(string,"white")) {

			if (colour_is_white(game_turn(Game))) {

				State->computer[White] = FALSE;
				State->computer[Black] = TRUE;

				XB->new_hack = TRUE;
				XB->result = FALSE;

				mess();
			}

		} else if (match(string,"xboard")) {

			// ignore

		} else if (match(string,".")) { // analyse info

			if (State->state == ANALYSE) {
				int depth=Uci->best_depth;//HACK: don't clear engine-output window...

				ASSERT(Uci->searching);
				ASSERT(Uci->pending_nb>=1);

				if (Uci->root_move != MoveNone && move_is_legal(Uci->root_move,Uci->board)) {
					move_to_san(Uci->root_move,Uci->board,move_string,256);
					gui_send(GUI,"stat01: %.0f "S64_FORMAT" %d %d %d %s",Uci->time*100.0,Uci->node_nb,/*Uci->*/depth,Uci->root_move_nb-(Uci->root_move_pos+1),Uci->root_move_nb,move_string);
				} else {
					gui_send(GUI,"stat01: %.0f "S64_FORMAT" %d %d %d",Uci->time*100.0,Uci->node_nb,/*Uci->*/depth,0,0); // HACK
				}
			}

		} else if (match(string,"?")) { // move now

			if (State->state == THINK) {

				ASSERT(Uci->searching);
				ASSERT(Uci->pending_nb>=1);

				// HACK: just send "stop" to the engine

				if (Uci->searching) {
					my_log("POLYGLOT STOP SEARCH\n");
					engine_send(Engine,"stop");
				}
			}

		} else { // unknown command, maybe a move?

			game_get_board(Game,board);
			move = move_from_san(string,board);

			if (move != MoveNone && move_is_legal(move,board)) {

				XB->new_hack = FALSE;
				ASSERT(!XB->result);
				XB->result = FALSE;

				move_step(move);
				no_mess(move);

			} else if (move != MoveNone) {

				gui_send(GUI,"Illegal move: %s",string);

			} else {

				gui_send(GUI,"Error (unknown command): %s",string);
			}
		}
	return;
}
static void xboard_step() {

   char string[StringSize];
   int move;
   char move_string[256];
   board_t board[1];

   xboard_get(XBoard,string,StringSize);

   if (false) {

   } else if (match(string,"accepted *")) {

      // ignore

   } else if (match(string,"analyze")) {

      State->computer[White] = false;
      State->computer[Black] = false;

      XB->analyse = true;
      XB->new_hack = false;
      ASSERT(!XB->result);
      XB->result = false;

      mess();

   } else if (match(string,"bk")) {

      if (option_get_bool("Book")) {
         game_get_board(Game,board);
         book_disp(board);
      }

   } else if (match(string,"black")) {

      if (colour_is_black(game_turn(Game))) {

         State->computer[White] = true;
         State->computer[Black] = false;

         XB->new_hack = true;
         XB->result = false;

         mess();
      }

   } else if (match(string,"computer")) {

      XB->computer = true;

   } else if (match(string,"draw")) {

      // ignore

   } else if (match(string,"easy")) {

      XB->ponder = false;

      mess();

   } else if (match(string,"edit")) {

      // refuse

      xboard_send(XBoard,"Error (unknown command): %s",string);

   } else if (match(string,"exit")) {

      State->computer[White] = false;
      State->computer[Black] = false;

      XB->analyse = false;

      mess();

   } else if (match(string,"force")) {

      State->computer[White] = false;
      State->computer[Black] = false;

      mess();

   } else if (match(string,"go")) {

      State->computer[game_turn(Game)] = true;
      State->computer[colour_opp(game_turn(Game))] = false;

      XB->new_hack = false;
      ASSERT(!XB->result);
      XB->result = false;

      mess();

   } else if (match(string,"hard")) {

      XB->ponder = true;

      mess();

   } else if (match(string,"hint")) {

      if (option_get_bool("Book")) {

         game_get_board(Game,board);
         move = book_move(board,false);

         if (move != MoveNone && move_is_legal(move,board)) {
            move_to_san(move,board,move_string,256);
            xboard_send(XBoard,"Hint: %s",move_string);
         }
      }

   } else if (match(string,"ics *")) {

      XB->ics = true;

   } else if (match(string,"level * *:* *")) {

      XB->mps  = atoi(Star[0]);
      XB->base = double(atoi(Star[1])) * 60.0 + double(atoi(Star[2]));
      XB->inc  = double(atoi(Star[3]));

   } else if (match(string,"level * * *")) {

      XB->mps  = atoi(Star[0]);
      XB->base = double(atoi(Star[1])) * 60.0;
      XB->inc  = double(atoi(Star[2]));

   } else if (match(string,"name *")) {

      my_string_set(&XB->name,Star[0]);

   } else if (match(string,"new")) {

      my_log("POLYGLOT NEW GAME\n");

      option_set("Chess960","false");

      game_clear(Game);

      if (XB->analyse) {
         State->computer[White] = false;
         State->computer[Black] = false;
      } else {
         State->computer[White] = false;
         State->computer[Black] = true;
      }

      XB->new_hack = true;
      XB->result = false;

      XB->depth_limit = false;

      XB->computer = false;
      my_string_set(&XB->name,"<empty>");

      board_update();
      mess();

      uci_send_ucinewgame(Uci);

   } else if (match(string,"nopost")) {

      XB->post = false;

   } else if (match(string,"otim *")) {

      XB->opp_time = double(atoi(Star[0])) / 100.0;
      if (XB->opp_time < 0.0) XB->opp_time = 0.0;

   } else if (match(string,"pause")) {

      // refuse

      xboard_send(XBoard,"Error (unknown command): %s",string);

   } else if (match(string,"ping *")) {

      // HACK; TODO: answer only after an engine move

      if (DelayPong) {
         if (XB->ping >= 0) xboard_send(XBoard,"pong %d",XB->ping); // HACK: get rid of old ping
         XB->ping = atoi(Star[0]);
         uci_send_isready(Uci);
      } else {
         ASSERT(XB->ping==-1);
         xboard_send(XBoard,"pong %s",Star[0]);
      }

   } else if (match(string,"playother")) {

      State->computer[game_turn(Game)] = false;
      State->computer[colour_opp(game_turn(Game))] = true;

      XB->new_hack = false;
      ASSERT(!XB->result);
      XB->result = false;

      mess();

   } else if (match(string,"post")) {

      XB->post = true;

   } else if (match(string,"protover *")) {

      XB->proto_ver = atoi(Star[0]);
      ASSERT(XB->proto_ver>=2);

      xboard_send(XBoard,"feature done=0");

      xboard_send(XBoard,"feature analyze=1");
      xboard_send(XBoard,"feature colors=0");
      xboard_send(XBoard,"feature draw=1");
      xboard_send(XBoard,"feature ics=1");
      xboard_send(XBoard,"feature myname=\"%s\"",option_get_string("EngineName"));
      xboard_send(XBoard,"feature name=1");
      xboard_send(XBoard,"feature pause=0");
      xboard_send(XBoard,"feature ping=1");
      xboard_send(XBoard,"feature playother=1");
      xboard_send(XBoard,"feature reuse=1");
      xboard_send(XBoard,"feature san=0");
      xboard_send(XBoard,"feature setboard=1");
      xboard_send(XBoard,"feature sigint=0");
      xboard_send(XBoard,"feature sigterm=0");
      xboard_send(XBoard,"feature time=1");
      xboard_send(XBoard,"feature usermove=1");

      if (uci_option_exist(Uci,"UCI_Chess960")) {
         xboard_send(XBoard,"feature variants=\"normal,fischerandom\"");
      } else {
         xboard_send(XBoard,"feature variants=\"normal\"");
      }

      if (Uci->ready) xboard_send(XBoard,"feature done=1");

      // otherwise "feature done=1" will be sent when the engine is ready

   } else if (match(string,"quit")) {

      my_log("POLYGLOT *** \"quit\" from XBoard ***\n");
      quit();

   } else if (match(string,"random")) {

      // ignore

   } else if (match(string,"rating * *")) {

      // ignore

   } else if (match(string,"remove")) {

      if (game_pos(Game) >= 2) {

         game_goto(Game,game_pos(Game)-2);

         ASSERT(!XB->new_hack);
         XB->new_hack = false; // HACK?
         XB->result = false;

         board_update();
         mess();
      }

   } else if (match(string,"rejected *")) {

      // ignore

   } else if (match(string,"reset")) { // protover 3?

      // refuse

      xboard_send(XBoard,"Error (unknown command): %s",string);

   } else if (false
           || match(string,"result * {*}")
           || match(string,"result * {* }")
           || match(string,"result * { *}")
           || match(string,"result * { * }")) {

      my_log("POLYGLOT GAME END\n");

      XB->result = true;

      mess();

      // book learning

      if (option_get_bool("Book") && option_get_bool("BookLearn")) {

         if (false) {
         } else if (my_string_equal(Star[0],"1-0")) {
            learn(+1);
         } else if (my_string_equal(Star[0],"0-1")) {
            learn(-1);
         } else if (my_string_equal(Star[0],"1/2-1/2")) {
            learn(0);
         }
      }

   } else if (match(string,"resume")) {

      // refuse

      xboard_send(XBoard,"Error (unknown command): %s",string);

   } else if (match(string,"sd *")) {

      XB->depth_limit = true;
      XB->depth_max = atoi(Star[0]);

   } else if (match(string,"setboard *")) {

      my_log("POLYGLOT FEN %s\n",Star[0]);

      if (!game_init(Game,Star[0])) my_fatal("xboard_step(): bad FEN \"%s\"\n",Star[0]);

      State->computer[White] = false;
      State->computer[Black] = false;

      XB->new_hack = true; // HACK?
      XB->result = false;

      board_update();
      mess();

   } else if (match(string,"st *")) {

      XB->time_limit = true;
      XB->time_max = double(atoi(Star[0]));

   } else if (match(string,"time *")) {

      XB->my_time = double(atoi(Star[0])) / 100.0;
      if (XB->my_time < 0.0) XB->my_time = 0.0;

   } else if (match(string,"undo")) {

      if (game_pos(Game) >= 1) {

         game_goto(Game,game_pos(Game)-1);

         ASSERT(!XB->new_hack);
         XB->new_hack = false; // HACK?
         XB->result = false;

         board_update();
         mess();
      }

   } else if (match(string,"usermove *")) {

      game_get_board(Game,board);
      move = move_from_san(Star[0],board);

      if (move != MoveNone && move_is_legal(move,board)) {

         XB->new_hack = false;
         ASSERT(!XB->result);
         XB->result = false;

         move_step(move);
         no_mess(move);

      } else {

         xboard_send(XBoard,"Illegal move: %s",Star[0]);
      }

   } else if (match(string,"variant *")) {

      if (my_string_equal(Star[0],"fischerandom")) {
         option_set("Chess960","true");
      } else {
         option_set("Chess960","false");
      }

   } else if (match(string,"white")) {

      if (colour_is_white(game_turn(Game))) {

         State->computer[White] = false;
         State->computer[Black] = true;

         XB->new_hack = true;
         XB->result = false;

         mess();
      }

   } else if (match(string,"xboard")) {

      // ignore

   } else if (match(string,".")) { // analyse info

      if (State->state == ANALYSE) {

         ASSERT(Uci->searching);
         ASSERT(Uci->pending_nb>=1);

         if (Uci->root_move != MoveNone && move_is_legal(Uci->root_move,Uci->board)) {
            move_to_san(Uci->root_move,Uci->board,move_string,256);
            xboard_send(XBoard,"stat01: %.0f %lld %d %d %d %s",Uci->time*100.0,Uci->node_nb,Uci->depth,Uci->root_move_nb-(Uci->root_move_pos+1),Uci->root_move_nb,move_string);
         } else {
            xboard_send(XBoard,"stat01: %.0f %lld %d %d %d",Uci->time*100.0,Uci->node_nb,Uci->depth,0,0); // HACK
         }
      }

   } else if (match(string,"?")) { // move now

      if (State->state == THINK) {

         ASSERT(Uci->searching);
         ASSERT(Uci->pending_nb>=1);

         // HACK: just send "stop" to the engine

         if (Uci->searching) {
            my_log("POLYGLOT STOP SEARCH\n");
            engine_send(Engine,"stop");
         }
      }

   } else { // unknown command, maybe a move?

      game_get_board(Game,board);
      move = move_from_san(string,board);

      if (move != MoveNone && move_is_legal(move,board)) {

         XB->new_hack = false;
         ASSERT(!XB->result);
         XB->result = false;

         move_step(move);
         no_mess(move);

      } else if (move != MoveNone) {

         xboard_send(XBoard,"Illegal move: %s",string);

      } else {

         xboard_send(XBoard,"Error (unknown command): %s",string);
      }
   }
}
Beispiel #5
0
static void search_update() {

   int move;
   int move_nb;
   board_t board[1];

   ASSERT(!Uci->searching);



   
   // launch a new search if needed

   

   if (State->state == THINK || State->state == PONDER || State->state == ANALYSE) {

      // [VdB] moved up as we need the move number

       game_get_board(Game,Uci->board);

      // opening book

       if (State->state == THINK &&
           option_get_bool(Option,"Book") &&
           Uci->board->move_nb<option_get_int(Option,"BookDepth")
           ) {


         move = book_move(Uci->board,option_get_bool(Option,"BookRandom"));

         if (move != MoveNone && move_is_legal(move,Uci->board)) {

            my_log("POLYGLOT *BOOK MOVE*\n");

            search_clear(); // clears Uci->ponder_move
            Uci->best_move = move;

            board_copy(board,Uci->board);
            move_do(board,move);
            Uci->ponder_move = book_move(board,FALSE); // expected move = best book move

            Uci->best_pv[0] = Uci->best_move;
            Uci->best_pv[1] = Uci->ponder_move; // can be MoveNone
            Uci->best_pv[2] = MoveNone;

            comp_move(Uci->best_move);

            return;
         }
      }

      // engine search

      my_log("POLYGLOT START SEARCH\n");

      // options

      uci_send_option(Uci,"UCI_3Check","%s",
                      option_get_bool(Option,"3Check")?"true":"false");
      uci_send_option(Uci,"UCI_Chess960","%s",
                      option_get_bool(Option,"Chess960")?"true":"false");
      uci_send_option(Uci,"UCI_Atomic","%s",
                      option_get_bool(Option,"Atomic")?"true":"false");
      uci_send_option(Uci,"UCI_Horde","%s",
                      option_get_bool(Option,"Horde")?"true":"false");

      if (option_get_int(Option,"UCIVersion") >= 2) {
         uci_send_option(Uci,"UCI_Opponent","none none %s %s",(XB->computer)?"computer":"human",XB->name);
         uci_send_option(Uci,"UCI_AnalyseMode","%s",(XB->analyse)?"true":"false");
      }

      uci_send_option(Uci,"Ponder","%s",ponder()?"true":"false");

      // position

      move = (State->state == PONDER) ? State->exp_move : MoveNone;
      send_board(move); // updates Uci->board global variable

      // search

      if (State->state == THINK || State->state == PONDER) {

         engine_send_queue(Engine,"go");

         if (XB->time_limit) {

            // fixed time per move
             
             if(XB->node_rate > 0){
                 engine_send_queue(Engine,
                                   " nodes %.0f",
                                   XB->time_max*((double)XB->node_rate));
             }else{
		 double computed_time;
		 double st_fudge;
		 st_fudge=(double) option_get_int(Option,"STFudge");
		 my_log("POLYGLOT Giving engine %.0fmsec extra time.\n",st_fudge);
		 computed_time=XB->time_max*1000.0-st_fudge;
		 if(computed_time< 1.0){
		     computed_time=1.0;
		 }
                 engine_send_queue(Engine,
                                   " movetime %.0f",
                                   computed_time);
             }

         } else {

            // time controls

                 if(XB->node_rate > 0) {
                     double time;
                     move_nb = 40;
                     if (XB->mps != 0){
                         move_nb = XB->mps - (Uci->board->move_nb % XB->mps);
                     }
                     time = XB->my_time / move_nb;
                     if(XB->inc != 0){
                         time += XB->inc;
                     }
                     if(time > XB->my_time){
                         time = XB->my_time;
                     }
                     engine_send_queue(Engine,
                                       " nodes %.0f",
                                       time*XB->node_rate);
                 } else {
                     
                     if (colour_is_white(Uci->board->turn)) {
                         engine_send_queue(Engine,
                                           " wtime %.0f btime %.0f",
                                           XB->my_time*1000.0,XB->opp_time*1000.0);
                     } else {
                         engine_send_queue(Engine,
                                           " wtime %.0f btime %.0f",
                                           XB->opp_time*1000.0,XB->my_time*1000.0);
                     }
                     
                     if (XB->inc != 0.0){
                         engine_send_queue(Engine,
                                           " winc %.0f binc %.0f",
                                           XB->inc*1000.0,XB->inc*1000.0);
                     }
                     if (XB->mps != 0) {

                         move_nb = XB->mps - (Uci->board->move_nb % XB->mps);
                         ASSERT(move_nb>=1&&move_nb<=XB->mps);
                         
                         engine_send_queue(Engine," movestogo %d",move_nb);
                     }
                 }
         }
         if (XB->depth_limit) engine_send_queue(Engine," depth %d",XB->depth_max);

         if (State->state == PONDER) engine_send_queue(Engine," ponder");

         engine_send(Engine,""); // newline

      } else if (State->state == ANALYSE) {

         engine_send(Engine,"go infinite");

      } else {

         ASSERT(FALSE);
      }

      // init search info

      ASSERT(!Uci->searching);

      search_clear();

      Uci->searching = TRUE;
      Uci->pending_nb++;
   }
}