Exemple #1
0
/*
 *******************************************************************************
 *                                                                             *
 *   Analyze() is used to handle the "analyze" command.  This mode basically   *
 *   puts Crafty into a "permanent pondering" state, where it reads a move     *
 *   from the input stream, and then "ponders" for the opposite side.          *
 *   Whenever a move is entered, Crafty reads this move, updates the game      *
 *   board, and then starts "pondering" for the other side.                    *
 *                                                                             *
 *   The purpose of this mode is to force Crafty to follow along in a game,    *
 *   providing analysis continually for the side on move until a move is       *
 *   entered, advancing the game to the next position.                         *
 *                                                                             *
 *******************************************************************************
 */
void Analyze() {
  int i, move, back_number, readstat = 1;
  TREE *const tree = block[0];

/*
 ************************************************************
 *                                                          *
 *  Initialize.                                             *
 *                                                          *
 ************************************************************
 */
  int save_swindle_mode = swindle_mode;

  swindle_mode = 0;
  ponder_move = 0;
  analyze_mode = 1;
  if (!xboard)
    display_options |= 1 + 2 + 4;
  _printf("Analyze Mode: type \"exit\" to terminate.\n");
/*
 ************************************************************
 *                                                          *
 *  Now loop waiting on input, searching the current        *
 *  position continually until a move comes in.             *
 *                                                          *
 ************************************************************
 */
  do {
    do {
      last_pv.pathd = 0;
      last_pv.pathl = 0;
      input_status = 0;
      pondering = 1;
      tree->status[1] = tree->status[0];
      Iterate(game_wtm, think, 0);
      pondering = 0;
      if (book_move)
        moves_out_of_book = 0;
      if (!xboard) {
        if (game_wtm)
          _printf("analyze.White(%d): ", move_number);
        else
          _printf("analyze.Black(%d): ", move_number);
        fflush(stdout);
      }
/*
 ************************************************************
 *                                                          *
 *  If we get back to here, something has been typed in and *
 *  is in the command buffer normally, unless the search    *
 *  terminated naturally due to finding a mate or reaching  *
 *  the max depth allowable.                                *
 *                                                          *
 ************************************************************
 */
      if (!input_status)
        do {
          readstat = Read(1, buffer);
          if (readstat < 0)
            break;
          nargs = ReadParse(buffer, args, " 	;");
          Print(128, "%s\n", buffer);
          if (strstr(args[0], "timeleft") && !xboard) {
            if (game_wtm)
              _printf("analyze.White(%d): ", move_number);
            else
              _printf("analyze.Black(%d): ", move_number);
            fflush(stdout);
          }
        } while (strstr(args[0], "timeleft"));
      else
        nargs = ReadParse(buffer, args, " 	;");
      if (readstat < 0)
        break;
      move = 0;
      if (!strcmp(args[0], "exit"))
        break;
/*
 ************************************************************
 *                                                          *
 *  First, check for the special analyze command "back n"   *
 *  and handle it if present, otherwise try Option() to see *
 *  if it recognizes the input as a command.                *
 *                                                          *
 ************************************************************
 */
      if (OptionMatch("back", args[0])) {
        if (nargs > 1)
          back_number = atoi(args[1]);
        else
          back_number = 1;
        for (i = 0; i < back_number; i++) {
          game_wtm = Flip(game_wtm);
          if (Flip(game_wtm))
            move_number--;
        }
        if (move_number == 0) {
          move_number = 1;
          game_wtm = 1;
        }
        sprintf(buffer, "reset %d", move_number);
        Option(tree);
        display = tree->position;
      } else if (Option(tree)) {
        display = tree->position;
      }
/*
 ************************************************************
 *                                                          *
 *  If InputMove() can recognize this as a move, make it,   *
 *  swap sides, and return to the top of the loop to call   *
 *  search from this new position.                          *
 *                                                          *
 ************************************************************
 */
      else if ((move = InputMove(tree, buffer, 0, game_wtm, 1, 0))) {
        char *outmove = OutputMove(tree, move, 0, game_wtm);

        if (history_file) {
          fseek(history_file, ((move_number - 1) * 2 + 1 - game_wtm) * 10,
              SEEK_SET);
          fprintf(history_file, "%9s\n", outmove);
        }
        if (game_wtm)
          Print(128, "White(%d): ", move_number);
        else
          Print(128, "Black(%d): ", move_number);
        Print(128, "%s\n", outmove);
        if (speech) {
          char announce[64];

          //strcpy(announce, SPEAK);
          //strcat(announce, outmove);
          //system(announce);

          SPEAK(outmove);
        }
        MakeMoveRoot(tree, move, game_wtm);
        display = tree->position;
        last_mate_score = 0;
        if (log_file)
          DisplayChessBoardFile(log_file, tree->position);
      }
/*
 ************************************************************
 *                                                          *
 *  If Option() didn't handle the input, then it is illegal *
 *  and should be reported to the user.                     *
 *                                                          *
 ************************************************************
 */
      else {
        pondering = 0;
        if (Option(tree) == 0)
          _printf("illegal move: %s\n", buffer);
        pondering = 1;
        display = tree->position;
      }
    } while (!move);
    if (readstat < 0 || !strcmp(args[0], "exit"))
      break;
    game_wtm = Flip(game_wtm);
    if (game_wtm)
      move_number++;
  } while (1);
  analyze_mode = 0;
  _printf("analyze complete.\n");
  pondering = 0;
  swindle_mode = save_swindle_mode;
}
Exemple #2
0
/*
 *******************************************************************************
 *                                                                             *
 *   Interrupt() is used to read in a move when the operator types something   *
 *   while a search is in progress (during pondering as one example.)  This    *
 *   routine reads in a command (move) and then makes two attempts to use this *
 *   input:  (1) call Option() to see if the command can be executed;  (2) try *
 *   InputMove() to see if this input is a legal move;  If so, and we are      *
 *   pondering see if it matches the move we are pondering.                    *
 *                                                                             *
 *******************************************************************************
 */
