cmd.c

来自「gun C 环境下编写的」· C语言 代码 · 共 995 行 · 第 1/2 页

C
995 行
字号
{
  board.side = 1^board.side;
  board.ep = -1 ; /* Enpassant doesn't apply after switch */
  printf ("%s to move\n", board.side == white ? "White" : "Black");
}

void cmd_time(void)
{
  TimeLimit[1^board.side] = atoi(token[1]) / 100.0f ;
}

void cmd_undo(void)
{
  if (GameCnt >= 0)
    UnmakeMove (board.side, &Game[GameCnt].move);
  else
    printf ("No moves to undo! \n");
  MoveLimit[board.side]++;
  TimeLimit[board.side] += Game[GameCnt+1].et;
  if (!(flags & XBOARD)) ShowBoard ();
}

void cmd_usage(void) 
{
      printf (
     "\n"
     " Usage: %s [OPTION]\n"
     "\n"
     " -h, --help         display this help and exit\n"
     " -v, --version      display version information and exit\n" 
     "\n"
     " -x, --xboard       start in engine mode\n"
     " -p, --post   	   start up showing thinking\n"
     " -e, --easy   	   disable thinking in opponents time\n"
     " -m, --manual  	   enable manual mode\n"
     " -s size, --hashsize=size   specify hashtable size in slots\n"
     "\n"
     " Options xboard and post are accepted without leading dashes\n"
     " for backward compatibility\n"
     "\n"
     "Report bugs to <bug-gnu-chess@gnu.org>.\n"
     "\n", progname);
     }


/* Play variant, we instruct interface in protover we play normal */
void cmd_variant(void) {}

void cmd_version(void)
{
   if (!(flags & XBOARD))
     printf ("%s %s\n", PROGRAM, VERSION);
   else
     printf ("Chess\n");
}

void cmd_white(void) 
{
 /* 
  * No longer used by Xboard but requested as a feature
  */

  NewPosition(); /* Reset some flags and settings */
  CLEAR ( flags, THINK);
  CLEAR ( flags, MANUAL);
  CLEAR (flags, TIMEOUT);   
  computer = black;
  if ( board.side == black ){
    board.side = white;
    board.ep = -1; /* Hack to fixed appearing pawn bug */
  }
}

void cmd_xboard(void)
{
  if (tokeneq (token[1], "off"))
    CLEAR (flags, XBOARD);
  else if (tokeneq (token[1], "on"))
    SET (flags, XBOARD);
  else if (!(flags & XBOARD)) { /* set if unset and only xboard called */
    SET (flags, XBOARD);	    /* like in xboard/winboard usage */
  }
}

/*
 * Command with subcommands, could write secondary method
 * tables here
 */

