X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=37a962663fd241434642d09c89c760682483a8b1;hp=85d702c4d4c410e0eb4e5eb045977c6d891e5114;hb=adeded29fb6ce483bbbafaa0f67aa086cad968f9;hpb=83a574ff271ec5924976b48cf65ac62278f87558 diff --git a/src/search.cpp b/src/search.cpp index 85d702c4..37a96266 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -42,7 +42,6 @@ namespace Search { LimitsType Limits; std::vector RootMoves; Position RootPos; - Color RootColor; Time::point SearchTime; StateStackPtr SetupStates; } @@ -77,6 +76,9 @@ namespace { return (Depth) Reductions[PvNode][i][std::min(int(d) / ONE_PLY, 63)][std::min(mn, 63)]; } + // Tempo bonus. Must be handled by search to preserve eval symmetry. + const int Tempo = 17; + size_t MultiPV, PVIdx; TimeManager TimeMgr; double BestMoveChanges; @@ -180,12 +182,11 @@ uint64_t Search::perft(Position& pos, Depth depth) { void Search::think() { - RootColor = RootPos.side_to_move(); - TimeMgr.init(Limits, RootPos.game_ply(), RootColor); + TimeMgr.init(Limits, RootPos.game_ply(), RootPos.side_to_move()); int cf = Options["Contempt Factor"] * PawnValueEg / 100; // From centipawns - DrawValue[ RootColor] = VALUE_DRAW - Value(cf); - DrawValue[~RootColor] = VALUE_DRAW + Value(cf); + DrawValue[ RootPos.side_to_move()] = VALUE_DRAW - Value(cf); + DrawValue[~RootPos.side_to_move()] = VALUE_DRAW + Value(cf); if (RootMoves.empty()) { @@ -203,8 +204,8 @@ void Search::think() { log << "\nSearching: " << RootPos.fen() << "\ninfinite: " << Limits.infinite << " ponder: " << Limits.ponder - << " time: " << Limits.time[RootColor] - << " increment: " << Limits.inc[RootColor] + << " time: " << Limits.time[RootPos.side_to_move()] + << " increment: " << Limits.inc[RootPos.side_to_move()] << " moves to go: " << Limits.movestogo << "\n" << std::endl; } @@ -472,7 +473,7 @@ namespace { bestValue = -VALUE_INFINITE; ss->currentMove = ss->ttMove = (ss+1)->excludedMove = bestMove = MOVE_NONE; ss->ply = (ss-1)->ply + 1; - (ss+1)->skipNullMove = false; (ss+1)->reduction = DEPTH_ZERO; + (ss+1)->skipNullMove = (ss+1)->nullChild = false; (ss+1)->reduction = DEPTH_ZERO; (ss+2)->killers[0] = (ss+2)->killers[1] = MOVE_NONE; // Used to send selDepth info to GUI @@ -483,7 +484,7 @@ namespace { { // Step 2. Check for aborted search and immediate draw if (Signals.stop || pos.is_draw() || ss->ply > MAX_PLY) - return ss->ply > MAX_PLY && !inCheck ? evaluate(pos) : DrawValue[pos.side_to_move()]; + return ss->ply > MAX_PLY && !inCheck ? evaluate(pos) + Tempo : DrawValue[pos.side_to_move()]; // Step 3. Mate distance pruning. Even if we mate at the next move our score // would be at best mate_in(ss->ply+1), but if alpha is already bigger because @@ -538,7 +539,7 @@ namespace { { // Never assume anything on values stored in TT if ((ss->staticEval = eval = tte->eval_value()) == VALUE_NONE) - eval = ss->staticEval = evaluate(pos); + eval = ss->staticEval = evaluate(pos) + Tempo; // Can ttValue be used as a better position evaluation? if (ttValue != VALUE_NONE) @@ -547,7 +548,7 @@ namespace { } else { - eval = ss->staticEval = evaluate(pos); + eval = ss->staticEval = ss->nullChild ? -(ss-1)->staticEval + 2 * Tempo : evaluate(pos) + Tempo; TT.store(posKey, VALUE_NONE, BOUND_NONE, DEPTH_NONE, MOVE_NONE, ss->staticEval); } @@ -607,10 +608,10 @@ namespace { + int(eval - beta) / PawnValueMg * ONE_PLY; pos.do_null_move(st); - (ss+1)->skipNullMove = true; + (ss+1)->skipNullMove = (ss+1)->nullChild = true; nullValue = depth-R < ONE_PLY ? -qsearch(pos, ss+1, -beta, -beta+1, DEPTH_ZERO) : - search(pos, ss+1, -beta, -beta+1, depth-R, !cutNode); - (ss+1)->skipNullMove = false; + (ss+1)->skipNullMove = (ss+1)->nullChild = false; pos.undo_null_move(); if (nullValue >= beta) @@ -870,8 +871,9 @@ moves_loop: // When in check and at SpNode search starts from here // Decrease reduction for moves that escape a capture if ( ss->reduction + && type_of(move) == NORMAL && type_of(pos.piece_on(to_sq(move))) != PAWN - && pos.see_sign(make_move(to_sq(move), from_sq(move))) < 0) + && pos.see(make_move(to_sq(move), from_sq(move))) < 0) ss->reduction = std::max(DEPTH_ZERO, ss->reduction - ONE_PLY); Depth d = std::max(newDepth - ss->reduction, ONE_PLY); @@ -1064,7 +1066,7 @@ moves_loop: // When in check and at SpNode search starts from here // Check for an instant draw or if the maximum ply has been reached if (pos.is_draw() || ss->ply > MAX_PLY) - return ss->ply > MAX_PLY && !InCheck ? evaluate(pos) : DrawValue[pos.side_to_move()]; + return ss->ply > MAX_PLY && !InCheck ? evaluate(pos) + Tempo : DrawValue[pos.side_to_move()]; // Decide whether or not to include checks: this fixes also the type of // TT entry depth that we are going to use. Note that in qsearch we use @@ -1101,7 +1103,7 @@ moves_loop: // When in check and at SpNode search starts from here { // Never assume anything on values stored in TT if ((ss->staticEval = bestValue = tte->eval_value()) == VALUE_NONE) - ss->staticEval = bestValue = evaluate(pos); + ss->staticEval = bestValue = evaluate(pos) + Tempo; // Can ttValue be used as a better position evaluation? if (ttValue != VALUE_NONE) @@ -1109,7 +1111,7 @@ moves_loop: // When in check and at SpNode search starts from here bestValue = ttValue; } else - ss->staticEval = bestValue = evaluate(pos); + ss->staticEval = bestValue = ss->nullChild ? -(ss-1)->staticEval + 2 * Tempo : evaluate(pos) + Tempo; // Stand pat. Return immediately if static value is at least beta if (bestValue >= beta) @@ -1552,7 +1554,7 @@ void Thread::idle_loop() { if (Threads.size() > 2) for (size_t i = 0; i < Threads.size(); ++i) { - int size = Threads[i]->splitPointsSize; // Local copy + const int size = Threads[i]->splitPointsSize; // Local copy sp = size ? &Threads[i]->splitPoints[size - 1] : NULL; if ( sp