Esempio n. 1
0
bool UsiClient::runPonder(const CommandArguments&) {
  searcherIsStarted_ = false;
  inPonder_ = true;

  ScopedThread searchThread;
  searchThread.start([this]() {
    ponder();
  }, [this]() {
    searcher_->interrupt();
  });
  waitForSearcherIsStarted();

  auto command = receive();
  if (command.state != CommandState::Ok) {
    return false;
  }

  auto args = StringUtil::split(command.value, [](char c) {
    return isspace(c);
  });

  if (args[0] == "stop") {
    send("bestmove", "resign");
    return true;
  }

  if (args[0] == "ponderhit") {
    std::string ponderSection(" ponder");
    lastGoCommand_.replace(lastGoCommand_.find(ponderSection),
                           ponderSection.length(),
                           "");
    deferredCommands_.push(lastPositionCommand_);
    deferredCommands_.push(lastGoCommand_);
    return true;
  }

  deferredCommands_.push(command.value);
 
  return true;
}
Esempio n. 2
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) {

      // 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++;
   }
}
Esempio n. 3
0
static void no_mess(int move) {

   ASSERT(move_is_ok(move));

   // just received a move, calculate the new state

   if (false) {

   } else if (!active()) {

      stop_search(); // abort a possible search

      State->state = WAIT;
      State->exp_move = MoveNone;

      my_log("POLYGLOT WAIT\n");

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

      ASSERT(State->computer[game_turn(Game)]);
      ASSERT(!State->computer[colour_opp(game_turn(Game))]);
      ASSERT(!XB->analyse);

      my_log("POLYGLOT WAIT -> THINK\n");

      State->state = THINK;
      State->exp_move = MoveNone;

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

      ASSERT(!State->computer[game_turn(Game)]);
      ASSERT(State->computer[colour_opp(game_turn(Game))]);
      ASSERT(!XB->analyse);

      if (ponder() && ponder_move_is_ok(Uci->ponder_move)) {

         my_log("POLYGLOT THINK -> PONDER\n");

         State->state = PONDER;
         State->exp_move = Uci->ponder_move;

      } else {

         my_log("POLYGLOT THINK -> WAIT\n");

         State->state = WAIT;
         State->exp_move = MoveNone;
      }

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

      ASSERT(State->computer[game_turn(Game)]);
      ASSERT(!State->computer[colour_opp(game_turn(Game))]);
      ASSERT(!XB->analyse);

      if (move == State->exp_move && Uci->searching) {

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

         my_timer_reset(State->timer);
         my_timer_start(State->timer);

         my_log("POLYGLOT PONDER -> THINK (*** HIT ***)\n");
         engine_send(Engine,"ponderhit");

         State->state = THINK;
         State->exp_move = MoveNone;

         send_pv(); // update display

         return; // do not launch a new search

      } else {

         my_log("POLYGLOT PONDER -> THINK (miss)\n");

         stop_search();

         State->state = THINK;
         State->exp_move = MoveNone;
      }

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

      ASSERT(XB->analyse);

      my_log("POLYGLOT ANALYSE -> ANALYSE\n");

      stop_search();

   } else {

      ASSERT(false);
   }

   search_update();
}
Esempio n. 4
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++;
   }
}
Esempio n. 5
0
int main (int argc, char *argv[])
{
  int i;

  /*
   * Parse command line arguments conforming with getopt_long syntax
   * Note: we have to support "xboard" and "post" as bare strings
   * for backward compatibility.
   */
 
  int c;
  int opt_help = 0, opt_version = 0, opt_post = 0, opt_xboard = 0, opt_hash = 0, opt_memory = 0, opt_easy = 0, opt_manual = 0;
  char *endptr;

  progname = argv[0]; /* Save in global for cmd_usage */

  while (1)
  {
    static struct option long_options[] =
    {
        {"hashsize", 1, 0, 's'},
        {"memory", 1, 0, 'M'},
        {"version", 0, 0, 'v'},
        {"help", 0, 0, 'h'},
        {"xboard", 0, 0, 'x'},
        {"post", 0, 0, 'p'},
        {"easy", 0, 0, 'e'},
        {"manual", 0, 0, 'm'},
        {0, 0, 0, 0}
    };
 
    /* getopt_long stores the option index here. */ 

    int option_index = 0;
 
    c = getopt_long (argc, argv, "ehmpvxs:M:",
             long_options, &option_index);
 
    /* Detect the end of the options. */
   if (c == -1)
     break;

   /* 
    * Options with a straight flag, could use getoopt_long
    * flag setting but this is more "obvious" and easier to
    * modify.
    */
   switch (c)
     {
     case 'v':
       opt_version = 1;
       break;
     case 'h':
       opt_help = 1;
       break;
     case 'x':
       opt_xboard = 1;
       break;
     case 'p':
       opt_post = 1;
       break;
     case 'e':
       opt_easy = 1;
       break;
     case 'm':
       opt_manual = 1;
       break;
     case 's':    
       if  ( optarg == NULL ){ /* we have error such as two -s */
         opt_help = 1;
         break;
       }
       errno = 0; /* zero error indicator */
       opt_hash = strtol (optarg, &endptr, 10);
       if ( errno != 0 || *endptr != '\0' ){
         printf("Hashsize out of Range or Invalid\n");
         return(1);
       }
       break;
     case 'M':    
       if  ( optarg == NULL ){ /* we have error such as two -s */
         opt_help = 1;
         break;
       }
       errno = 0; /* zero error indicator */
       opt_memory = strtol (optarg, &endptr, 10);
       if ( errno != 0 || *endptr != '\0' ){
         printf("Memory size invalid\n");
         return(1);
       }
       break;
     case '?': /* On error give help - getopt does a basic message. */
       opt_help = 1;
       break;
     default:
       puts ("Option Processing Failed\n");
       abort();
     }
  } /* end of getopt_long style parsing */

  /* Initialize random number generator */
  srand((unsigned int) time(NULL));
  
  /* initialize control flags */
  flags = ULL(0);

  /* output for thinking */
  ofp = stdout;

  /* Handle old style command line options */
  if (argc > 1) {
    for (i = 0; i < argc; i++) {
      if (strcmp(argv[i],"xboard") == 0) {
	SET (flags, XBOARD);
      } else if (strcmp(argv[i],"post") == 0) {
	SET (flags, POST);
      }
    }
  }
  if (opt_xboard == 1)
	SET (flags, XBOARD);
  if (opt_post == 1)
	SET (flags, POST);	
  if (opt_manual ==1)
	SET (flags, MANUAL);
  cmd_version();
  
  /* If the version option was specified we can exit here */
  if (opt_version == 1)
	return(0);
  
  /* If a usage statement is required output it here */
  if (opt_help == 1){
    cmd_usage();
    return (1); /* Maybe an error if due to bad arguments. */
  }

  if (opt_memory != 0 && opt_hash != 0 ){
    cmd_usage();
    return (1); /* only one or the other */
  }

  HashSize = 0 ; /* Set HashSize zero */
  if ( opt_hash != 0)
    CalcHashSize(opt_hash);

  if ( opt_memory > 0 ){
    int tablesize=(1048576*opt_memory)/(2*sizeof(HashSlot));
    CalcHashSize(tablesize);
  }

  Initialize ();

  if ( opt_easy == 0)
   SET (flags, HARD);

  if (argc > 1) {
    for (i = 0; i < argc; i++) {
      if (strcmp(argv[i],"xboard") == 0) {
	SET (flags, XBOARD);
      } else if (strcmp(argv[i],"post") == 0) {
	SET (flags, POST);
      } 
    }
  }

  bookmode = BOOKPREFER;
  bookfirstlast = 3;

  while (!(flags & QUIT)) {
    wait_for_input();
    parse_input();
    if ((flags & THINK) && !(flags & MANUAL) && !(flags & ENDED)) {
      if (!(flags & XBOARD)) printf("Thinking...\n");
      Iterate ();
      CLEAR (flags, THINK);
    }
    RealGameCnt = GameCnt;
    RealSide = board.side;
    input_wakeup();
    /* Ponder only after first move */
    /* Ponder or (if pondering disabled) just wait for input */
    if ((flags & HARD) && !(flags & QUIT) ) {
      ponder();
    }
  }
  
  CleanupInput();

  /*  Some cleaning up  */
  free (HashTab[0]);
  free (HashTab[1]);

  return (0);
}
Esempio n. 6
0
    }

  if ( fin() < 0 ) { out_error( "%s", str_error ); }

  return EXIT_SUCCESS;
}


