+ // Step 14. Reduced depth search
+ // If the move fails high will be re-searched at full depth.
+ bool doFullDepthSearch = true;
+
+ if ( depth >= 3 * ONE_PLY
+ && !captureOrPromotion
+ && !dangerous
+ && !move_is_castle(move)
+ && !move_is_killer(move, ss))
+ {
+ ss->reduction = reduction<PvNode>(depth, moveCount);
+ if (ss->reduction)
+ {
+ Depth d = newDepth - ss->reduction;
+ value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
+ : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, ply+1);
+
+ doFullDepthSearch = (value > alpha);
+ }
+
+ // The move failed high, but if reduction is very big we could
+ // face a false positive, retry with a less aggressive reduction,
+ // if the move fails high again then go with full depth search.
+ if (doFullDepthSearch && ss->reduction > 2 * ONE_PLY)
+ {
+ assert(newDepth - ONE_PLY >= ONE_PLY);
+
+ ss->reduction = ONE_PLY;
+ value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, ply+1);
+ doFullDepthSearch = (value > alpha);
+ }
+ ss->reduction = DEPTH_ZERO; // Restore original reduction
+ }
+
+ // Step 15. Full depth search
+ if (doFullDepthSearch)
+ {
+ value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
+ : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
+
+ // 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 = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
+ : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
+ }