diff --git a/src/position.cpp b/src/position.cpp index 646b61ea..09daeba0 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -703,7 +703,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI // pointer to point to the new, ready to be updated, state. struct ReducedStateInfo { Key pawnKey, materialKey; - int castleRights, rule50, gamePly, pliesFromNull; + int castleRights, rule50, ply, pliesFromNull; Square epSquare; Score value; Value npMaterial[2]; @@ -715,7 +715,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI // Save the current key to the history[] array, in order to be able to // detect repetition draws. - history[st->gamePly++] = key; + history[st->ply++] = key; // Update side to move key ^= zobSideToMove; @@ -819,7 +819,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI set_bit(&(byTypeBB[promotion]), to); board[to] = piece_of_color_and_type(us, promotion); - // Update piece counts + // Update piece counts pieceCount[us][promotion]++; pieceCount[us][PAWN]--; @@ -1243,7 +1243,7 @@ void Position::do_null_move(StateInfo& backupSt) { // Save the current key to the history[] array, in order to be able to // detect repetition draws. - history[st->gamePly++] = st->key; + history[st->ply++] = st->key; // Update the necessary information if (st->epSquare != SQ_NONE) @@ -1278,7 +1278,7 @@ void Position::undo_null_move() { // Update the necessary information sideToMove = opposite_color(sideToMove); st->rule50--; - st->gamePly--; + st->ply--; } @@ -1481,15 +1481,15 @@ void Position::clear() { } -/// Position::reset_game_ply() simply sets gamePly to 0. It is used from the +/// Position::reset_ply() simply sets ply to 0. It is used from the /// UCI interface code, whenever a non-reversible move is made in a /// 'position fen moves m1 m2 ...' command. This makes it possible /// for the program to handle games of arbitrary length, as long as the GUI /// handles draws by the 50 move rule correctly. -void Position::reset_game_ply() { +void Position::reset_ply() { - st->gamePly = 0; + st->ply = 0; } @@ -1666,9 +1666,11 @@ bool Position::is_draw() const { if (st->rule50 > 100 || (st->rule50 == 100 && !is_check())) return true; - // Draw by repetition? - for (int i = 4, e = Min(Min(st->gamePly, st->rule50), st->pliesFromNull); i <= e; i += 2) - if (history[st->gamePly - i] == st->key) + assert(st->ply >= st->rule50); + + // Draw by repetition? + for (int i = 4, e = Min(st->rule50, st->pliesFromNull); i <= e; i += 2) + if (history[st->ply - i] == st->key) return true; return false; diff --git a/src/position.h b/src/position.h index ff1fa937..cc816910 100644 --- a/src/position.h +++ b/src/position.h @@ -100,7 +100,7 @@ enum Phase { struct StateInfo { Key pawnKey, materialKey; - int castleRights, rule50, gamePly, pliesFromNull; + int castleRights, rule50, ply, pliesFromNull; Square epSquare; Score value; Value npMaterial[2]; @@ -273,7 +273,7 @@ public: // Game ply information int ply() const; - void reset_game_ply(); + void reset_ply(); // Position consistency check, for debugging bool is_ok(int* failedStep = NULL) const; @@ -558,7 +558,7 @@ inline PieceType Position::captured_piece() const { } inline int Position::ply() const { - return st->gamePly; + return st->ply; } #endif // !defined(POSITION_H_INCLUDED) diff --git a/src/search.cpp b/src/search.cpp index 739cce0b..02e171b7 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -89,7 +89,7 @@ namespace { void idle_loop(int threadID, SplitPoint* sp); template - void split(const Position& pos, SearchStack* ss, int ply, Value* alpha, const Value beta, Value* bestValue, + void split(const Position& pos, SearchStack* ss, Value* alpha, const Value beta, Value* bestValue, Depth depth, bool mateThreat, int* moveCount, MovePicker* mp, int master, bool pvNode); private: @@ -285,10 +285,10 @@ namespace { Value root_search(Position& pos, SearchStack* ss, RootMoveList& rml, Value* alphaPtr, Value* betaPtr); template - Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply, bool allowNullmove, int threadID, Move excludedMove = MOVE_NONE); + Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, bool allowNullmove, int threadID, Move excludedMove = MOVE_NONE); template - Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply, int threadID); + Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int threadID); template void sp_search(SplitPoint* sp, int threadID); @@ -637,6 +637,7 @@ namespace { H.clear(); init_ss_array(ss); ValueByIteration[1] = rml.get_move_score(0); + p.reset_ply(); Iteration = 1; // Is one move significantly better than others after initial scoring ? @@ -877,7 +878,7 @@ namespace { alpha = -VALUE_INFINITE; // Full depth PV search, done on first move or after a fail high - value = -search(pos, ss+1, -beta, -alpha, newDepth, 1, false, 0); + value = -search(pos, ss+1, -beta, -alpha, newDepth, false, 0); } else { @@ -894,7 +895,7 @@ namespace { if (ss->reduction) { // Reduced depth non-pv search using alpha as upperbound - value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, 1, true, 0); + value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, true, 0); doFullDepthSearch = (value > alpha); } } @@ -904,12 +905,12 @@ namespace { { // Full depth non-pv search using alpha as upperbound ss->reduction = Depth(0); - value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth, 1, true, 0); + value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth, true, 0); // If we are above alpha then research at same depth but as PV // to get a correct score or eventually a fail high above beta. if (value > alpha) - value = -search(pos, ss+1, -beta, -alpha, newDepth, 1, false, 0); + value = -search(pos, ss+1, -beta, -alpha, newDepth, false, 0); } } @@ -1033,12 +1034,12 @@ namespace { template Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, - int ply, bool allowNullmove, int threadID, Move excludedMove) { + bool allowNullmove, int threadID, Move excludedMove) { assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE); assert(beta > alpha && beta <= VALUE_INFINITE); assert(PvNode || alpha == beta - 1); - assert(ply >= 0 && ply < PLY_MAX); + assert(pos.ply() > 0 && pos.ply() < PLY_MAX); assert(threadID >= 0 && threadID < TM.active_threads()); Move movesSearched[256]; @@ -1052,11 +1053,12 @@ namespace { bool isCheck, singleEvasion, moveIsCheck, captureOrPromotion, dangerous; bool mateThreat = false; int moveCount = 0; + int ply = pos.ply(); refinedValue = bestValue = value = -VALUE_INFINITE; oldAlpha = alpha; if (depth < OnePly) - return qsearch(pos, ss, alpha, beta, Depth(0), ply, threadID); + return qsearch(pos, ss, alpha, beta, Depth(0), threadID); // Step 1. Initialize node and poll // Polling can abort search. @@ -1129,7 +1131,7 @@ namespace { && !pos.has_pawn_on_7th(pos.side_to_move())) { Value rbeta = beta - razor_margin(depth); - Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), ply, threadID); + Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), threadID); if (v < rbeta) // Logically we should return (v + razor_margin(depth)), but // surprisingly this did slightly weaker in tests. @@ -1171,7 +1173,7 @@ namespace { pos.do_null_move(st); - nullValue = -search(pos, ss+1, -beta, -alpha, depth-R*OnePly, ply+1, false, threadID); + nullValue = -search(pos, ss+1, -beta, -alpha, depth-R*OnePly, false, threadID); pos.undo_null_move(); @@ -1185,7 +1187,7 @@ namespace { return nullValue; // Do zugzwang verification search - Value v = search(pos, ss, alpha, beta, depth-5*OnePly, ply, false, threadID); + Value v = search(pos, ss, alpha, beta, depth-5*OnePly, false, threadID); if (v >= beta) return nullValue; } else { @@ -1212,7 +1214,7 @@ namespace { && (PvNode || (!isCheck && ss->eval >= beta - IIDMargin))) { Depth d = (PvNode ? depth - 2 * OnePly : depth / 2); - search(pos, ss, alpha, beta, d, ply, false, threadID); + search(pos, ss, alpha, beta, d, false, threadID); ttMove = ss->pv[ply]; tte = TT.retrieve(posKey); } @@ -1259,7 +1261,7 @@ namespace { if (abs(ttValue) < VALUE_KNOWN_WIN) { Value b = ttValue - SingularExtensionMargin; - Value v = search(pos, ss, b - 1, b, depth / 2, ply, false, threadID, move); + Value v = search(pos, ss, b - 1, b, depth / 2, false, threadID, move); if (v < ttValue - SingularExtensionMargin) ext = OnePly; @@ -1306,7 +1308,7 @@ namespace { // Step extra. pv search (only in PV nodes) // The first move in list is the expected PV if (PvNode && moveCount == 1) - value = -search(pos, ss+1, -beta, -alpha, newDepth, ply+1, false, threadID); + value = -search(pos, ss+1, -beta, -alpha, newDepth, false, threadID); else { // Step 14. Reduced depth search @@ -1322,7 +1324,7 @@ namespace { ss->reduction = reduction(depth, moveCount); if (ss->reduction) { - value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, ply+1, true, threadID); + value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, true, threadID); doFullDepthSearch = (value > alpha); } @@ -1332,7 +1334,7 @@ namespace { if (doFullDepthSearch && ss->reduction > 2 * OnePly) { ss->reduction = OnePly; - value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, ply+1, true, threadID); + value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, true, threadID); doFullDepthSearch = (value > alpha); } } @@ -1341,13 +1343,13 @@ namespace { if (doFullDepthSearch) { ss->reduction = Depth(0); - value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1, true, threadID); + value = -search(pos, ss+1, -(alpha+1), -alpha, newDepth, true, threadID); // Step extra. pv search (only in PV nodes) // Search only for possible new PV nodes, if instead value >= beta then // parent node fails low with value <= alpha and tries another move. if (PvNode && value > alpha && value < beta) - value = -search(pos, ss+1, -beta, -alpha, newDepth, ply+1, false, threadID); + value = -search(pos, ss+1, -beta, -alpha, newDepth, false, threadID); } } @@ -1380,7 +1382,7 @@ namespace { && TM.available_thread_exists(threadID) && !AbortSearch && !TM.thread_should_stop(threadID)) - TM.split(pos, ss, ply, &alpha, beta, &bestValue, depth, + TM.split(pos, ss, &alpha, beta, &bestValue, depth, mateThreat, &moveCount, &mp, threadID, PvNode); } @@ -1425,14 +1427,13 @@ namespace { // less than OnePly). template - Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, - Depth depth, int ply, int threadID) { + Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int threadID) { assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE); assert(beta >= -VALUE_INFINITE && beta <= VALUE_INFINITE); assert(PvNode || alpha == beta - 1); assert(depth <= 0); - assert(ply >= 0 && ply < PLY_MAX); + assert(pos.ply() > 0 && pos.ply() < PLY_MAX); assert(threadID >= 0 && threadID < TM.active_threads()); EvalInfo ei; @@ -1442,6 +1443,7 @@ namespace { bool isCheck, enoughMaterial, moveIsCheck, evasionPrunable; const TTEntry* tte = NULL; int moveCount = 0; + int ply = pos.ply(); Value oldAlpha = alpha; // Initialize, and make an early exit in case of an aborted search, @@ -1563,7 +1565,7 @@ namespace { // Make and search the move pos.do_move(move, st, ci, moveIsCheck); - value = -qsearch(pos, ss+1, -beta, -alpha, depth-OnePly, ply+1, threadID); + value = -qsearch(pos, ss+1, -beta, -alpha, depth-OnePly, threadID); pos.undo_move(move); assert(value > -VALUE_INFINITE && value < VALUE_INFINITE); @@ -1636,6 +1638,7 @@ namespace { Position pos(*sp->pos); CheckInfo ci(pos); + int ply = pos.ply(); SearchStack* ss = sp->sstack[threadID] + 1; isCheck = pos.is_check(); @@ -1709,7 +1712,7 @@ namespace { if (ss->reduction) { Value localAlpha = sp->alpha; - value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth-ss->reduction, sp->ply+1, true, threadID); + value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth-ss->reduction, true, threadID); doFullDepthSearch = (value > localAlpha); } @@ -1720,7 +1723,7 @@ namespace { { ss->reduction = OnePly; Value localAlpha = sp->alpha; - value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth-ss->reduction, sp->ply+1, true, threadID); + value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth-ss->reduction, true, threadID); doFullDepthSearch = (value > localAlpha); } } @@ -1730,10 +1733,10 @@ namespace { { ss->reduction = Depth(0); Value localAlpha = sp->alpha; - value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth, sp->ply+1, true, threadID); + value = -search(pos, ss+1, -(localAlpha+1), -localAlpha, newDepth, true, threadID); if (PvNode && value > localAlpha && value < sp->beta) - value = -search(pos, ss+1, -sp->beta, -sp->alpha, newDepth, sp->ply+1, false, threadID); + value = -search(pos, ss+1, -sp->beta, -sp->alpha, newDepth, false, threadID); } // Step 16. Undo move @@ -1756,7 +1759,7 @@ namespace { if (PvNode && value < sp->beta) // This guarantees that always: sp->alpha < sp->beta sp->alpha = value; - sp_update_pv(sp->parentSstack, ss, sp->ply); + sp_update_pv(sp->parentSstack, ss, ply); } } } @@ -2622,11 +2625,10 @@ namespace { // split() returns. template - void ThreadsManager::split(const Position& p, SearchStack* ss, int ply, Value* alpha, - const Value beta, Value* bestValue, Depth depth, bool mateThreat, - int* moveCount, MovePicker* mp, int master, bool pvNode) { + void ThreadsManager::split(const Position& p, SearchStack* ss, Value* alpha, const Value beta, + Value* bestValue, Depth depth, bool mateThreat, int* moveCount, + MovePicker* mp, int master, bool pvNode) { assert(p.is_ok()); - assert(ply > 0 && ply < PLY_MAX); assert(*bestValue >= -VALUE_INFINITE); assert(*bestValue <= *alpha); assert(*alpha < beta); @@ -2652,7 +2654,6 @@ namespace { // Initialize the split point object splitPoint->parent = threads[master].splitPoint; splitPoint->stopRequest = false; - splitPoint->ply = ply; splitPoint->depth = depth; splitPoint->mateThreat = mateThreat; splitPoint->alpha = *alpha; @@ -2787,7 +2788,7 @@ namespace { init_ss_array(ss); pos.do_move(cur->move, st); moves[count].move = cur->move; - moves[count].score = -qsearch(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 1, 0); + moves[count].score = -qsearch(pos, ss+1, -VALUE_INFINITE, VALUE_INFINITE, Depth(0), 0); moves[count].pv[0] = cur->move; moves[count].pv[1] = MOVE_NONE; pos.undo_move(cur->move); diff --git a/src/thread.h b/src/thread.h index 782694ad..0a28f39b 100644 --- a/src/thread.h +++ b/src/thread.h @@ -54,7 +54,6 @@ struct SplitPoint { Depth depth; bool pvNode, mateThreat; Value beta; - int ply; SearchStack sstack[MAX_THREADS][PLY_MAX_PLUS_2]; // Const pointers to shared data diff --git a/src/uci.cpp b/src/uci.cpp index 23b0cc27..77c96343 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -206,7 +206,7 @@ namespace { move = move_from_string(RootPosition, token); RootPosition.do_move(move, st); if (RootPosition.rule_50_counter() == 0) - RootPosition.reset_game_ply(); + RootPosition.reset_ply(); } // Our StateInfo st is about going out of scope so copy // its content inside RootPosition before they disappear.