static int
main_child( tree_t * restrict ptree )
{
  int iret;

  /* ponder a move */
  ponder_move = 0;
  iret = ponder( ptree );
  if ( iret < 0 ) { return iret; }
  else if ( game_status & flag_quit ) { return -3; }

  /* move prediction succeeded, pondering finished,
     and computer made a move. */
  else if ( iret == 2 ) { return 1; }

  /* move prediction failed, pondering aborted,
     and we have opponent's move in input buffer. */
  else if ( ponder_move == MOVE_PONDER_FAILED )
    {
    }

  /* pondering is interrupted or ended.
     do nothing until we get next input line. */
Esempio n. 7
0
/* returns -1 for stalemate or winner's color */
int playchess()
{
    int use_pondering = 0;
    
    printboard_and_time();
     
    for (;;)
    {
	long starttime, endtime;
	move m;
	int g;

	g = gameoverp(tomove());

	if (g)
	{
	    switch (g)
	    {
		case END_CHECKMATE:
		    if (tomove() == BLACK)
		    {
			return end(WHITE, "white mates");
		    }
		    else
		    {
			return end(BLACK, "black mates");
		    }
		case END_STALEMATE:
		    return end(-1, "stalemate");
		case NON_MATERIAL:
		    return end(-1, "insufficient material");
		case REP_DRAW:
		    if (!robo_mode)
		    {
			printf("drawable position\n");
		    }
		    if (computer[WHITE]||computer[BLACK])
		    {
			if (robo_mode)
			    tellics("draw\n");
			return end(-1, "draw by repetition of moves");
		    }
		    break;
	    }
	}
    
	starttime = get_ms();
	
	if (computer[tomove()])
	{
	    m = bce();

	    if ((m!=dummymove)&&(validmove(m)==1))
	    {
		printf("move %s\n", movestring(m));
	    }
	    else
	    {
		if (robo_mode)
		{
		    tellics("mailmoves\n");
		    tellics(
			"message madhacker valid? = %d, move = %s, wouldbeincheckp() = %d, wouldbeinfullcheckp() = %d, pv = %s\n",
			validmove(m),
			movestring(m),
			wouldbeincheckp(m),
			wouldbeincheckfullp(m),
			thoughts);
		    tellics("abort\n");
		}
		else
		{
		    printf("BCE returned invalid move: %s\n", movestring(m));
		    printf("valid? = %d\n", validmove(m));

		    fprintf(stdout, "random seed = %ld\n", seed);
		    fprintf(stdout, "hash = %lld\n", board->hash);
		    fprintf(stdout, "draw? = %d g = %d\n",
			    draw_by_rep(), g);
		    computer[1] = computer[0] = 0;
		}
	    }
	    use_pondering = 1;
	}
	else 
	{
	    if ((ponder_mode && computer[opp(tomove())])&&
		use_pondering)
	    {
		ponder();
		use_pondering = 0;
	    }
	    
	    m = usermove();
	    use_pondering = 0;
	}
    
	endtime = get_ms();
	chessclock[tomove()] -= (endtime-starttime);
	chessclock[tomove()] += clockinc;
    
	if (m)
	{
	    domove(m);
	    update_state(m);
	    printboard_and_time();
	}
    }
}
Esempio n. 8
0
/**
 * \brief  	This is the main run cycle of the game,
 * 		no matter what happens in the game logic or
 * 		which engine is chosen, it always get to this point
 * 		Mainly timer and logic processes are performed here.
 */
void GsApp::runMainCycle()
{
    // I hope the engine has been set. Otherwise quit the app
    assert(mpCurEngine);

    mpCurEngine->start();

    float acc = 0.0f;
    float start = 0.0f;
    float elapsed = 0.0f;
    float total_elapsed = 0.0f;
    float curr = 0.0f;
    int counter = 0;

    while(1)
    {
        const float logicLatency = gTimer.LogicLatency();
        const float renderLatency = gTimer.RenderLatency();

        curr = timerTicks();

        if(gTimer.resetLogicSignal())
            start = curr;

        elapsed = curr - start;        

        start = timerTicks();

        acc += elapsed;

        // Perform the game cycle
        while( acc > logicLatency )
        {
            // Poll Inputs
            gInput.pollEvents();

            // Process App Events
            gEventManager.processSinks();

            // Ponder Game Control
            ponder(logicLatency);

            acc -= logicLatency;
        }

        // Now we render the whole GameControl Object to the blit surface
        render();

        // Apply graphical effects if any.
        gEffectController.render();

        // Pass all the surfaces to one. Some special surfaces are used and are collected here
        gVideoDriver.collectSurfaces();

        // Now you really render the screen
        // When enabled, it also will apply Filters
        gVideoDriver.updateDisplay();


        elapsed = timerTicks() - start;
        total_elapsed += elapsed;

        if( mustShutdown() )
            break;

        int waitTime = renderLatency - elapsed;

        // wait time remaining in current loop
        if( waitTime > 0 )
            timerDelay(waitTime);

        total_elapsed += static_cast<float>(waitTime);

        // This will refresh the fps display, so it stays readable and calculates an average value.
        counter++;
        if(counter >= 100)
        {
            counter = 0;
            gTimer.setTimeforLastLoop(total_elapsed/100.0f);
            total_elapsed = 0.0f;
        }
    }

    cleanup();
}