// 无害裁剪 int HarmlessPruning ( void ) { // 1. 和局局面 if ( pos.IsDraw() ) { return 0; // eleeye上表示,为了安全起见,不用pos.DrawValue() } // 2. 路径重复 const int vRep = roll.RepStatus (); if ( vRep != REP_NONE ) { return roll.RepValue ( vRep ); } return - MATE_VALUE; }
// 尝试某个着法,并返回着法状态,参阅"cchess.h" bool TryMove(PositionStruct &pos, int &nStatus, int mv) { if (!pos.LegalMove(mv)) { nStatus = MOVE_ILLEGAL; return false; } if (!pos.MakeMove(mv)) { nStatus = MOVE_INCHECK; return false; } nStatus = 0; nStatus += (pos.LastMove().CptDrw > 0 ? MOVE_CAPTURE : 0); nStatus += (pos.LastMove().ChkChs > 0 ? MOVE_CHECK : 0); nStatus += (pos.IsMate() ? MOVE_MATE : 0); nStatus += pos.RepStatus(3) * MOVE_PERPETUAL; // 提示:参阅"position.cpp"中的"IsRep()"函数 nStatus += (pos.IsDraw() ? MOVE_DRAW : 0); pos.UndoMakeMove(); return true; }
// 无害裁剪 static int HarmlessPruning(const PositionStruct &pos, int vlBeta) { int vl, vlRep; // 1. 杀棋步数裁剪; vl = pos.nDistance - MATE_VALUE; if (vl >= vlBeta) { return vl; } // 2. 和棋裁剪; if (pos.IsDraw()) { return 0; // 安全起见,这里不用"pos.DrawValue()"; } // 3. 重复裁剪; vlRep = pos.RepStatus(); if (vlRep > 0) { return pos.RepValue(vlRep); } return -MATE_VALUE; }
// 主搜索函数 int SearchMain ( void ) { // 特殊情况 MoveSortStruct mvsort; int nMoveNum = mvsort.InitMove (); if ( nMoveNum == 0 ) { // 无着法 printf ( "bestmove a0a1 resign\n" ); fflush ( stdout ); return 0; } else if ( nMoveNum == 1 ) { // 唯一着法 printf ( "bestmove %s\n", MoveIntToStr(mvsort.move[0]).c_str() ); fflush ( stdout ); return mvsort.move[0]; } if ( pos.IsDraw() ) { // 和局 printf ( "bestmove a0a1 draw\n" ); fflush ( stdout ); // 注意不要return } // 初始化 ClearHistoryTable (); ClearHashTable (); ClearHashTableQC (); InitBeginTime ( SEARCH_TOTAL_TIME ); // 迭代加深搜索 printf("depth time nNode rBeta"); for ( int i = 0; i < 3; i ++ ) { printf(" bvl[%d] bmv[%d]", i, i); } printf("\n"); fflush ( stdout ); int lastbvl[nBest], lastbmv[nBest]; ClearBmvBvl ( lastbmv, lastbvl ); for ( int depth = 1; /*depth <= ?*/; depth ++ ) { InitBeginTime ( THIS_SEARCH_TIME ); InitSearchStruct (); SearchAlphaBeta ( depth, - MATE_VALUE, MATE_VALUE ); if ( TimeOut() ) { CopyBmvBvl ( Search.bmv, Search.bvl, lastbmv, lastbvl ); break; } else { CopyBmvBvl ( lastbmv, lastbvl, Search.bmv, Search.bvl ); } printf( "%5d %.2fs %7d %2.0f%%", depth, TimeCost(SEARCH_TOTAL_TIME), Search.nNode, 100.0*Search.nBeta/Search.nNode); for ( int i = 0; i < 3; i ++ ) { printf(" %6d %s", Search.bvl[i], MoveIntToStr(Search.bmv[i]).c_str()); } printf("\n"); fflush ( stdout ); if ( Search.bvl[0] <= - BAN_VALUE || Search.bvl[0] >= BAN_VALUE) { break; } if ( Search.bvl[1] <= - BAN_VALUE || Search.bmv[1] == 0 ) { break; } } printf ( "totaltime: %.2fs\n", TimeCost(SEARCH_TOTAL_TIME) ); fflush ( stdout ); // 输出最优着法 if ( Search.bmv[0] == 0 || Search.bvl[0] <= - BAN_VALUE ) { printf ( "bestmove a0a1 resign\n" ); // 认输 fflush ( stdout ); return 0; } else { printf ( "bestmove %s\n", MoveIntToStr(Search.bmv[0]).c_str() ); fflush ( stdout ); return Search.bmv[0]; } }