void BuildPos(PositionStruct &pos, const UcciCommStruct &UcciComm) { int i, mv; pos.FromFen(UcciComm.szFenStr); for (i = 0; i < UcciComm.nMoveNum; i ++) { mv = COORD_MOVE(UcciComm.lpdwMovesCoord[i]); if (mv == 0) { break; } if (pos.LegalMove(mv) && pos.MakeMove(mv) && pos.LastMove().CptDrw > 0) { // 始终让pos.nMoveNum反映没吃子的步数 pos.SetIrrev(); } } }
// 尝试某个着法,并返回着法状态,参阅"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 SearchQuiesc(PositionStruct &pos, int vlAlpha, int vlBeta) { int vlBest, vl, mv; bool bInCheck; MoveSortStruct MoveSort; // 静态搜索例程包括以下几个步骤: Search2.nAllNodes ++; // 1. 无害裁剪; vl = HarmlessPruning(pos, vlBeta); if (vl > -MATE_VALUE) { return vl; } #ifdef HASH_QUIESC // 3. 置换裁剪; vl = ProbeHashQ(pos, vlAlpha, vlBeta); if (Search.bUseHash && vl > -MATE_VALUE) { return vl; } #endif // 4. 达到极限深度,直接返回评价值; if (pos.nDistance == LIMIT_DEPTH) { return Evaluate(pos, vlAlpha, vlBeta); } __ASSERT(Search.pos.nDistance < LIMIT_DEPTH); // 5. 初始化; vlBest = -MATE_VALUE; bInCheck = (pos.LastMove().ChkChs > 0); // 6. 对于被将军的局面,生成全部着法; if (bInCheck) { MoveSort.InitAll(pos); } else { // 7. 对于未被将军的局面,在生成着法前首先尝试空着(空着启发),即对局面作评价; vl = Evaluate(pos, vlAlpha, vlBeta); __ASSERT_BOUND(1 - WIN_VALUE, vl, WIN_VALUE - 1); __ASSERT(vl > vlBest); if (vl >= vlBeta) { #ifdef HASH_QUIESC RecordHashQ(pos, vl, MATE_VALUE); #endif return vl; } vlBest = vl; vlAlpha = MAX(vl, vlAlpha); // 8. 对于未被将军的局面,生成并排序所有吃子着法(MVV(LVA)启发); MoveSort.InitQuiesc(pos); } // 9. 用Alpha-Beta算法搜索这些着法; while ((mv = MoveSort.NextQuiesc(bInCheck)) != 0) { __ASSERT(bInCheck || pos.ucpcSquares[DST(mv)] > 0); if (pos.MakeMove(mv)) { vl = -SearchQuiesc(pos, -vlBeta, -vlAlpha); pos.UndoMakeMove(); if (vl > vlBest) { if (vl >= vlBeta) { #ifdef HASH_QUIESC if (vl > -WIN_VALUE && vl < WIN_VALUE) { RecordHashQ(pos, vl, MATE_VALUE); } #endif return vl; } vlBest = vl; vlAlpha = MAX(vl, vlAlpha); } } } // 10. 返回分值。 if (vlBest == -MATE_VALUE) { __ASSERT(pos.IsMate()); return pos.nDistance - MATE_VALUE; } else { #ifdef HASH_QUIESC if (vlBest > -WIN_VALUE && vlBest < WIN_VALUE) { RecordHashQ(pos, vlBest > vlAlpha ? vlBest : -MATE_VALUE, vlBest); } #endif return vlBest; } }