Esempio n. 1
0
int main(void) {
    int i;
    bool bPonderTime;
    UcciCommStruct UcciComm;
    const char *szEngineName;
    PositionStruct posProbe;
#ifdef _WIN32
    HMODULE hModule;
#else
    void *hModule;
#endif

    int mv, stat;
    char fen[1024];

    /* disable stdio buffering */
    if (setvbuf(stdin, NULL, _IONBF, 0) != 0)
        perror("setvbuf");
    if (setvbuf(stdout, NULL, _IONBF, 0) != 0)
        perror("setvbuf");

    // myfp = fopen("test", "w+");
    // fputs("test\n", myfp);

    xb_mv_left = 40;
    xb_mv_ctrl = 40;
    xb_tm_left = 30000;
    xb_tm_ctrl = 30000;
    xb_tm_incr = 0;
    xb_post = 0;
    xb_ponder = 0;
    xb_depth = UCCI_MAX_DEPTH;
    xb_force = 0;
    Search.nHashSize = 4;
    Search.nRandom = 0;
    Search.nRandomSave = 2;

    /* if not working with autotools */
#ifndef PKGDATADIR
#define PKGDATADIR "."
#endif

    LocatePath(Search.szBookFile, PKGDATADIR "/book.dat");
    //LocatePath(Search.szBookFile, "book.dat");
    LocatePath(Search.szLibEvalFile, cszLibEvalFile);
    hModule = LoadEvalApi(Search.szLibEvalFile);

    bPonderTime = false;
    PreGenInit();
    NewHash(24); // 24=16MB, 25=32MB, 26=64MB, ...
    Search.pos.FromFen(cszStartFen);
    Search.pos.nDistance = 0;
    Search.PreEvaluate(&Search.pos, &PreEval);
    Search.nBanMoves = 0;
    Search.bQuit = Search.bBatch = Search.bDebug = Search.bAlwaysCheck = false;
    Search.bUseHash = Search.bUseBook = Search.bNullMove = Search.bKnowledge = true;
    Search.bIdle = false;
    Search.nCountMask = INTERRUPT_COUNT - 1;
    Search.nRandomMask = 0;
    Search.rc4Random.InitRand();

    szEngineName = Search.GetEngineName();
    if (szEngineName == NULL) {
        PrintLn("id name ElephantEye");
    } else {
        printf("id name %s / ElephantEye\n", szEngineName);
        fflush(stdout);
    }
    PrintLn("id version 3.15");
    PrintLn("id copyright 2004-2008 www.elephantbase.net");
    PrintLn("id author Morning Yellow");
    PrintLn("id user ElephantEye Test Team");

    while (BootLine() != UCCI_COMM_XBOARD);
    // PrintLn("option usemillisec type check default true");
    // PrintLn("option promotion type check default false");
    // PrintLn("option batch type check default false");
    // PrintLn("option debug type check default false");
    // PrintLn("option ponder type check default false");
    // PrintLn("option alwayscheck type check default false");
    // PrintLn("option usehash type check default true");
    // PrintLn("option usebook type check default true");
    // printf("option bookfiles type string default %s\n", Search.szBookFile);
    // fflush(stdout);
    // printf("option evalapi type string default %s\n", szLibEvalFile);
    // fflush(stdout);
    // PrintLn("option hashsize type spin min 16 max 1024 default 16");
    // PrintLn("option idle type combo var none var small var medium var large default none");
    // PrintLn("option pruning type combo var none var small var medium var large default large");
    // PrintLn("option knowledge type combo var none var small var medium var large default large");
    // PrintLn("option randomness type combo var none var small var medium var large default none");
    // PrintLn("option newgame type button");
    // PrintLn("ucciok");

    // 以下是接收指令和提供对策的循环体
    while (!Search.bQuit) {
        switch (IdleLine(UcciComm, Search.bDebug)) {
        case UCCI_COMM_STOP:
            PrintLn("nobestmove");
            break;
        case UCCI_COMM_POSITION:
            BuildPos(Search.pos, UcciComm);
            Search.pos.nDistance = 0;
            Search.PreEvaluate(&Search.pos, &PreEval);
            Search.nBanMoves = 0;
            hint_mv = 0;
            break;
        case UCCI_COMM_NEW:
            Search.pos.FromFen(cszStartFen);
            Search.pos.nDistance = 0;
            Search.PreEvaluate(&Search.pos, &PreEval);
            Search.nBanMoves = 0;
            xb_force = 0;
            xb_tm_left = xb_tm_ctrl;
            xb_mv_left = xb_mv_ctrl;
            xb_depth = UCCI_MAX_DEPTH;
            hint_mv = 0;
            break;
        case UCCI_COMM_BANMOVES:
            Search.nBanMoves = UcciComm.nBanMoveNum;
            for (i = 0; i < UcciComm.nBanMoveNum; i ++) {
                Search.wmvBanList[i] = COORD_MOVE(UcciComm.lpdwBanMovesCoord[i]);
            }
            break;
        case UCCI_COMM_SETOPTION:
            switch (UcciComm.Option) {
            case UCCI_OPTION_PROMOTION:
                PreEval.bPromotion = UcciComm.bCheck;
                break;
            case UCCI_OPTION_ALWAYSCHECK:
                Search.bAlwaysCheck = UcciComm.bCheck;
                break;
            case UCCI_OPTION_USEHASH:
                Search.bUseHash = UcciComm.bCheck;
                break;
            case UCCI_OPTION_USEBOOK:
                Search.bUseBook = UcciComm.bCheck;
                break;
            case UCCI_OPTION_BOOKFILES:
                if (AbsolutePath(UcciComm.szOption)) {
                    strcpy(Search.szBookFile, UcciComm.szOption);
                } else {
                    LocatePath(Search.szBookFile, UcciComm.szOption);
                }
                break;
            case UCCI_OPTION_EVALAPI:
                if (AbsolutePath(UcciComm.szOption)) {
                    strcpy(Search.szLibEvalFile, UcciComm.szOption);
                } else {
                    LocatePath(Search.szLibEvalFile, UcciComm.szOption);
                }
                FreeEvalApi(hModule);
                hModule = LoadEvalApi(Search.szLibEvalFile);
                break;
            case UCCI_OPTION_HASHSIZE:
                DelHash();
                Search.nHashSize = UcciComm.nSpin;
                NewHash(UcciComm.nSpin + 20);
                break;
            case UCCI_OPTION_PRUNING:
                Search.bNullMove = UcciComm.bCheck;
                break;
            case UCCI_OPTION_KNOWLEDGE:
                Search.bKnowledge = UcciComm.bCheck;
                break;
            case UCCI_OPTION_RANDOMNESS:
                Search.nRandom = UcciComm.nSpin;
                if (UcciComm.nSpin)
                    Search.nRandomSave = UcciComm.nSpin;
                Search.nRandomMask = (1 << Search.nRandom) - 1;
                break;
            default:
                break;
            }
            break;
        case UCCI_COMM_GO:
            // Search.bPonder = UcciComm.bPonder;
            // Search.bDraw = UcciComm.bDraw;
            // switch (UcciComm.Go) {
            // case UCCI_GO_DEPTH:
            //   Search.nGoMode = GO_MODE_INFINITY;
            //   Search.nNodes = 0;
            //   SearchMain(UcciComm.nDepth);
            //   break;
            // case UCCI_GO_NODES:
            //   Search.nGoMode = GO_MODE_NODES;
            //   Search.nNodes = UcciComm.nNodes;
            //   SearchMain(UCCI_MAX_DEPTH);
            //   break;
            // case UCCI_GO_TIME_MOVESTOGO:
            // case UCCI_GO_TIME_INCREMENT:
            //   Search.nGoMode = GO_MODE_TIMER;
            //   if (UcciComm.Go == UCCI_GO_TIME_MOVESTOGO) {
            //     // 对于时段制,把剩余时间平均分配到每一步,作为适当时限。
            //     // 剩余步数从1到5,最大时限依次是剩余时间的100%、90%、80%、70%和60%,5以上都是50%
            //     Search.nProperTimer = UcciComm.nTime / UcciComm.nMovesToGo;
            //     Search.nMaxTimer = UcciComm.nTime * MAX(5, 11 - UcciComm.nMovesToGo) / 10;
            //   } else {
            //     // 对于加时制,假设棋局会在20回合内结束,算出平均每一步的适当时限,最大时限是剩余时间的一半
            //     Search.nProperTimer = UcciComm.nTime / 20 + UcciComm.nIncrement;
            //     Search.nMaxTimer = UcciComm.nTime / 2;
            //   }
            //   // 如果是后台思考的时间分配策略,那么适当时限设为原来的1.25倍
            //   Search.nProperTimer += (bPonderTime ? Search.nProperTimer / 4 : 0);
            //   Search.nMaxTimer = MIN(Search.nMaxTimer, Search.nProperTimer * 10);
            //   SearchMain(UCCI_MAX_DEPTH);
            //   break;
            // default:
            //   break;
            // }
            xb_force = 0;
            Search.nGoMode = GO_MODE_TIMER;
            prepare_clock();
            SearchMain(xb_depth);
            update_clock();
            break;
        case UCCI_COMM_PROBE:
            BuildPos(posProbe, UcciComm);
            if (!PopHash(posProbe)) {
                PopLeaf(posProbe);
            }
            break;
        case UCCI_COMM_QUIT:
            Search.bQuit = true;
            break;
        case UCCI_COMM_UNDO:
            if (Search.pos.nDistance >= 1)
                Search.pos.UndoMakeMove();
            hint_mv = 0;
            break;
        case UCCI_COMM_REMOVE:
            if (Search.pos.nDistance >= 2) {
                Search.pos.UndoMakeMove();
                Search.pos.UndoMakeMove();
            }
            hint_mv = 0;
            break;
        case UCCI_COMM_USERMOVE:
            mv = COORD_MOVE(UcciComm.dwMoveCoord);
            TryMove(Search.pos, stat, mv);
            switch (stat) {
            case MOVE_ILLEGAL:
                printf("Illegal move: %.4s\n", (char *)&UcciComm.dwMoveCoord);
                break;
            case MOVE_INCHECK:
                printf("Illegal move (in check): %.4s\n", (char *)&UcciComm.dwMoveCoord);
                break;
            case MOVE_DRAW:
                puts("1/2-1/2 {Draw by rule}\n");
                break;
            case MOVE_PERPETUAL_LOSS:
                printf("Illegal move (perpetual attack): %.4s\n", (char *)&UcciComm.dwMoveCoord);
                break;
            case MOVE_PERPETUAL:
                puts("1/2-1/2 {Draw by repetition}\n");
                break;
            case MOVE_MATE:
                if (Search.pos.sdPlayer == 0)
                    puts("1-0 {checkmate or stalemate}\n");
                else
                    puts("0-1 {checkmate or stalemate}\n");
                break;
            default:
                Search.pos.MakeMove(mv);
                if (!xb_force) {
                    prepare_clock();
                    SearchMain(xb_depth);
                    update_clock();
                }
                break;
            }
            break;
        default:
            break;
        }
    }
    DelHash();
    FreeEvalApi(hModule);
    return 0;
}
Esempio n. 2
0
int start(void) {
  int i;
  bool bPonderTime;
  UcciCommStruct UcciComm;
  char szLibEvalFile[1024];
  const char *szEngineName;
  PositionStruct posProbe;
#ifdef _WIN32
  HMODULE hModule;  
#else
  void *hModule;
#endif

  if (BootLine() != UCCI_COMM_UCCI) {
    return 0;
  }
  LocatePath(Search.szBookFile, "BOOK.DAT");
  LocatePath(szLibEvalFile, cszLibEvalFile);
  hModule = LoadEvalApi(szLibEvalFile);
  bPonderTime = false;
  PreGenInit();
  NewHash(24); // 24=16MB, 25=32MB, 26=64MB, ...
  Search.pos.FromFen("rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR b - - 0 1");
  Search.pos.nDistance = 0;
  Search.PreEvaluate(&Search.pos, &PreEval);
  Search.nBanMoves = 0;
  Search.bQuit = Search.bBatch = Search.bDebug = Search.bAlwaysCheck = false;
  Search.bUseHash = Search.bUseBook = Search.bNullMove = Search.bKnowledge = true;
  Search.bIdle = false;
  Search.nCountMask = INTERRUPT_COUNT - 1;
  Search.nRandomMask = 0;
  Search.rc4Random.InitRand();
  szEngineName = Search.GetEngineName();
  if (szEngineName == NULL) {
    PrintLn("#id name ElephantEye");
  } else {
	  //printf("id name %s / ElephantEye\n", szEngineName);
	  //fflush(stdout);
	  pipeOutputWrite("id name %s / ElephantEye\n", szEngineName);
  }
  PrintLn("#id version 3.15");
  PrintLn("#id copyright 2004-2008 www.elephantbase.net");
  PrintLn("#id author Morning Yellow");
  PrintLn("#id user ElephantEye Test Team");
  PrintLn("#option usemillisec type check default true");
  PrintLn("#option promotion type check default false");
  PrintLn("#option batch type check default false");
  PrintLn("#option debug type check default false");
  PrintLn("#option ponder type check default false");
  PrintLn("#option alwayscheck type check default false");
  PrintLn("#option usehash type check default true");
  PrintLn("#option usebook type check default true");
  //printf("option bookfiles type string default %s\n", Search.szBookFile);
  //fflush(stdout);
  pipeOutputWrite("#option bookfiles type string default %s\n", Search.szBookFile);
  //printf("option evalapi type string default %s\n", szLibEvalFile);
  //fflush(stdout);
  pipeOutputWrite("#option evalapi type string default %s\n", szLibEvalFile);
  PrintLn("#option hashsize type spin min 16 max 1024 default 16");
  PrintLn("#option idle type combo var none var small var medium var large default none");
  PrintLn("#option pruning type combo var none var small var medium var large default large");
  PrintLn("#option knowledge type combo var none var small var medium var large default large");
  PrintLn("#option randomness type combo var none var small var medium var large default none");
  PrintLn("#option newgame type button");
  PrintLn("#ucciok");

  // 以下是接收指令和提供对策的循环体
  while (!Search.bQuit) {
    switch (IdleLine(UcciComm, Search.bDebug)) {
    case UCCI_COMM_ISREADY:
      PrintLn("#readyok");
      break;
    case UCCI_COMM_STOP:
      PrintLn("#nobestmove");
      break;
    case UCCI_COMM_POSITION:
      BuildPos(Search.pos, UcciComm);
      Search.pos.nDistance = 0;
      Search.PreEvaluate(&Search.pos, &PreEval);
      Search.nBanMoves = 0;
      break;
    case UCCI_COMM_BANMOVES:
      Search.nBanMoves = UcciComm.nBanMoveNum;
      for (i = 0; i < UcciComm.nBanMoveNum; i ++) {
        Search.wmvBanList[i] = COORD_MOVE(UcciComm.lpdwBanMovesCoord[i]);
      }
      break;
    case UCCI_COMM_SETOPTION:
      switch (UcciComm.Option) {
      case UCCI_OPTION_PROMOTION:
        PreEval.bPromotion = UcciComm.bCheck;
        break;
      case UCCI_OPTION_BATCH:
        Search.bBatch = UcciComm.bCheck;
        break;
      case UCCI_OPTION_DEBUG:
        Search.bDebug = UcciComm.bCheck;
        break;
      case UCCI_OPTION_PONDER:
        bPonderTime = UcciComm.bCheck;
        break;
      case UCCI_OPTION_ALWAYSCHECK:
        Search.bAlwaysCheck = UcciComm.bCheck;
        break;
      case UCCI_OPTION_USEHASH:
        Search.bUseHash = UcciComm.bCheck;
        break;
      case UCCI_OPTION_USEBOOK:
        Search.bUseBook = UcciComm.bCheck;
        break;
      case UCCI_OPTION_BOOKFILES:
        if (AbsolutePath(UcciComm.szOption)) {
          strcpy(Search.szBookFile, UcciComm.szOption);
        } else {
          LocatePath(Search.szBookFile, UcciComm.szOption);
        }
        break;
      case UCCI_OPTION_EVALAPI:
        if (AbsolutePath(UcciComm.szOption)) {
          strcpy(szLibEvalFile, UcciComm.szOption);
        } else {
          LocatePath(szLibEvalFile, UcciComm.szOption);
        }
        FreeEvalApi(hModule);
        hModule = LoadEvalApi(szLibEvalFile);
        break;
      case UCCI_OPTION_HASHSIZE:
        DelHash();
        i = 19; // 小于1,分配0.5M置换表
        while (UcciComm.nSpin > 0) {
          UcciComm.nSpin /= 2;
          i ++;
        }
        NewHash(MAX(i, 24)); // 最小的置换表设为16M
        break;
      case UCCI_OPTION_IDLE:
        switch (UcciComm.Grade) {
        case UCCI_GRADE_NONE:
          Search.bIdle = false;
          Search.nCountMask = INTERRUPT_COUNT - 1;
          break;
        case UCCI_GRADE_SMALL:
          Search.bIdle = true;
          Search.nCountMask = INTERRUPT_COUNT / 4 - 1;
          break;
        case UCCI_GRADE_MEDIUM:
          Search.bIdle = true;
          Search.nCountMask = INTERRUPT_COUNT / 16 - 1;
          break;
        case UCCI_GRADE_LARGE:
          Search.bIdle = true;
          Search.nCountMask = INTERRUPT_COUNT / 64 - 1;
          break;
        default:
          break;
        }
        break;
      case UCCI_OPTION_PRUNING:
        Search.bNullMove = (UcciComm.Grade != UCCI_GRADE_NONE);
        break;
      case UCCI_OPTION_KNOWLEDGE:
        Search.bKnowledge = (UcciComm.Grade != UCCI_GRADE_NONE);
        break;
      case UCCI_OPTION_RANDOMNESS:
        switch (UcciComm.Grade) {
        case UCCI_GRADE_NONE:
          Search.nRandomMask = 0;
          break;
        case UCCI_GRADE_SMALL:
          Search.nRandomMask = 1;
          break;
        case UCCI_GRADE_MEDIUM:
          Search.nRandomMask = 3;
          break;
        case UCCI_GRADE_LARGE:
          Search.nRandomMask = 7;
          break;
        default:
          break;
        }
        break;
      default:
        break;
      }
      break;
    case UCCI_COMM_GO:
      Search.bPonder = UcciComm.bPonder;
      Search.bDraw = UcciComm.bDraw;
      switch (UcciComm.Go) {
      case UCCI_GO_DEPTH:
        Search.nGoMode = GO_MODE_INFINITY;
        Search.nNodes = 0;
        SearchMain(UcciComm.nDepth);
        break;
      case UCCI_GO_NODES:
        Search.nGoMode = GO_MODE_NODES;
        Search.nNodes = UcciComm.nNodes;
        SearchMain(UCCI_MAX_DEPTH);
        break;
      case UCCI_GO_TIME_MOVESTOGO:
      case UCCI_GO_TIME_INCREMENT:
        Search.nGoMode = GO_MODE_TIMER;
        if (UcciComm.Go == UCCI_GO_TIME_MOVESTOGO) {
          // 对于时段制,把剩余时间平均分配到每一步,作为适当时限。
          // 剩余步数从1到5,最大时限依次是剩余时间的100%、90%、80%、70%和60%,5以上都是50%
          Search.nProperTimer = UcciComm.nTime / UcciComm.nMovesToGo;
          Search.nMaxTimer = UcciComm.nTime * MAX(5, 11 - UcciComm.nMovesToGo) / 10;
        } else {
          // 对于加时制,假设棋局会在20回合内结束,算出平均每一步的适当时限,最大时限是剩余时间的一半
          Search.nProperTimer = UcciComm.nTime / 20 + UcciComm.nIncrement;
          Search.nMaxTimer = UcciComm.nTime / 2;
        }
        // 如果是后台思考的时间分配策略,那么适当时限设为原来的1.25倍
        Search.nProperTimer += (bPonderTime ? Search.nProperTimer / 4 : 0);
        Search.nMaxTimer = MIN(Search.nMaxTimer, Search.nProperTimer * 10);
        SearchMain(UCCI_MAX_DEPTH);
        break;
      default:
        break;
      }
      break;
    case UCCI_COMM_PROBE:
      BuildPos(posProbe, UcciComm);
      if (!PopHash(posProbe)) {
        PopLeaf(posProbe);
      }
      break;
    case UCCI_COMM_QUIT:
      Search.bQuit = true;
      break;
    default:
      break;
    }
  }
  DelHash();
  FreeEvalApi(hModule);
  PrintLn("#bye");
  return 0;
}
Esempio n. 3
0
int main(int argc, char * argv[])
{
	const char *BoolValue[2] = { "false", "true" };
    printf("Mars V0.3 UCCI based on Fruit 2.1 by Fabien Letouzey\n");
	printf("作者:顾剑辉\n");
    printf("网站:www.jsmaster.com\n");
	printf("请键入ucci指令......\n");
    //position fen rnbakab2/9/2c1c1n2/p1p1p3p/6p2/2PN3r1/P3P1P1P/1C2C1N2/9/1RBAKAB1R w - - 0 7   
	//position fen 1rbakab2/9/1cn5n/pR4p1p/2p1p4/4c1P2/P1P4rP/2N1C1NC1/4A4/2B1KABR1 w - - 0 10
	//9/3ka4/3R5/5r2p/p5p2/4N4/P5P1P/9/4A2c1/2BK2B2 b - - 0 36
	CommEnum IdleComm;
	CommDetail Command;
	int move,n;
	undo_t undo[1];
 
	if(BootLine() == e_CommUcci)
	{

		zobrist_gen();
	    pre_move_gen();
	    trans_init(Trans);
	    trans_alloc(Trans);
        material_init();
        material_alloc(); 
		OutFile = stdout;
        board_from_fen("rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR r - - 0 1");
		//board_from_fen("3k5/9/9/9/9/4c4/9/9/4n4/4K4 r - - 0 1");
		//board_from_fen("3k5/9/9/9/9/4c4/3C5/2n1n4/4K4/9 r - - 0 1");
		printf("position fen rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR r - - 0 1\n\n");
		print_board();
		printf("\n");
		printf("id name Mars v0.3\n");
		fflush(stdout);
		printf("id copyright 版权所有(C) 2005-2008\n");
		fflush(stdout);
		printf("id author 顾剑辉\n");
		fflush(stdout);
		printf("id user 未知\n\n");
		fflush(stdout);
/*
				printf("option batch type check default %s\n", BoolValue[ThisSearch.bBatch]);
		fflush(stdout);

		// option debug 让引擎输出详细的搜索信息,并非真正的调试模式。
		printf("option debug type check default %s\n", BoolValue[ThisSearch.Debug]);
		fflush(stdout);

		// 指定开局库文件的名称,可指定多个开局库文件,用分号“;”隔开,如不让引擎使用开局库,可以把值设成空
		ThisSearch.bUseOpeningBook = ThisSearch.m_Hash.LoadBook(BookFile);
		if(ThisSearch.bUseOpeningBook)
			printf("option bookfiles type string default %s\n", BookFile);
		else
			printf("option bookfiles type string default %s\n", 0);
		fflush(stdout);

		// 残局库名称
		printf("option egtbpaths type string default null\n");
		fflush(stdout);

		// 显示Hash表的大小
		printf("option hashsize type spin default %d MB\n", ThisSearch.m_Hash.nHashSize*2*sizeof(CHashRecord)/1024/1024);
		fflush(stdout);

		// 引擎的线程数
		printf("option threads type spin default %d\n", 0);
		fflush(stdout);

		// 引擎达到自然限着的半回合数
		printf("option drawmoves type spin default %d\n", ThisSearch.NaturalBouts);
		fflush(stdout);

		// 棋规
		printf("option repetition type spin default %d 1999年版《中国象棋竞赛规则》\n", e_RepetitionChineseRule);
		fflush(stdout);

		// 空着裁减是否打开
		printf("option pruning type check %d\n", ThisSearch);
		fflush(stdout);

		// 估值函数的使用情况
		printf("option knowledge type check %d\n", ThisSearch);
		fflush(stdout);

		// 指定选择性系数,通常有0,1,2,3四个级别。给估值函数加减一定范围内的随机数,让引擎每次走出不相同的棋。
		printf("option selectivity type spin min 0 max 3 default %d\n", ThisSearch.nSelectivity);
		fflush(stdout);

		// 指定下棋的风格,通常有solid(保守)、normal(均衡)和risky(冒进)三种
		printf("option style type combo var solid var normal var risky default %s\n", ChessStyle[ThisSearch.nStyle]);
		fflush(stdout);		
*/
		// copyprotection 显示版权检查信息(正在检查,版权信息正确或版权信息错误)。 
		printf("copyprotection ok\n\n");
		fflush(stdout);

		// ucciok 这是ucci指令的最后一条反馈信息,表示引擎已经进入用UCCI协议通讯的状态。
		printf("ucciok\n\n");
		fflush(stdout);
        
		//FILE * out=fopen("info.txt","w+");
		do 
		{
			IdleComm = IdleLine(Command, 0);
			switch (IdleComm) 
			{
				// isready 检测引擎是否处于就绪状态,其反馈信息总是readyok,该指令仅仅用来检测引擎的“指令接收缓冲区”是否能正常容纳指令。
				// readyok 表明引擎处于就绪状态(即可接收指令的状态),不管引擎处于空闲状态还是思考状态。
				case e_CommIsReady:
					//fprintf(out,"readyok\n");
					printf("readyok\n");
					fflush(stdout);
					break;

				// stop 中断引擎的思考,强制出着。后台思考没有命中时,就用该指令来中止思考,然后重新输入局面。
				case e_CommStop:
					//ThisSearch.bStopThinking = 1;
					printf("nobestmove\n");
					printf("score 0\n");
					fflush(stdout);
					break;

				// position fen 设置“内置棋盘”的局面,用fen来指定FEN格式串,moves后面跟的是随后走过的着法
				case e_CommPosition:
					// 将界面传来的Fen串转化为棋局信息
					// board_clear();
					//fprintf(out,"%s\n",Command.Position.FenStr);
                    //fprintf(out,"%d",Command.Position.MoveNum);
					//fprintf(out,"%s\n",Command.Position.CoordList);
					 //trans_clear(Trans);
					 board_from_fen(Command.Position.FenStr);
					 print_board();
					 for(n=0; n<Command.Position.MoveNum; n++)
					{
						move = move_from_string(Command.Position.CoordList[n]);
						//fprintf(out,"%x ",move);
						if( !move )
							break;

						move_do(move,undo);
						//ThisSearch.StepRecords[ThisSearch.nCurrentStep-1] |= ThisSearch.Checking(ThisSearch.Player) << 24;
					}
					// 将局面走到当前,主要是为了更新着法记录,用于循环检测。
					break;

				// banmoves 为当前局面设置禁手,以解决引擎无法处理的长打问题。当出现长打局面时,棋手可以操控界面向引擎发出禁手指令。
				case e_CommBanMoves:
					break;

				// setoption 设置引擎各种参数
				case e_CommSetOption:
					switch(Command.Option.Type) 
					{
						// setoption batch %d
						case e_OptionBatch:
							batch=(Command.Option.Value.Check == e_CheckTrue);
							printf("option batch type check default %s\n", BoolValue[batch]);
							fflush(stdout);
							break;

						// setoption debug %d 让引擎输出详细的搜索信息,并非真正的调试模式。
						case e_OptionDebug:
							
							break;

						// setoption bookfiles %s  指定开局库文件的名称,可指定多个开局库文件,用分号“;”隔开,如不让引擎使用开局库,可以把值设成空
						case e_OptionBookFiles:
							
							break;

						// setoption egtbpaths %s  指定残局库文件的名称,可指定多个残局库路径,用分号“;”隔开,如不让引擎使用残局库,可以把值设成空
						case e_OptionEgtbPaths:
							// 引擎目前不支持开局库
							
							break;

						// setoption hashsize %d  以MB为单位规定Hash表的大小,-1表示让引擎自动分配Hash表。1~1024MB
						// 象堡界面有个Bug,每次设置引擎时,这个命令应在开局库的前面
						case e_OptionHashSize:
							// -1MB(自动), 0MB(自动), 1MB(16), 2MB(17), 4MB(18), 8MB(19), 16MB(20), 32MB(21), 64MB(22), 128MB(23), 256MB(24), 512MB(25), 1024MB(26)
							if( Command.Option.Value.Spin <= 0)
								n = 22;		// 缺省情况下,引擎自动分配(1<<22)*16=64MB,红与黑两各表,双方各一半。
							else
							{
								n = 15;											// 0.5 MB = 512 KB 以此为基数
								while( Command.Option.Value.Spin > 0 )
								{
									Command.Option.Value.Spin >>= 1;			// 每次除以2,直到为0
									n ++;
								}
							}								

							break;

						// setoption threads %d	      引擎的线程数,为多处理器并行运算服务
						case e_OptionThreads:
							// ThisSearch.nThreads = Command.Option.Value.Spin;		// 0(auto),1,2,4,8,16,32
							printf("option drawmoves type spin default %d\n", 0);
							fflush(stdout);
							break;

						// setoption drawmoves %d	  达到自然限着的回合数:50,60,70,80,90,100,象堡已经自动转化为半回合数
						case e_OptionDrawMoves:
							
							break;

						// setoption repetition %d	  处理循环的棋规,目前只支持“中国象棋棋规1999”
						case e_OptionRepetition:
							// ThisSearch.nRepetitionStyle = Command.Option.Value.Repetition;
							// e_RepetitionAlwaysDraw  不变作和
							// e_RepetitionCheckBan    禁止长将
							// e_RepetitionAsianRule   亚洲规则
							// e_RepetitionChineseRule 中国规则(缺省)
							
							break;

						// setoption pruning %d,“空着向前裁剪”是否打开
						case e_OptionPruning:
							//ThisSearch.bPruning = Command.Option.Value.Scale;
							//printf("option pruning type check %d\n", ThisSearch);
							//fflush(stdout);
							break;

						// setoption knowledge %d,估值函数的使用
						case e_OptionKnowledge:
							//ThisSearch.bKnowledge = Command.Option.Value.Scale;
							//printf("option knowledge type check %d\n", ThisSearch);
							//fflush(stdout);
							break;

						// setoption selectivity %d  指定选择性系数,通常有0,1,2,3四个级别
						case e_OptionSelectivity:
							/*switch (Command.Option.Value.Scale)
							{
								case e_ScaleNone:
									ThisSearch.SelectMask = 0;
									break;
								case e_ScaleSmall:
									ThisSearch.SelectMask = 1;
									break;
								case e_ScaleMedium:
									ThisSearch.SelectMask = 3;
									break;
								case e_ScaleLarge:
									ThisSearch.SelectMask = 7;
									break;
								default:
									ThisSearch.SelectMask = 0;
									break;
							}
							printf("option selectivity type spin min 0 max 3 default %d\n", ThisSearch.SelectMask);
							fflush(stdout);*/
							break;

						// setoption style %d  指定下棋的风格,通常有solid(保守)、normal(均衡)和risky(冒进)三种
						case e_OptionStyle:
							//ThisSearch.nStyle = Command.Option.Value.Style;
							//printf("option style type combo var solid var normal var risky default %s\n", ChessStyle[Command.Option.Value.Style]);
							//fflush(stdout);
							break;						

						// setoption loadbook  UCCI界面ElephantBoard在每次新建棋局时都会发送这条指令
						case e_OptionLoadBook:
							/*ThisSearch.m_Hash.ClearHashTable();
							ThisSearch.bUseOpeningBook = ThisSearch.m_Hash.LoadBook(BookFile);
							
							if(ThisSearch.bUseOpeningBook)
								printf("option loadbook succeed. %s\n", BookFile);		// 成功
							else
								printf("option loadbook failed! %s\n", "Not found file BOOK.DAT");				// 没有开局库
							fflush(stdout);
							printf("\n\n");
							fflush(stdout);
							*/
							break;

						default:
							break;
					}
					break;

				// Prepare timer strategy according to "go depth %d" or "go ponder depth %d" command
				case e_CommGo:
				case e_CommGoPonder:
					switch (Command.Search.Mode)
					{
						// 固定深度Command.Search.DepthTime.Depth
						case e_TimeDepth:
							ponder = 2;
							search(Command.Search.DepthTime.Depth,0,0);
							break;

						// 时段制: 分配时间 = 剩余时间 / 要走的步数
						case e_TimeMove:
							ponder = (IdleComm == e_CommGoPonder ? 1 : 0);
							search(32,Command.Search.DepthTime.Time * 1000 / Command.Search.TimeMode.MovesToGo, Command.Search.DepthTime.Time * 1000);
						//	ThisSearch.Ponder = (IdleComm == e_CommGoPonder ? 1 : 0);
						//	printf("%d\n", Command.Search.TimeMode.MovesToGo);
						//	ThisSearch.MainSearch(127, Command.Search.DepthTime.Time * 1000 / Command.Search.TimeMode.MovesToGo, Command.Search.DepthTime.Time * 1000);
							break;

						// 加时制: 分配时间 = 每步增加的时间 + 剩余时间 / 20 (即假设棋局会在20步内结束)
						case e_TimeInc:
                            ponder = (IdleComm == e_CommGoPonder ? 1 : 0);
							search(32,(Command.Search.DepthTime.Time + Command.Search.TimeMode.Increment * 20) * 1000 / 20, Command.Search.DepthTime.Time * 1000);
						 //	ThisSearch.Ponder = (IdleComm == e_CommGoPonder ? 1 : 0);
						 //	ThisSearch.MainSearch(127, (Command.Search.DepthTime.Time + Command.Search.TimeMode.Increment * 20) * 1000 / 20, Command.Search.DepthTime.Time * 1000);
							break;

						default:
							break;
					}
					break;
			}
		} while (IdleComm != e_CommQuit);
        //fprintf(out,"bye");
		//fclose(out);
		printf("bye\n");
		fflush(stdout);
		//getchar();
	}