Exemple #1
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;
}
Exemple #2
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;
}