void Interrupt(int ply) {
  int temp, i, left = 0, readstat, result, time_used;
  int save_move_number;
  TREE *const tree = block[0];

/*
 ************************************************************
 *                                                          *
 *   If trying to find a move to ponder, and the operator   *
 *   types a command, exit a.s.a.p.                         *
 *                                                          *
 ************************************************************
 */
  if (puzzling)
    abort_search = 1;
/*
 ************************************************************
 *                                                          *
 *   First check to see if this is a command by calling     *
 *   Option().  Option() will return a 0 if it didn't       *
 *   recognize the command; otherwise it returns a 1 if     *
 *   the command was executed, or a 2 if we need to abort   *
 *   the search to execute the command.                     *
 *                                                          *
 ************************************************************
 */
  else
    do {
      readstat = Read(0, buffer);
      if (readstat <= 0)
        break;
      nargs = ReadParse(buffer, args, " 	;");
      if (nargs == 0) {
        Print(128, "ok.\n");
        break;
      }
      if (strcmp(args[0], ".")) {
        save_move_number = move_number;
        if (!wtm)
          move_number--;
        if (root_wtm)
          Print(128, "Black(%d): %s\n", move_number, buffer);
        else
          Print(128, "White(%d): %s\n", move_number, buffer);
        move_number = save_move_number;
      }
/*
 ************************************************************
 *                                                          *
 *   "." command displays status of current search.         *
 *                                                          *
 ************************************************************
 */
      if (!strcmp(args[0], ".")) {
        if (xboard) {
          end_time = ReadClock();
          time_used = (end_time - start_time);
          printf("stat01: %d ", time_used);
          printf(BMF " ", tree->nodes_searched);
          printf("%d ", iteration_depth);
          for (i = 0; i < n_root_moves; i++)
            if (!(root_moves[i].status & 128))
              left++;
          printf("%d %d\n", left, n_root_moves);
          fflush(stdout);
          break;
        } else {
          end_time = ReadClock();
          time_used = (end_time - start_time);
          printf("time:%s ", DisplayTime(time_used));
          printf("nodes:" BMF "\n", tree->nodes_searched);
          DisplayTreeState(block[0], 1, 0, ply);
        }
      }
/*
 ************************************************************
 *                                                          *
 *   "mn" command is used to set the move number to a       *
 *   specific value...                                      *
 *                                                          *
 ************************************************************
 */
      else if (!strcmp("mn", args[0])) {
        if (nargs == 2) {
          move_number = atoi(args[1]);
          Print(128, "move number set to %d\n", move_number);
        }
      }
/*
 ************************************************************
 *                                                          *
 *   "?" command says "move now!"                           *
 *                                                          *
 ************************************************************
 */
      else if (!strcmp(args[0], "?")) {
        if (thinking) {
          time_abort = 1;
          abort_search = 1;
        }
      }
/*
 ************************************************************
 *                                                          *
 *   Next see if Option() recognizes this as a command.     *
 *                                                          *
 ************************************************************
 */
      else {
        save_move_number = move_number;
        if (!analyze_mode && !wtm)
          move_number--;
        result = Option(tree);
        move_number = save_move_number;
        if (result >= 2) {
          if (thinking && result != 3)
            Print(128, "command not legal now.\n");
          else {
            abort_search = 1;
            input_status = 2;
            break;
          }
        } else if ((result != 1) && analyze_mode) {
          abort_search = 1;
          input_status = 2;
          break;
        }
/*
 ************************************************************
 *                                                          *
 *   Now, check to see if the operator typed a move.  If    *
 *   so, and it matched the predicted move, switch from     *
 *   pondering to thinking to start the timer.  If this     *
 *   is a move, but not the predicted move, abort the       *
 *   search, and start over with the right move.            *
 *                                                          *
 ************************************************************
 */
        else if (!result) {
          if (pondering) {
            nargs = ReadParse(buffer, args, " 	;");
            temp = InputMove(tree, args[0], 0, Flip(root_wtm), 1, 1);
            if (temp) {
              if ((From(temp) == From(ponder_move)) &&
                  (To(temp) == To(ponder_move)) &&
                  (Piece(temp) == Piece(ponder_move)) &&
                  (Captured(temp) == Captured(ponder_move)) &&
                  (Promote(temp) == Promote(ponder_move))) {
                predicted++;
                input_status = 1;
                pondering = 0;
                thinking = 1;
                opponent_end_time = ReadClock();
                program_start_time = ReadClock();
                Print(128, "predicted move made.\n");
              } else {
                input_status = 2;
                abort_search = 1;
                break;
              }
            } else if (!strcmp(args[0], "go") || !strcmp(args[0], "move") ||
                !strcmp(args[0], "SP")) {
              abort_search = 1;
              break;
            } else
              Print(4095, "Illegal move: %s\n", args[0]);
          } else
            Print(4095, "unrecognized/illegal command: %s\n", args[0]);
        }
      }
    } while (1);
  if (log_file)
    fflush(log_file);
}