void cmd_show (void)
/************************************************************************
 *
 *  The show command driver section.
 *
 ************************************************************************/
{
   if (tokeneq (token[1], "board"))
      ShowBoard ();
   else if (tokeneq (token[1], "rating"))
   {
      printf("My rating = %d\n",myrating);
      printf("Opponent rating = %d\n",opprating);
   } 
   else if (tokeneq (token[1], "time"))
      ShowTime ();
   else if (tokeneq (token[1], "moves")) {
      GenCnt = 0;
      TreePtr[2] = TreePtr[1];
      GenMoves (1);      
      ShowMoveList (1);
      printf ("No. of moves generated = %ld\n", GenCnt);
   }
   else if (tokeneq (token[1], "escape")) {
      GenCnt = 0;
      TreePtr[2] = TreePtr[1];
      GenCheckEscapes (1);      
      ShowMoveList (1);
      printf ("No. of moves generated = %ld\n", GenCnt);
   }
   else if (tokeneq (token[1], "noncapture"))
   {
      GenCnt = 0;
      TreePtr[2] = TreePtr[1];
      GenNonCaptures (1);      
      FilterIllegalMoves (1);
      ShowMoveList (1);
      printf ("No. of moves generated = %ld\n", GenCnt);
   }
   else if (tokeneq (token[1], "capture"))
   {
      GenCnt = 0;
      TreePtr[2] = TreePtr[1];
      GenCaptures (1);      
      FilterIllegalMoves (1);
      ShowMoveList (1);
      printf ("No. of moves generated = %ld\n", GenCnt);
   }
   else if (tokeneq (token[1], "eval") || tokeneq (token[1], "score"))
   {
      int s, wp, bp, wk, bk;
      BitBoard *b;

      phase = PHASE;
      GenAtaks ();
      FindPins (&pinned);
      hunged[white] = EvalHung(white);
      hunged[black] = EvalHung(black);
      b = board.b[white];
      pieces[white] = b[knight] | b[bishop] | b[rook] | b[queen]; 
      b = board.b[black];
      pieces[black] = b[knight] | b[bishop] | b[rook] | b[queen]; 
      wp = ScoreP (white);
      bp = ScoreP (black);
      wk = ScoreK (white);
      bk = ScoreK (black);
      printf ("White:  Mat:%4d/%4d  P:%d  N:%d  B:%d  R:%d  Q:%d  K:%d  Dev:%d  h:%d x:%d\n",
	board.pmaterial[white], board.material[white], wp, ScoreN(white), 
        ScoreB(white), ScoreR(white), ScoreQ(white), wk, 
        ScoreDev(white), hunged[white], ExchCnt[white]);
      printf ("Black:  Mat:%4d/%4d  P:%d  N:%d  B:%d  R:%d  Q:%d  K:%d  Dev:%d  h:%d x:%d\n",
	board.pmaterial[black], board.material[black], bp, ScoreN(black), 
        ScoreB(black), ScoreR(black), ScoreQ(black), bk,
        ScoreDev(black), hunged[black], ExchCnt[black]);
      printf ("Phase: %d\t", PHASE);
      s = ( EvaluateDraw () ? DRAWSCORE : Evaluate (-INFINITY, INFINITY));
      printf ("score = %d\n", s);
      printf ("\n");
   }
   else if (tokeneq (token[1], "game"))
     ShowGame ();
   else if (tokeneq (token[1], "pin"))
   {
      BitBoard b;
      GenAtaks ();
      FindPins (&b);
      ShowBitBoard (&b);
   }
}

void cmd_test (void)
/*************************************************************************
 *
 *  The test command driver section.
 *
 *************************************************************************/
{
  if (tokeneq (token[1], "movelist"))
    TestMoveList ();
  else if (tokeneq (token[1], "capture"))
    TestCaptureList ();
  else if (tokeneq (token[1], "movegenspeed"))
    TestMoveGenSpeed ();
  else if (tokeneq (token[1], "capturespeed"))
    TestCaptureGenSpeed ();
  else if (tokeneq (token[1], "eval"))
    TestEval ();
  else if (tokeneq (token[1], "evalspeed"))
    TestEvalSpeed ();
}

/*
 * This is more or less copied from the readme, and the
 * parser is not very clever, so the lines containing
 * command names should not be indented, the lines with
 * explanations following them should be indented. Do not
 * use tabs for indentation, only spaces. CAPITALS are
 * reserved for parameters in the command names. The
 * array must be terminated by two NULLs.
 * 
 * This one should be integrated in the method table.
 * (Very much like docstrings in Lisp.)
 */

