Vratko Polák wrote:But there probably is a good reason why the condition uses ttValue (minus margin), so I will think about it more deeply.
At higher depths, ttValue tends to be near previous beta, so it is probably not far away (compared to margin) from current alpha. Also, the margin is tuned for using ttValue. Except that, I have found no valid reason to use ttValue instead of alpha.
Anyway, I have run a third test for SMRC, this time it was Tinapa with verification reduction of (R+2). The original Stockfish lost +186 =592 -222 (LOS=11:88). So, the original would lost to combined entity "SMRC Stockfish with various null-move settings" by +564 =1801 -635 (LOS=8:91), and that means very high probability of at least one of the patches being better than original Stockfish. Here is the tested patch:
Code: Select all
diff -dur src-Ch/search.cpp src-TiAv0SmrcCh/search.cpp
--- src-Ch/search.cpp 2010-07-09 13:04:18.000000000 +0200
+++ src-TiAv0SmrcCh/search.cpp 2010-07-31 21:21:33.000000000 +0200
@@ -1058,7 +1058,7 @@
const TTEntry* tte;
Key posKey;
Move ttMove, move, excludedMove;
- Depth ext, newDepth;
+ Depth ext, newDepth, oldDepth = depth;
Value bestValue, value, oldAlpha;
Value refinedValue, nullValue, futilityValueScaled; // Non-PV specific
bool isCheck, singleEvasion, singularExtensionNode, moveIsCheck, captureOrPromotion, dangerous;
@@ -1185,7 +1185,7 @@
ss->currentMove = MOVE_NULL;
// Null move dynamic reduction based on depth
- int R = 3 + (depth >= 5 * OnePly ? depth / 8 : 0);
+ int R = 3 + (depth > 4*OnePly ? (int(depth) - 3*int(OnePly)/2) / (3*int(OnePly)) : 0); // inspired by Tinapa 1.01
// Null move dynamic reduction based on value
if (refinedValue - beta > PawnValueMidgame)
@@ -1206,11 +1206,13 @@
nullValue = beta;
// Do zugzwang verification search at high depths
- if (depth < 6 * OnePly)
+ if (depth-(R+2)*OnePly < OnePly)
return nullValue;
ss->skipNullMove = true;
- Value v = search<NonPV>(pos, ss, alpha, beta, depth-5*OnePly, ply);
+ (ss-1)->reduction += (R+2)*OnePly;
+ Value v = search<NonPV>(pos, ss, alpha, beta, depth-(R+2)*OnePly, ply);
+ (ss-1)->reduction -= (R+2)*OnePly;
ss->skipNullMove = false;
if (v >= beta)
@@ -1285,8 +1287,7 @@
// its siblings. To verify this we do a reduced search on all the other moves but the
// ttMove, if result is lower then ttValue minus a margin then we extend ttMove.
if ( singularExtensionNode
- && move == tte->move()
- && ext < OnePly)
+ && move == tte->move())
{
Value ttValue = value_from_tt(tte->value(), ply);
@@ -1295,12 +1296,17 @@
Value b = ttValue - SingularExtensionMargin;
ss->excludedMove = move;
ss->skipNullMove = true;
- Value v = search<NonPV>(pos, ss, b - 1, b, depth / 2, ply);
+ assert((depth + (ss-1)->reduction) / 2 <= depth);
+ Value v = search<NonPV>(pos, ss, b - 1, b, (depth + (ss-1)->reduction) / 2, ply);
ss->skipNullMove = false;
ss->excludedMove = MOVE_NONE;
if (v < ttValue - SingularExtensionMargin)
ext = OnePly;
+ else
+ singularExtensionNode = false;
}
+ else
+ singularExtensionNode = false;
}
newDepth = depth - OnePly + ext;
@@ -1396,6 +1402,19 @@
}
}
+ // Singular Move Reduction Cancellation.
+ if ( singularExtensionNode
+ && ttMove == move
+ && (ss-1)->reduction
+ && value >= beta)
+ {
+ depth += (ss-1)->reduction;
+ newDepth += (ss-1)->reduction;
+ assert(PvNode == NonPV);
+ value = newDepth < OnePly ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, Depth(0), ply+1)
+ : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
+ }
+
// Step 16. Undo move
pos.undo_move(move);
@@ -1444,7 +1463,7 @@
ValueType f = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT);
move = (bestValue <= oldAlpha ? MOVE_NONE : ss->bestMove);
- TT.store(posKey, value_to_tt(bestValue, ply), f, depth, move, ss->eval, ei.kingDanger[pos.side_to_move()]);
+ TT.store(posKey, value_to_tt(bestValue, ply), f, oldDepth, move, ss->eval, ei.kingDanger[pos.side_to_move()]);
// Update killers and history only for non capture moves that fails high
if (bestValue >= beta)