From 6716337f407ad6586b636aca72ee673655822137 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Mon, 31 May 2010 21:38:34 +0100 Subject: [PATCH] Use ply counter in Position object And avoid a redundant one passed as argument in search calls. Also renamed gamePly in ply to better clarify this is used as search ply and is set to zero at the beginning of the search. No functional change. Signed-off-by: Marco Costalba --- src/position.cpp | 24 ++++++++-------- src/position.h | 6 ++-- src/search.cpp | 73 ++++++++++++++++++++++++------------------------ src/thread.h | 1 - src/uci.cpp | 2 +- 5 files changed, 54 insertions(+), 52 deletions(-) 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. -- 2.39.2