static const char * const helpstr[] = {
   "^C",
   " Typically the interrupt key stops a search in progress,",
   " makes the move last considered best and returns to the",
   " command prompt",
   "quit",
   " quit the program.",
   "exit",
   " In analysis mode this stops analysis, otherwise it quits the program.",
   "help",
   " Produces a help blurb corresponding to this list of commands.",
   "book",
   " add - compiles book.dat from book.pgn",
   " on - enables use of book",
   " off - disables use of book",
   " worst - play worst move from book",
   " best - play best move from book",
   " prefer - default, same as 'book on'",
   " random - play any move from book",
   "version",
   " prints out the version of this program",
   "pgnsave FILENAME",
   " saves the game so far to the file from memory",
   "pgnload FILENAME",
   " loads the game in the file into memory",
   "force",
   "manual",
   " Makes the program stop moving. You may now enter moves",
   " to reach some position in the future.",
   " ",
   "white",
   " Program plays white",
   "black",
   " Program plays black",
   "go",
   " Computer takes whichever side is on move and begins its",
   " thinking immediately",
   "post",
   " Arranges for verbose thinking output showing variation, score,",
   " time, depth, etc.",
   "nopost",
   " Turns off verbose thinking output",
   "name NAME",
   " Lets you input your name. Also writes the log.nnn and a",
   " corresponding game.nnn file. For details please see",
   " auxillary file format sections.",
   "result",
   " Mostly used by Internet Chess server.",
   "activate",
   " This command reactivates a game that has been terminated automatically",
   " due to checkmate or no more time on the clock. However, it does not",
   " alter those conditions. You would have to undo a move or two or",
   " add time to the clock with level or time in that case.",
   "rating COMPUTERRATING OPPONENTRATING",
   " Inputs the estimated rating for computer and for its opponent",
   "new",
   " Sets up new game (i.e. positions in original positions)",
   "time",
   " Inputs time left in game for computer in hundredths of a second.",
   " Mostly used by Internet Chess server.",
   "hash",
   " on - enables using the memory hash table to speed search",
   " off - disables the memory hash table",
   "hashsize N",
   " Sets the hash table to permit storage of N positions",
   "null",
   " on - enables using the null move heuristic to speed search",
   " off - disables using the null move heuristic",
   "xboard",
   " on - enables use of xboard/winboard",
   " off - disables use of xboard/winboard",
   "depth N",
   " Sets the program to look N ply (half-moves) deep for every",
   " search it performs. If there is a checkmate or other condition",
   " that does not allow that depth, then it will not be ",
   "level MOVES MINUTES INCREMENT",
   " Sets time control to be MOVES in MINUTES with each move giving",
   " an INCREMENT (in seconds, i.e. Fischer-style clock).",
   "load",
   "epdload",
   " Loads a position in EPD format from disk into memory.",
   "save",
   "epdsave",
   " Saves game position into EPD format from memory to disk.",
   "switch",
   " Switches side to move",
   "solve FILENAME",
   "solveepd FILENAME",
   " Solves the positions in FILENAME",
   "remove",
   " Backs up two moves in game history",
   "undo",
   " Backs up one move in game history",
   "usage",
   " Display command line syntax",
   "show",
   " board - displays the current board",
   " time - displays the time settings",
   " moves - shows all moves using one call to routine",
   " escape - shows moves that escape from check using one call to routine",
   " noncapture - shows non-capture moves",
   " capture - shows capture moves",
   " eval [or score] - shows the evaluation per piece and overall",
   " game - shows moves in game history",
   " pin - shows pinned pieces",
   "test",
   " movelist - reads in an epd file and shows legal moves for its entries",
   " capture - reads in an epd file and shows legal captures for its entries",
   " movegenspeed - tests speed of move generator",
   " capturespeed - tests speed of capture move generator",
   " eval - reads in an epd file and shows evaluation for its entries",
   " evalspeed tests speed of the evaluator",
   "bk",
   " show moves from opening book.",
   NULL,
   NULL
};

void cmd_help (void)
/**************************************************************************
 *
 *  Display all the help commands.
 *
 **************************************************************************/
{
   const char * const *p;
   int count, len;

   if (strlen(token[1])>0) {
      for (p=helpstr, count=0; *p; p++) {
	 if  (strncmp(*p, token[1], strlen(token[1])) == 0) {
	    puts(*p);
	    while (*++p && **p != ' ') /* Skip aliases */ ;
	    for (; *p && **p == ' '; p++) {
	       puts(*p);
	    }
	    return;
	 }
      }
      printf("Help for command %s not found\n\n", token[1]);
   }
   printf("List of commands: (help COMMAND to get more help)\n");
   for (p=helpstr, count=0; *p; p++) {
      len = strcspn(*p, " ");
      if (len > 0) {
	 count += printf("%.*s  ", len, *p);
	 if (count > 60) {
	    count = 0;
	    puts("");
	 }
      }
   }
   puts("");
}

