diff --git a/Rapfi/search/ab/search.cpp b/Rapfi/search/ab/search.cpp index d9f78e6..ab6f8fc 100644 --- a/Rapfi/search/ab/search.cpp +++ b/Rapfi/search/ab/search.cpp @@ -640,6 +640,17 @@ Value search(Board &board, SearchStack *ss, Value alpha, Value beta, Depth depth // Dive into vcf search when the depth reaches zero (~17 elo) if (depth <= 0.0f) { + (ss + 1)->staticEval = ss->staticEval = Evaluation::evaluate(board, alpha, beta); + + // Update bound using standing pat + if (oppo5) + beta = std::min(beta, ss->staticEval); + else + alpha = std::max(alpha, ss->staticEval); + // Prune directly if the value is already outside the window + if (alpha >= beta) + return alpha; + return oppo5 ? vcfdefend(board, ss, alpha, beta) : vcfsearch(board, ss, alpha, beta); } @@ -1505,7 +1516,7 @@ Value vcfsearch(Board &board, SearchStack *ss, Value alpha, Value beta, Depth de // Check if we reached the max ply if (ss->ply >= MAX_PLY) - return Evaluation::evaluate(board, alpha, beta); + return alpha; // Check for immediate winning if ((value = quickWinCheck(board, ss->ply, beta)) != VALUE_ZERO) { @@ -1546,9 +1557,11 @@ Value vcfsearch(Board &board, SearchStack *ss, Value alpha, Value beta, Depth de // Step 5. Static position evaluation if (ttHit) { // Never assume anything about values stored in TT - bestValue = ss->staticEval = ttEval; - if (bestValue == VALUE_NONE) - bestValue = ss->staticEval = Evaluation::evaluate(board, alpha, beta); + if (ttEval != VALUE_NONE) + ss->staticEval = ttEval; + else if (depth < 0) + ss->staticEval = Evaluation::evaluate(board, alpha, beta); + bestValue = ss->staticEval; // Try to use ttValue as a better eval estimation if (ttValue != VALUE_NONE @@ -1556,10 +1569,14 @@ Value vcfsearch(Board &board, SearchStack *ss, Value alpha, Value beta, Depth de bestValue = ttValue; } else { - // In case of null move search use previous static eval with a different sign - bestValue = ss->staticEval = (ss - 1)->currentMove == Pos::PASS - ? -(ss - 1)->staticEval - : Evaluation::evaluate(board, alpha, beta); + if (depth < 0) { + // In case of null move search use previous static eval with a different sign + ss->staticEval = (ss - 1)->currentMove == Pos::PASS + ? -(ss - 1)->staticEval + : Evaluation::evaluate(board, alpha, beta); + } + + bestValue = ss->staticEval; } // Stand pat. Return immediately if static value is at least beta @@ -1686,17 +1703,13 @@ Value vcfdefend(Board &board, SearchStack *ss, Value alpha, Value beta, Depth de thisThread->selDepth = ss->ply + 1; // Step 2. Check for immediate evaluation, draw and winning - // Return evaluation immediately if there is no vcf threat - if (!oppo5) - return Evaluation::evaluate(board, alpha, beta); - // Check if the board has been filled or we have reached the max game ply. if (board.movesLeft() == 0 || board.nonPassMoveCount() >= thisThread->options().maxMoves) return getDrawValue(board, thisThread->options(), ss->ply); - // Check if we reached the max ply - if (ss->ply >= MAX_PLY) - return Evaluation::evaluate(board, alpha, beta); + // Check if we reached the max ply or if there is no vcf threat + if (ss->ply >= MAX_PLY || !oppo5) + return beta; // Step 3. Search the only defence move Pos move = board.stateInfo().lastPattern4(oppo, A_FIVE);