예제 #1
0
파일: ucci.cpp 프로젝트: StevenLOL/ChessQ
UcciCommEnum BootLine(void) {
  char szLineStr[LINE_INPUT_MAX_CHAR];
  pipeStd.Open();
  while (!pipeStd.LineInput(szLineStr)) {
    Idle();
  }
  if (StrEqv(szLineStr, "ucci")) {
    return UCCI_COMM_UCCI;
  } else {
    return UCCI_COMM_UNKNOWN;
  }
}
예제 #2
0
파일: ucci.cpp 프로젝트: StevenLOL/ChessQ
UcciCommEnum BootLine(void) {
  char szLineStr[LINE_INPUT_MAX_CHAR];
  pipeStdHandle.Open();
  while (!pipeStdHandle.LineInput(szLineStr)) {
    Idle();
  }
  if (strcmp(szLineStr, "ucci") == 0) {
    return UCCI_COMM_UCCI;
  } else {
    return UCCI_COMM_NONE;
  }
}
예제 #3
0
void engine_open(engine_t * engine){
   int affinity;
    char *my_dir;
    if( (my_dir = _getcwd( NULL, 0 )) == NULL )
        my_fatal("Can't build path: %s\n",strerror(errno));
	if(SetCurrentDirectory(option_get_string("EngineDir"))==0){
		printf("tellusererror Polyglot:EngineDir error: %s\n",option_get_string("EngineDir"));
		fflush(stdout);
		Sleep(50000);
		my_fatal("EngineDir path error: %s\n",option_get_string("EngineDir"));
	}
	pipeEngine.Open(option_get_string("EngineCommand"));
        //play with affinity
#ifndef NO_AFFINITY
    affinity=option_get_int("Affinity");

	if(affinity!=-1){
		my_log("POLYGLOT SetProcess Affinity\n");
		SetProcessAffinityMask(child,affinity); //
	}
#endif
        //lets go back
    SetCurrentDirectory(my_dir);
        // set priority
    if (option_get_bool("UseNice")){
          my_log("POLYGLOT Adjust Engine Piority\n");
		  SetPriorityClass(child, GetWin32Priority(option_get_int("NiceValue")));
    }
}
예제 #4
0
파일: ucci.cpp 프로젝트: StevenLOL/ChessQ
UcciCommEnum BusyLine(UcciCommStruct &UcciComm, bool bDebug) {
  char szLineStr[LINE_INPUT_MAX_CHAR];
  char *lp;
  if (pipeStd.LineInput(szLineStr)) {
    if (bDebug) {
      printf("info busyline [%s]\n", szLineStr);
      fflush(stdout);
    }
    // "BusyLine"只能接收"isready"、"ponderhit"和"stop"这三条指令
    if (false) {
    } else if (StrEqv(szLineStr, "isready")) {
      return UCCI_COMM_ISREADY;
    } else if (StrEqv(szLineStr, "ponderhit draw")) {
      return UCCI_COMM_PONDERHIT_DRAW;
    // 注意:必须首先判断"ponderhit draw",再判断"ponderhit"
    } else if (StrEqv(szLineStr, "ponderhit")) {
      return UCCI_COMM_PONDERHIT;
    } else if (StrEqv(szLineStr, "stop")) {
      return UCCI_COMM_STOP;
    } else if (StrEqv(szLineStr, "quit")) {
      return UCCI_COMM_QUIT;
    } else {
      lp = szLineStr;
      if (StrEqvSkip(lp, "probe ")) {
        return ParsePos(UcciComm, lp) ? UCCI_COMM_PROBE : UCCI_COMM_UNKNOWN;
      } else {
        return UCCI_COMM_UNKNOWN;
      }
    }
  } else {
    return UCCI_COMM_UNKNOWN;
  }
}
예제 #5
0
Boolean peek_engine_get(engine_t * engine, char *szLineStr, int size){
	if (pipeEngine.LineInput(szLineStr)) {
    my_log("Engine->Adapter: %s\n", szLineStr);
    return TRUE;
  } else {
	szLineStr[0]='\0';
    return FALSE;
  }
}
예제 #6
0
파일: ucci.cpp 프로젝트: StevenLOL/ChessQ
UcciCommEnum BusyLine(Bool bDebug) {
  char szLineStr[LINE_INPUT_MAX_CHAR];
  if (pipeStdHandle.LineInput(szLineStr)) {
    if (bDebug) {
      printf("info string %s\n", szLineStr);
      fflush(stdout);
    }
    // "BusyLine"只能接收"isready"、"ponderhit"和"stop"这三条指令
    if (strcmp(szLineStr, "isready") == 0) {
      return UCCI_COMM_ISREADY;
    } else if (strcmp(szLineStr, "ponderhit") == 0) {
      return UCCI_COMM_PONDERHIT;
    } else if (strcmp(szLineStr, "stop") == 0) {
      return UCCI_COMM_STOP;
    } else {
      return UCCI_COMM_NONE;
    }
  } else {
    return UCCI_COMM_NONE;
  }
}
예제 #7
0
void engine_send(engine_t * engine, const char *szFormat, ...) {
  vsprintf(szQueueString + nQueuePtr, szFormat, (va_list) (&szFormat + 1));
  pipeEngine.LineOutput(szQueueString);
  my_log("Adapter->Engine: %s\n", szQueueString);
  nQueuePtr = 0;
}
예제 #8
0
void engine_close(engine_t *engine){
	pipeEngine.Close();
}
예제 #9
0
파일: ucci.cpp 프로젝트: StevenLOL/ChessQ
UcciCommEnum IdleLine(UcciCommStruct &UcciComm, bool bDebug) {
  char szLineStr[LINE_INPUT_MAX_CHAR];
  char *lp;
  int i;
  bool bGoTime;

  while (!pipeStd.LineInput(szLineStr)) {
    Idle();
  }
  lp = szLineStr;
  if (bDebug) {
    printf("info idleline [%s]\n", lp);
    fflush(stdout);
  }
  if (false) {
  // "IdleLine()"是最复杂的UCCI指令解释器,大多数的UCCI指令都由它来解释,包括:

  // 1. "isready"指令
  } else if (StrEqv(lp, "isready")) {
    return UCCI_COMM_ISREADY;

  // 2. "setoption <option> [<arguments>]"指令
  } else if (StrEqvSkip(lp, "setoption ")) {
    if (false) {

    // (1) "batch"选项
    } else if (StrEqvSkip(lp, "batch ")) {
      UcciComm.Option = UCCI_OPTION_BATCH;
      if (StrEqv(lp, "on")) {
        UcciComm.bCheck = true;
      } else if (StrEqv(lp, "true")) {
        UcciComm.bCheck = true;
      } else {
        UcciComm.bCheck = false;
      } // 由于"batch"选项默认是关闭的,所以只有设定"on"或"true"时才打开,下同

    // (2) "debug"选项
    } else if (StrEqvSkip(lp, "debug ")) {
      UcciComm.Option = UCCI_OPTION_DEBUG;
      if (StrEqv(lp, "on")) {
        UcciComm.bCheck = true;
      } else if (StrEqv(lp, "true")) {
        UcciComm.bCheck = true;
      } else {
        UcciComm.bCheck = false;
      }

    // (3) "ponder"选项
    } else if (StrEqvSkip(lp, "ponder ")) {
      UcciComm.Option = UCCI_OPTION_PONDER;
      if (StrEqv(lp, "on")) {
        UcciComm.bCheck = true;
      } else if (StrEqv(lp, "true")) {
        UcciComm.bCheck = true;
      } else {
        UcciComm.bCheck = false;
      }

    // (4) "usehash"选项
    } else if (StrEqvSkip(lp, "usehash ")) {
      UcciComm.Option = UCCI_OPTION_USEHASH;
      if (StrEqv(lp, "off")) {
        UcciComm.bCheck = false;
      } else if (StrEqv(lp, "false")) {
        UcciComm.bCheck = false;
      } else {
        UcciComm.bCheck = true;
      }

    // (5) "usebook"选项
    } else if (StrEqvSkip(lp, "usebook ")) {
      UcciComm.Option = UCCI_OPTION_USEBOOK;
      if (StrEqv(lp, "off")) {
        UcciComm.bCheck = false;
      } else if (StrEqv(lp, "false")) {
        UcciComm.bCheck = false;
      } else {
        UcciComm.bCheck = true;
      }

    // (6) "useegtb"选项
    } else if (StrEqvSkip(lp, "useegtb ")) {
      UcciComm.Option = UCCI_OPTION_USEEGTB;
      if (StrEqv(lp, "off")) {
        UcciComm.bCheck = false;
      } else if (StrEqv(lp, "false")) {
        UcciComm.bCheck = false;
      } else {
        UcciComm.bCheck = true;
      }

    // (7) "bookfiles"选项
    } else if (StrEqvSkip(lp, "bookfiles ")) {
      UcciComm.Option = UCCI_OPTION_BOOKFILES;
      UcciComm.szOption = lp;

    // (8) "egtbpaths"选项
    } else if (StrEqvSkip(lp, "egtbpaths ")) {
      UcciComm.Option = UCCI_OPTION_EGTBPATHS;
      UcciComm.szOption = lp;

    // (9) "evalapi"选项,3.3以后不再支持

    // (10) "hashsize"选项
    } else if (StrEqvSkip(lp, "hashsize ")) {
      UcciComm.Option = UCCI_OPTION_HASHSIZE;
      UcciComm.nSpin = Str2Digit(lp, 0, 1024);

    // (11) "threads"选项
    } else if (StrEqvSkip(lp, "threads ")) {
      UcciComm.Option = UCCI_OPTION_THREADS;
      UcciComm.nSpin = Str2Digit(lp, 0, 32);

    // (12) "promotion"选项
    } else if (StrEqvSkip(lp, "promotion ")) {
      UcciComm.Option = UCCI_OPTION_PROMOTION;
      if (StrEqv(lp, "on")) {
        UcciComm.bCheck = true;
      } else if (StrEqv(lp, "true")) {
        UcciComm.bCheck = true;
      } else {
        UcciComm.bCheck = false;
      }

    // (13) "idle"选项
    } else if (StrEqvSkip(lp, "idle ")) {
      UcciComm.Option = UCCI_OPTION_IDLE;
      if (false) {
      } else if (StrEqv(lp, "none")) {
        UcciComm.Grade = UCCI_GRADE_NONE;
      } else if (StrEqv(lp, "small")) {
        UcciComm.Grade = UCCI_GRADE_SMALL;
      } else if (StrEqv(lp, "medium")) {
        UcciComm.Grade = UCCI_GRADE_MEDIUM;
      } else if (StrEqv(lp, "large")) {
        UcciComm.Grade = UCCI_GRADE_LARGE;
      } else {
        UcciComm.Grade = UCCI_GRADE_NONE;
      }

    // (14) "pruning"选项
    } else if (StrEqvSkip(lp, "pruning ")) {
      UcciComm.Option = UCCI_OPTION_PRUNING;
      if (false) {
      } else if (StrEqv(lp, "none")) {
        UcciComm.Grade = UCCI_GRADE_NONE;
      } else if (StrEqv(lp, "small")) {
        UcciComm.Grade = UCCI_GRADE_SMALL;
      } else if (StrEqv(lp, "medium")) {
        UcciComm.Grade = UCCI_GRADE_MEDIUM;
      } else if (StrEqv(lp, "large")) {
        UcciComm.Grade = UCCI_GRADE_LARGE;
      } else {
        UcciComm.Grade = UCCI_GRADE_LARGE;
      }

    // (15) "knowledge"选项
    } else if (StrEqvSkip(lp, "knowledge ")) {
      UcciComm.Option = UCCI_OPTION_KNOWLEDGE;
      if (false) {
      } else if (StrEqv(lp, "none")) {
        UcciComm.Grade = UCCI_GRADE_NONE;
      } else if (StrEqv(lp, "small")) {
        UcciComm.Grade = UCCI_GRADE_SMALL;
      } else if (StrEqv(lp, "medium")) {
        UcciComm.Grade = UCCI_GRADE_MEDIUM;
      } else if (StrEqv(lp, "large")) {
        UcciComm.Grade = UCCI_GRADE_LARGE;
      } else {
        UcciComm.Grade = UCCI_GRADE_LARGE;
      }

    // (16) "randomness"选项
    } else if (StrEqvSkip(lp, "randomness ")) {
      UcciComm.Option = UCCI_OPTION_RANDOMNESS;
      if (false) {
      } else if (StrEqv(lp, "none")) {
        UcciComm.Grade = UCCI_GRADE_NONE;
      } else if (StrEqv(lp, "tiny")) {
        UcciComm.Grade = UCCI_GRADE_TINY;
      } else if (StrEqv(lp, "small")) {
        UcciComm.Grade = UCCI_GRADE_SMALL;
      } else if (StrEqv(lp, "medium")) {
        UcciComm.Grade = UCCI_GRADE_MEDIUM;
      } else if (StrEqv(lp, "large")) {
        UcciComm.Grade = UCCI_GRADE_LARGE;
      } else if (StrEqv(lp, "huge")) {
        UcciComm.Grade = UCCI_GRADE_HUGE;
      } else {
        UcciComm.Grade = UCCI_GRADE_NONE;
      }

    // (17) "style"选项
    } else if (StrEqvSkip(lp, "style ")) {
      UcciComm.Option = UCCI_OPTION_STYLE;
      if (false) {
      } else if (StrEqv(lp, "solid")) {
        UcciComm.Style = UCCI_STYLE_SOLID;
      } else if (StrEqv(lp, "normal")) {
        UcciComm.Style = UCCI_STYLE_NORMAL;
      } else if (StrEqv(lp, "risky")) {
        UcciComm.Style = UCCI_STYLE_RISKY;
      } else {
        UcciComm.Style = UCCI_STYLE_NORMAL;
      }

    // (18) "newgame"选项
    } else if (StrEqv(lp, "newgame")) {
      UcciComm.Option = UCCI_OPTION_NEWGAME;

    // (19) 无法识别的选项,有扩充的余地
    } else {
      UcciComm.Option = UCCI_OPTION_UNKNOWN;
    }
    return UCCI_COMM_SETOPTION;

  // 3. "position {<special_position> | fen <fen_string>} [moves <move_list>]"指令
  } else if (StrEqvSkip(lp, "position ")) {
    return ParsePos(UcciComm, lp) ? UCCI_COMM_POSITION : UCCI_COMM_UNKNOWN;

  // 4. "banmoves <move_list>"指令,处理起来和"position ... moves ..."是一样的
  } else if (StrEqvSkip(lp, "banmoves ")) {
    UcciComm.nBanMoveNum = MIN((int) (strlen(lp) + 1) / 5, MAX_MOVE_NUM);
    for (i = 0; i < UcciComm.nBanMoveNum; i ++) {
      dwCoordList[i] = *(uint32_t *) lp;
      lp += sizeof(uint32_t) + 1;
    }
    UcciComm.lpdwBanMovesCoord = dwCoordList;
    return UCCI_COMM_BANMOVES;

  // 5. "go [ponder | draw] <mode>"指令
  } else if (StrEqvSkip(lp, "go ")) {
    UcciComm.bPonder = UcciComm.bDraw = false;
    // 首先判断到底是"go"、"go ponder"还是"go draw"
    if (StrEqvSkip(lp, "ponder ")) {
      UcciComm.bPonder = true;
    } else if (StrEqvSkip(lp, "draw ")) {
      UcciComm.bDraw = true;
    }
    // 然后判断思考模式
    bGoTime = false;
    if (false) {
    } else if (StrEqvSkip(lp, "depth ")) {
      UcciComm.Go = UCCI_GO_DEPTH;
      UcciComm.nDepth = Str2Digit(lp, 0, UCCI_MAX_DEPTH);
    } else if (StrEqvSkip(lp, "nodes ")) {
      UcciComm.Go = UCCI_GO_NODES;
      UcciComm.nDepth = Str2Digit(lp, 0, 2000000000);
    } else if (StrEqvSkip(lp, "time ")) {
      UcciComm.nTime = Str2Digit(lp, 0, 2000000000);
      bGoTime = true;
    // 如果没有说明是固定深度还是设定时限,就固定深度为"UCCI_MAX_DEPTH"
    } else {
      UcciComm.Go = UCCI_GO_DEPTH;
      UcciComm.nDepth = UCCI_MAX_DEPTH;
    }
    // 如果是设定时限,就要判断是时段制还是加时制
    if (bGoTime) {
      if (false) {
      } else if (StrScanSkip(lp, " movestogo ")) {
        UcciComm.Go = UCCI_GO_TIME_MOVESTOGO;
        UcciComm.nMovesToGo = Str2Digit(lp, 1, 999);
      } else if (StrScanSkip(lp, " increment ")) {
        UcciComm.Go = UCCI_GO_TIME_INCREMENT;
        UcciComm.nIncrement = Str2Digit(lp, 0, 999999);
      // 如果没有说明是时段制还是加时制,就设定为步数是1的时段制
      } else {
        UcciComm.Go = UCCI_GO_TIME_MOVESTOGO;
        UcciComm.nMovesToGo = 1;
      }
    }
    return UCCI_COMM_GO;

  // 6. "stop"指令
  } else if (StrEqv(lp, "stop")) {
    return UCCI_COMM_STOP;

  // 7. "probe {<special_position> | fen <fen_string>} [moves <move_list>]"指令
  } else if (StrEqvSkip(lp, "probe ")) {
    return ParsePos(UcciComm, lp) ? UCCI_COMM_PROBE : UCCI_COMM_UNKNOWN;

  // 8. "quit"指令
  } else if (StrEqv(lp, "quit")) {
    return UCCI_COMM_QUIT;

  // 9. 无法识别的指令
  } else {
    return UCCI_COMM_UNKNOWN;
  }
}
예제 #10
0
파일: ucci.cpp 프로젝트: StevenLOL/ChessQ
UcciCommEnum IdleLine(UcciCommStruct &ucsCommand, Bool bDebug) {
  char szLineStr[LINE_INPUT_MAX_CHAR];
  int i;
  char *lpLineChar;
  UcciCommEnum uceReturnValue;

  while (!pipeStdHandle.LineInput(szLineStr)) {
    Idle();
  }
  lpLineChar = szLineStr;
  if (bDebug) {
    printf("info string %s\n", lpLineChar);
    fflush(stdout);
  }
  // "IdleLine()"是最复杂的UCCI指令解释器,大多数的UCCI指令都由它来解释,包括:

  // 1. "isready"指令
  if (strcmp(lpLineChar, "isready") == 0) {
    return UCCI_COMM_ISREADY;

  // 2. "setoption <option> [<arguments>]"指令
  } else if (strncmp(lpLineChar, "setoption ", 10) == 0) {
    lpLineChar += 10;

    // (i) "batch"选项
    if (strncmp(lpLineChar, "batch ", 6) == 0) {
      lpLineChar += 6;
      ucsCommand.Option.uoType = UCCI_OPTION_BATCH;
      if (strncmp(lpLineChar, "on", 2) == 0) {
        ucsCommand.Option.Value.bCheck = TRUE;
      } else if (strncmp(lpLineChar, "true", 4) == 0) {
        ucsCommand.Option.Value.bCheck = TRUE;
      } else {
        ucsCommand.Option.Value.bCheck = FALSE;
      } // 由于"batch"选项默认是关闭的,所以只有设定"on"或"true"时才打开,下同

    // (ii) "debug"选项
    } else if (strncmp(lpLineChar, "debug ", 6) == 0) {
      lpLineChar += 6;
      ucsCommand.Option.uoType = UCCI_OPTION_DEBUG;
      if (strncmp(lpLineChar, "on", 2) == 0) {
        ucsCommand.Option.Value.bCheck = TRUE;
      } else if (strncmp(lpLineChar, "true", 4) == 0) {
        ucsCommand.Option.Value.bCheck = TRUE;
      } else {
        ucsCommand.Option.Value.bCheck = FALSE;
      }

    // (iii) "usemillisec"选项
    } else if (strncmp(lpLineChar, "usemillisec ", 12) == 0) {
      lpLineChar += 12;
      ucsCommand.Option.uoType = UCCI_OPTION_USEMILLISEC;
      if (strncmp(lpLineChar, "on", 2) == 0) {
        ucsCommand.Option.Value.bCheck = TRUE;
      } else if (strncmp(lpLineChar, "true", 4) == 0) {
        ucsCommand.Option.Value.bCheck = TRUE;
      } else {
        ucsCommand.Option.Value.bCheck = FALSE;
      }

    // (iv) "bookfiles"选项
    } else if (strncmp(lpLineChar, "bookfiles ", 10) == 0) {
      ucsCommand.Option.uoType = UCCI_OPTION_BOOKFILES;
      ucsCommand.Option.Value.szString = lpLineChar + 10;

    // (v) "hashsize"选项
    } else if (strncmp(lpLineChar, "hashsize ", 9) == 0) {
      lpLineChar += 9;
      ucsCommand.Option.uoType = UCCI_OPTION_HASHSIZE;
      ucsCommand.Option.Value.nSpin = ReadDigit(lpLineChar, 1024);

    // (vi) "threads"选项
    } else if (strncmp(lpLineChar, "threads ", 8) == 0) {
      lpLineChar += 8;
      ucsCommand.Option.uoType = UCCI_OPTION_THREADS;
      ucsCommand.Option.Value.nSpin = ReadDigit(lpLineChar, 32);

    // (vii) "drawmoves"选项
    } else if (strncmp(lpLineChar, "drawmoves ", 10) == 0) {
      lpLineChar += 10;
      ucsCommand.Option.uoType = UCCI_OPTION_DRAWMOVES;
      ucsCommand.Option.Value.nSpin = ReadDigit(lpLineChar, 200);

    // (viii) "repetition"选项
    } else if (strncmp(lpLineChar, "repetition ", 11) == 0) {
      lpLineChar += 11;
      ucsCommand.Option.uoType = UCCI_OPTION_REPETITION;
      if (strncmp(lpLineChar, "alwaysdraw", 10) == 0) {
        ucsCommand.Option.Value.urRepet = UCCI_REPET_ALWAYSDRAW;
      } else if (strncmp(lpLineChar, "checkban", 8) == 0) {
        ucsCommand.Option.Value.urRepet = UCCI_REPET_CHECKBAN;
      } else if (strncmp(lpLineChar, "asianrule", 9) == 0) {
        ucsCommand.Option.Value.urRepet = UCCI_REPET_ASIANRULE;
      } else if (strncmp(lpLineChar, "chineserule", 11) == 0) {
        ucsCommand.Option.Value.urRepet = UCCI_REPET_CHINESERULE;
      } else {
        ucsCommand.Option.Value.urRepet = UCCI_REPET_CHINESERULE;
      }

    // (ix) "pruning"选项
    } else if (strncmp(lpLineChar, "pruning ", 8) == 0) {
      lpLineChar += 8;
      ucsCommand.Option.uoType = UCCI_OPTION_PRUNING;
      if (strncmp(lpLineChar, "none", 4) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_NONE;
      } else if (strncmp(lpLineChar, "small", 5) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_SMALL;
      } else if (strncmp(lpLineChar, "medium", 6) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_MEDIUM;
      } else if (strncmp(lpLineChar, "large", 5) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_LARGE;
      } else {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_LARGE;
      }

    // (x) "knowledge"选项
    } else if (strncmp(lpLineChar, "knowledge ", 10) == 0) {
      lpLineChar += 10;
      ucsCommand.Option.uoType = UCCI_OPTION_KNOWLEDGE;
      if (strncmp(lpLineChar, "none", 4) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_NONE;
      } else if (strncmp(lpLineChar, "small", 5) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_SMALL;
      } else if (strncmp(lpLineChar, "medium", 6) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_MEDIUM;
      } else if (strncmp(lpLineChar, "large", 5) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_LARGE;
      } else {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_LARGE;
      }

    // (xi) "selectivity"选项
    } else if (strncmp(lpLineChar, "selectivity ", 12) == 0) {
      lpLineChar += 12;
      ucsCommand.Option.uoType = UCCI_OPTION_SELECTIVITY;
      if (strncmp(lpLineChar, "none", 4) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_NONE;
      } else if (strncmp(lpLineChar, "small", 5) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_SMALL;
      } else if (strncmp(lpLineChar, "medium", 6) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_MEDIUM;
      } else if (strncmp(lpLineChar, "large", 5) == 0) {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_LARGE;
      } else {
        ucsCommand.Option.Value.ugGrade = UCCI_GRADE_NONE;
      }

    // (xii) "style"选项
    } else if (strncmp(lpLineChar, "style ", 6) == 0) {
      lpLineChar += 6;
      ucsCommand.Option.uoType = UCCI_OPTION_STYLE;
      if (strncmp(lpLineChar, "solid", 5) == 0) {
        ucsCommand.Option.Value.usStyle = UCCI_STYLE_SOLID;
      } else if (strncmp(lpLineChar, "normal", 6) == 0) {
        ucsCommand.Option.Value.usStyle = UCCI_STYLE_NORMAL;
      } else if (strncmp(lpLineChar, "risky", 5) == 0) {
        ucsCommand.Option.Value.usStyle = UCCI_STYLE_RISKY;
      } else {
        ucsCommand.Option.Value.usStyle = UCCI_STYLE_NORMAL;
      }

    // (xiii) "loadbook"选项
    } else if (strncmp(lpLineChar, "loadbook", 8) == 0) {
      ucsCommand.Option.uoType = UCCI_OPTION_LOADBOOK;

    // (xiv) 无法识别的选项,有扩充的余地
    } else {
      ucsCommand.Option.uoType = UCCI_OPTION_NONE;
    }
    return UCCI_COMM_SETOPTION;

  // 3. "position {<special_position> | fen <fen_string>} [moves <move_list>]"指令
  } else if (strncmp(lpLineChar, "position ", 9) == 0) {            
    lpLineChar += 9;
    // 首先判断是否是特殊局面(这里规定了5种),是特殊局面就直接转换成对应的FEN串
    if (strncmp(lpLineChar, "startpos", 8) == 0) {
      ucsCommand.Position.szFenStr = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1";
    } else if (strncmp(lpLineChar, "midgamepos", 10) == 0) {
      ucsCommand.Position.szFenStr = "2bakab1r/6r2/1cn4c1/p1p1p3p/9/2P3p2/PC2P1n1P/2N1B1NC1/R4R3/3AKAB2 w - - 0 1";
    } else if (strncmp(lpLineChar, "checkmatepos", 12) == 0) {
      ucsCommand.Position.szFenStr = "4kar2/4a2rn/4bc3/RN1c5/2bC5/9/4p4/9/4p4/3p1K3 w - - 0 1";
    } else if (strncmp(lpLineChar, "zugzwangpos", 11) == 0) {
      ucsCommand.Position.szFenStr = "3k5/4PP3/4r4/3P5/9/9/9/9/9/5K3 w - - 0 1";
    } else if (strncmp(lpLineChar, "endgamepos", 10) == 0) {
      ucsCommand.Position.szFenStr = "4k4/4a4/4P4/9/9/9/9/4B4/9/4K4 w - - 0 1";
    // 然后判断是否指定了FEN串
    } else if (strncmp(lpLineChar, "fen ", 4) == 0) {
      ucsCommand.Position.szFenStr = lpLineChar + 4;
    // 如果两者都不是,就立即返回
    } else {
      return UCCI_COMM_NONE;
    }
    // 然后寻找是否指定了后续着法,即是否有"moves"关键字
    lpLineChar = strstr(lpLineChar, " moves ");
    ucsCommand.Position.nMoveNum = 0;
    if (lpLineChar != NULL) {
      lpLineChar += 7;
      ucsCommand.Position.nMoveNum = ((strlen(lpLineChar) + 1) / 5); // 提示:"moves"后面的每个着法都是4个字符和1个空格
      for (i = 0; i < ucsCommand.Position.nMoveNum; i ++) {
        dwCoordList[i] = *(long *) lpLineChar; // 4个字符可转换为一个"long",存储和处理起来方便
        lpLineChar += 5;
      }
      ucsCommand.Position.lpdwCoordList = dwCoordList;
    }
    return UCCI_COMM_POSITION;

  // 4. "banmoves <move_list>"指令,处理起来和"position ... moves ..."是一样的
  } else if (strncmp(lpLineChar, "banmoves ", 9) == 0) {
    lpLineChar += 9;
    ucsCommand.BanMoves.nMoveNum = ((strlen(lpLineChar) + 1) / 5);
    for (i = 0; i < ucsCommand.Position.nMoveNum; i ++) {
      dwCoordList[i] = *(long *) lpLineChar;
      lpLineChar += 5;
    }
    ucsCommand.BanMoves.lpdwCoordList = dwCoordList;
    return UCCI_COMM_BANMOVES;

  // 5. "go [ponder] {infinite | depth <depth> | time <time> [movestogo <moves_to_go> | increment <inc_time>]}"指令
  } else if (strncmp(lpLineChar, "go ", 3) == 0) {
    lpLineChar += 3;
    // 首先判断到底是"go"还是"go ponder",因为两者解释成不同的指令
    if (strncmp(lpLineChar, "ponder ", 7) == 0) {
      lpLineChar += 7;
      uceReturnValue = UCCI_COMM_GOPONDER;
    } else {
      uceReturnValue = UCCI_COMM_GO;
    }
    // 然后判断到底是固定深度还是设定时限
    if (strncmp(lpLineChar, "time ", 5) == 0) {
      lpLineChar += 5;
      ucsCommand.Search.DepthTime.nTime = ReadDigit(lpLineChar, 36000);
      // 如果是设定时限,就要判断是时段制还是加时制
      if (strncmp(lpLineChar, " movestogo ", 11) == 0) {
        lpLineChar += 11;
        ucsCommand.Search.utMode = UCCI_TIME_MOVE;
        ucsCommand.Search.TimeMode.nMovesToGo = ReadDigit(lpLineChar, 100);
        if (ucsCommand.Search.TimeMode.nMovesToGo < 1) {
          ucsCommand.Search.TimeMode.nMovesToGo = 1;
        }
      } else if (strncmp(lpLineChar, " increment ", 11) == 0) {
        lpLineChar += 11;
        ucsCommand.Search.utMode = UCCI_TIME_INC;
        ucsCommand.Search.TimeMode.nIncrement = ReadDigit(lpLineChar, 600);
      // 如果没有说明是时段制还是加时制,就设定为步数是1的时段制
      } else {
        ucsCommand.Search.utMode = UCCI_TIME_MOVE;
        ucsCommand.Search.TimeMode.nMovesToGo = 1;
      }
    } else if (strncmp(lpLineChar, "depth ", 6) == 0) {
      lpLineChar += 6;
      ucsCommand.Search.utMode = UCCI_TIME_DEPTH;
      ucsCommand.Search.DepthTime.nDepth = ReadDigit(lpLineChar, UCCI_MAX_DEPTH - 1);
    // 如果没有说明是固定深度还是设定时限,就固定深度为"UCCI_MAX_DEPTH"
    } else {
      ucsCommand.Search.utMode = UCCI_TIME_DEPTH;
      ucsCommand.Search.DepthTime.nDepth = UCCI_MAX_DEPTH - 1;
    }
    return uceReturnValue;

  // 5. "stop"指令
  } else if (strcmp(lpLineChar, "stop") == 0) {
    return UCCI_COMM_STOP;

  // 6. "quit"指令
  } else if (strcmp(lpLineChar, "quit") == 0) {
    return UCCI_COMM_QUIT;

  // 7. 无法识别的指令
  } else {
    return UCCI_COMM_NONE;
  }
}