Skip to content

Commit

Permalink
reduce full depth by 1 if reduction is high
Browse files Browse the repository at this point in the history
and fix max LMR extension to 1
and remove decreasing reduction for false forbidden move in Renju

test r15
  • Loading branch information
dhbloo committed Jun 12, 2024
1 parent 1bec5d0 commit 010470d
Showing 1 changed file with 70 additions and 69 deletions.
139 changes: 70 additions & 69 deletions Rapfi/search/ab/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ Value search(Board &board, SearchStack *ss, Value alpha, Value beta, Depth depth
searchData->rootDepth,
move);

// Initialize various heruistic information
// Initialize heruistic information
ss->moveCount = ++moveCount;
ss->moveP4[BLACK] = board.cell(move).pattern4[BLACK];
ss->moveP4[WHITE] = board.cell(move).pattern4[WHITE];
Expand All @@ -998,6 +998,13 @@ Value search(Board &board, SearchStack *ss, Value alpha, Value beta, Depth depth
int distSelf = Pos::distance(move, (ss - 2)->currentMove);
bool distract = distSelf > (Rule == RENJU ? 5 : 4) && distOppo > 4;

Depth r = reduction<Rule, PvNode>(searcher->reductions,
depth,
moveCount,
improvement,
beta - alpha,
searchData->rootDelta);

// Step 12. Pruning at shallow depth
// Do pruning only when we have non-losing moves, otherwise we may have a false mate.
if (!RootNode && bestValue > VALUE_MATED_IN_MAX_PLY) {
Expand Down Expand Up @@ -1101,73 +1108,56 @@ Value search(Board &board, SearchStack *ss, Value alpha, Value beta, Depth depth
board.move<Rule>(move);
TT.prefetch(board.zobristKey());

bool doFullDepthSearch;
// Step 15. Late move reduction (LMR). Moves are searched with a reduced
// depth and will be re-searched at full depth if fail high.
if (depth > 2 && moveCount > 1 + 2 * RootNode
&& (!importantMove // do LMR for non important move
|| distract // do LMR for distract move
|| cutNode // do LMR for all moves in cut node
|| moveCount >= lateMoveCount<Rule>(depth, improvement > 0) // do LMR for late move
|| mp.hasPolicyScore() // do LMR for low policy
&& mp.curMoveScore() < policyReductionScore<Rule>(depth))) {
Value delta = beta - alpha;
Depth r = reduction<Rule, PvNode>(searcher->reductions,
depth,
moveCount,
improvement,
delta,
searchData->rootDelta);

// Policy based reduction
if (mp.hasPolicyScore())
r += policyReduction<Rule>(mp.curMoveScore()
* (0.1f / Evaluation::PolicyBuffer::ScoreScale));

// Dynamic reduction based on complexity
r += complexity * complexityReduction<Rule>(trivialMove, importantMove, distract);

// Decrease reduction if position is or has been on the PV and
// the node is not likely to fail low.
if (ss->ttPv && !likelyFailLow)
r -= 1.0f;

// Increase reduction for nodes that does not improve root alpha
if (!RootNode && (ss->ply & 1) && bestValue >= -searchData->rootAlpha)
r += 1.0f;

// Increase reduction for cut nodes if is not killer moves
if (cutNode && !(!oppo4 && ss->isKiller(move) && ss->moveP4[self] < H_FLEX3))
r += 1.7f;

// Increase reduction for useless defend move (~25 elo)
if (oppo4 && ss->moveP4[oppo] < E_BLOCK4)
r += (distOppo > 4) * 2 + (distSelf > 4);

// Decrease reduction for continous attack
if (!oppo4 && (ss - 2)->moveP4[self] >= H_FLEX3
&& (ss->moveP4[self] >= H_FLEX3 || distSelf <= 4 && ss->moveP4[self] >= J_FLEX2_2X))
r -= 0.75f;

if constexpr (Rule == Rule::RENJU) {
// Decrease reduction for false forbidden move in Renju
if (ss->moveP4[BLACK] == FORBID)
r -= 1.0f;
}
// Policy based reduction
if (mp.hasPolicyScore())
r += policyReduction<Rule>(mp.curMoveScore()
* (0.1f / Evaluation::PolicyBuffer::ScoreScale));

// Update statScore of this node
ss->statScore = searchData->mainHistory[self][move][HIST_ATTACK]
+ searchData->mainHistory[self][move][HIST_QUIET] * 4 / 5 - 3391;
// Dynamic reduction based on complexity
r += complexity * complexityReduction<Rule>(trivialMove, importantMove, distract);

// Decrease/increase reduction for moves with a good/bad history
// Use less stat score at higher depths
r -= ss->statScore * (1.0f / (12633 + 4055 * (depth > 7)));
// Decrease reduction if position is or has been on the PV and
// the node is not likely to fail low.
if (ss->ttPv && !likelyFailLow)
r -= 1.0f;

// Allow LMR to do deeper search in some circumstances
int deeper = r < -1 && moveCount <= 4 ? 1 : 0;
// Increase reduction for nodes that does not improve root alpha
if (!RootNode && (ss->ply & 1) && bestValue >= -searchData->rootAlpha)
r += 1.0f;

// Increase reduction for cut nodes if is not killer moves
if (cutNode && !(!oppo4 && ss->isKiller(move) && ss->moveP4[self] < H_FLEX3))
r += 1.7f;

// Increase reduction for useless defend move (~25 elo)
if (oppo4 && ss->moveP4[oppo] < E_BLOCK4)
r += (distOppo > 4) * 2 + (distSelf > 4);

// Decrease reduction for continous attack
if (!oppo4 && (ss - 2)->moveP4[self] >= H_FLEX3
&& (ss->moveP4[self] >= H_FLEX3 || distSelf <= 4 && ss->moveP4[self] >= J_FLEX2_2X))
r -= 0.75f;

//if constexpr (Rule == Rule::RENJU) {
// // Decrease reduction for false forbidden move in Renju
// if (ss->moveP4[BLACK] == FORBID)
// r -= 1.0f;
//}

// Update statScore of this node
ss->statScore = searchData->mainHistory[self][move][HIST_ATTACK]
+ searchData->mainHistory[self][move][HIST_QUIET] * 4 / 5 - 3391;

// Decrease/increase reduction for moves with a good/bad history
// Use less stat score at higher depths
r -= ss->statScore * (1.0f / (12633 + 4055 * (depth > 7)));

// Step 15. Late move reduction (LMR). Moves are searched with a reduced
// depth and will be re-searched at full depth if fail high.
if (depth >= 2 && moveCount > 1 + RootNode) {
// Allow LMR to do deeper search in some circumstances
// Clamp the LMR depth to newDepth (no depth less than one)
Depth d = std::max(std::min(newDepth - r, newDepth + deeper), 1.0f);
Depth d = std::max(std::min(newDepth - r, newDepth + 1), 1.0f);

value = -search<Rule, NonPV>(board, ss + 1, -(alpha + 1), -alpha, d, true);

Expand All @@ -1179,16 +1169,27 @@ Value search(Board &board, SearchStack *ss, Value alpha, Value beta, Depth depth
else
ss->extraExtension += std::max(ext - 1.0f, 0.0f);
newDepth += ext;
}

doFullDepthSearch = (value > alpha && d < newDepth);
if (d < newDepth)
value = -search<Rule, NonPV>(board,
ss + 1,
-(alpha + 1),
-alpha,
newDepth,
!cutNode);
}
}
else
doFullDepthSearch = !PvNode || moveCount > 1;

// Step 16. Full depth search when LMR is skipped or fails high
if (doFullDepthSearch)
value = -search<Rule, NonPV>(board, ss + 1, -(alpha + 1), -alpha, newDepth, !cutNode);
else if (!PvNode || moveCount > 1) {
// If expected reduction is high, we reduce search depth by 1 here
value = -search<Rule, NonPV>(board,
ss + 1,
-(alpha + 1),
-alpha,
newDepth - (r >= 5),
!cutNode);
}

// For balance move mode, we also check if a move can trigger beta cut
// (which is too good to be balanced), so we can safely discard this move.
Expand Down

0 comments on commit 010470d

Please sign in to comment.