First idea is about what to return when we have nullValue>=beta. When testing 4 different patches to improve stability (round robin of matches of 1000 games repeating from first 500 gaviota starters), the best with +5(+-7) elo over original stockfish (los 81:18) was this patch
Code: Select all
diff -dur src-Ch/search.cpp src-Pv6Ch/search.cpp
--- src-Ch/search.cpp 2010-04-20 00:45:49.000000000 +0200
+++ src-Pv6Ch/search.cpp 2010-06-19 19:15:20.000000000 +0200
@@ -1334,7 +1334,8 @@
if (v < rbeta)
// Logically we should return (v + razor_margin(depth)), but
// surprisingly this did slightly weaker in tests.
- return v;
+ //return v;
+ return v + razor_margin(depth);
}
// Step 7. Static null move pruning
@@ -1387,6 +1388,18 @@
&& !AbortSearch
&& !TM.thread_should_stop(threadID))
{
+ // Reduce nullValue to not contradict null move conditions when used as lower bound.
+ if (beta < refinedValue - PawnValueMidgame)
+ {
+ if (nullValue >= refinedValue - PawnValueMidgame)
+ nullValue = Max(beta, refinedValue - PawnValueMidgame - 4);
+ }
+ else
+ {
+ nullValue = Min(nullValue, refinedValue + (depth >= 4 * OnePly ? NullMoveMargin : 0));
+ assert(nullValue >= beta);
+ }
+
assert(value_to_tt(nullValue, ply) == nullValue);
TT.store(posKey, nullValue, VALUE_TYPE_NS_LO, depth, MOVE_NONE);
When I saw that I am not getting stability, just elo, I focused more on null move search. So I asked myself, why do we do verification search with reduction of 5*OnePly when null move search was reduced by R*OnePly? Patch:
Code: Select all
diff -dur src-Ch/search.cpp src-Nmv0Ch/search.cpp
--- src-Ch/search.cpp 2010-04-20 00:45:49.000000000 +0200
+++ src-Nmv0Ch/search.cpp 2010-07-01 22:44:01.000000000 +0200
@@ -1382,8 +1382,8 @@
// Do zugzwang verification search for high depths, don't store in TT
// if search was stopped.
- if ( ( depth < 6 * OnePly
- || search(pos, ss, beta, depth-5*OnePly, ply, false, threadID) >= beta)
+ if ( ( depth-(R+2)*OnePly < OnePly
+ || search(pos, ss, beta, depth-(R+2)*OnePly, ply, false, threadID) >= beta)
&& !AbortSearch
&& !TM.thread_should_stop(threadID))
{
Code: Select all
diff -dur src-Ch/search.cpp src-Nmv1Ch/search.cpp
--- src-Ch/search.cpp 2010-04-20 00:45:49.000000000 +0200
+++ src-Nmv1Ch/search.cpp 2010-07-01 22:43:59.000000000 +0200
@@ -1376,14 +1376,24 @@
if (nullValue >= beta)
{
+ // Reduce nullValue to not contradict null move conditions when used as lower bound.
+ if (beta < refinedValue - PawnValueMidgame)
+ {
+ if (nullValue >= refinedValue - PawnValueMidgame)
+ nullValue = Max(beta, refinedValue - PawnValueMidgame - 8);
+ }
+ else
+ {
+ nullValue = Min(nullValue, refinedValue + (depth >= 4 * OnePly ? NullMoveMargin : 0));
+ assert(nullValue >= beta);
+ }
// Do not return unproven mate scores
- if (nullValue >= value_mate_in(PLY_MAX))
- nullValue = beta;
+ assert(nullValue < value_mate_in(PLY_MAX));
// Do zugzwang verification search for high depths, don't store in TT
// if search was stopped.
- if ( ( depth < 6 * OnePly
- || search(pos, ss, beta, depth-5*OnePly, ply, false, threadID) >= beta)
+ if ( ( depth-(R+2)*OnePly < OnePly
+ || search(pos, ss, beta, depth-(R+2)*OnePly, ply, false, threadID) >= beta)
&& !AbortSearch
&& !TM.thread_should_stop(threadID))
{