/*
 * Try a method table, one could also include the documentation
 * strings here
 */

struct methodtable {
  const char *name;
  void (*method) (void);
};

/* Last entry contains to NULL pointers */

/* List commands we don't implement to avoid illegal moving them */

const struct methodtable commands[] = {
  { "?", cmd_movenow },
  { "accepted", cmd_accepted },
  { "activate", cmd_activate },
  { "analyze", cmd_analyze },
  { "bk", cmd_bk },
  { "black", cmd_black },
  { "book", cmd_book },
  { "computer", cmd_computer },
  { "depth", cmd_depth },
  { "draw", cmd_draw },
  { "easy", cmd_easy },
  { "edit", cmd_edit },
  { "epd", cmd_epd },
  { "epdload", cmd_load },
  { "epdsave", cmd_save },
  { "exit", cmd_exit },
  { "force", cmd_force },
  { "go", cmd_go },
  { "hard", cmd_hard },
  { "hash", cmd_hash },
  { "hashsize", cmd_hashsize },
  { "help", cmd_help },
  { "hint", cmd_hint },
  { "level", cmd_level },
  { "list", cmd_list },
  { "load", cmd_load },
  { "manual", cmd_manual },
  { "name", cmd_name },
  { "new", cmd_new },
  { "nopost", cmd_nopost },
  { "null", cmd_null },
  { "otim", cmd_otim },
  { "pgnload", cmd_pgnload },
  { "pgnsave", cmd_pgnsave },
  { "ping", cmd_ping },
  { "post", cmd_post },
  { "protover", cmd_protover },
  { "quit", cmd_quit },
  { "random", cmd_random },
  { "rating", cmd_rating },
  { "rejected", cmd_rejected },
  { "remove", cmd_remove },
  { "result", cmd_result },
  { "save", cmd_save },
  { "setboard", cmd_setboard },
  { "show", cmd_show },
  { "solve", cmd_solve },
  { "solveepd", cmd_solve },
  { "st", cmd_st },
  { "switch", cmd_switch },
  { "test", cmd_test },
  { "time", cmd_time },
  { "undo", cmd_undo },
  { "usage", cmd_usage },
  { "variant", cmd_variant },
  { "version", cmd_version },
  { "white", cmd_white },
  { "xboard", cmd_xboard },
  { NULL, NULL }
};

void parse_input(void)
/*************************************************************************
 *
 *  This is the main user command interface driver.
 *
 *************************************************************************/
{
   leaf *ptr; 
   const struct methodtable * meth;
 
   dbg_printf("parse_input() called, inputstr = *%s*\n", inputstr);
   
   split_input();

   for (meth = commands; meth->name != NULL; meth++) {
     if (tokeneq(token[0], meth->name)) {
       meth->method();
       return;
     }
   }

   /* OK, no known command, this should be a move */
   ptr = ValidateMove (token[0]);
   if (ptr != NULL) {
     SANMove (ptr->move, 1);
     MakeMove (board.side, &ptr->move);
     strcpy (Game[GameCnt].SANmv, SANmv);
     printf("%d. ",GameCnt/2+1);
     printf("%s",token[0]);
     if (ofp != stdout) {
       fprintf(ofp,"%d. ",GameCnt/2+1);
       fprintf(ofp,"%s",token[0]);
     }
     putchar('\n');
     fflush(stdout);
     if (ofp != stdout) {
       fputc('\n',ofp);
       fflush(ofp);
     }
     if (!(flags & XBOARD)) ShowBoard (); 
     SET (flags, THINK);
   }
   else {
     /*
      * Must Output Illegal move to prevent Xboard accepting illegal
      * en passant captures and other subtle mistakes
      */
     printf("Illegal move: %s\n",token[0]);
     fflush(stdout);
   }  
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?