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; }
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; }
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(); }