A fair bit of that was mistaken.
But regarding what I'd patch:
I and others want SF to print a new PV every time it changes its mind about the best move.
If a move fails high, SF will play that move if it's interrupted during resolution.
If the resolution fails low, SF will change its mind.
As a hack, I print the second case as an lowerbound like the first. There's no reason except to tell the GUI there's still no multipv score update, and to make it "look like" part of the same fail high resolution.
The diff in SearchLogs (also visible in UCI output) for Uly's position (which, argh, the forum software is re-indenting):
Code: Select all
--- SearchLog.txt-before 2011-04-13 23:59:42.053061006 -0700
+++ SearchLog.txt-after 2011-04-13 23:48:48.723061006 -0700
@@ -1,36 +1,38 @@
Searching: r2k1r2/pp1n1q1p/1npP4/4p1P1/4P3/1PbB2NP/P1P1Q1RK/3R4 b - -
infinite: 0 ponder: 0 time: 0 increment: 0 moves to go: 0
1 +0.35 00:00 152 Ke8
2 -0.27 00:00 196 Ke8 Nf5
2 +0.34 00:00 392 Qf3 Rf1 Qxe2 Rxf8+ Nxf8 Nxe2
3 -0.14 00:00 705 Qf3 Nf5 Qxe2 Bxe2
4 -0.12 00:00 1339 Qf3 Nf5 Qxe2 Bxe2 Nd5
5 +0.10 00:00 2080 Qf3 Nf5 Qxe2 Bxe2 Nc5 Bf3
6 +0.20 00:00 3717 Qf3 Qxf3 Rxf3 Nf5 Rf4 Kg3 Ke8
7 > +0.44 00:00 6469 Qf3 Qxf3 Rxf3 Nf5 Nc5 Be2 Rf4
7 +0.34 00:00 9714 Qf3 a3 Qxe2 Bxe2 Bb2 a4 Nc5 a5
7 > +0.69 00:00 13266 Bb4 Rf1 Qe6 Rxf8+ Nxf8
+ 7 > +0.34 00:00 15732 Qf3 a3 Qxe2 Bxe2 Bb2 a4 Nc5 a5
8 > +0.57 00:00 22579 Qf3 a3 Qxe2 Bxe2 a5 Nf5 Nc5
8 +0.49 00:00 23800 Qf3 a3 Qxe2 Bxe2 a5 Bg4 a4 Ne2 Bd4
9 +0.39 00:00 37107 Qf3 a4 Qxe2 Bxe2 Nc5 Bg4 Ke8 Bf5 Rg8 Ne2
10 +0.29 00:00 52600 Qf3 Qxf3 Rxf3 Be2 Rf4 Bg4 Bb4 Bf5 Nc8 Nh5 Rf3 Bg4
11 < +0.11 00:00 69915 Qf3 Qxf3 Rxf3 Be2 Rf4 Bg4 Bb4 Bf5 Nc8 Nh5 Rf3 Nf6
Nxf6 gxf6 Nxd6 Rg8+
11 +0.11 00:00 98989 Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Nh5 a6 Ng7 Nc5 Bf5
Rf7
12 +0.07 00:00 123993 Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Nc8 c3 Bc5 b4
Bxd6 Bxh7
13 +0.00 00:00 224376 Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
14 +0.00 00:00 287084 Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
15 +0.00 00:00 426958 Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
16 +0.00 00:01 833391 Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
17 +0.00 00:02 1493K Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
18 +0.00 00:04 2550K Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
19 +0.00 00:06 3886K Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
19 > +0.11 00:12 7460K a5 Nf5 a4 Qe3 axb3 cxb3 Bb4 Rc2 Qe6 Be2 Nd5
19 > +0.22 00:15 9357K a5 Nf5 a4 Qe3 axb3 cxb3 Bb4 Rc2 Qe6 Be2 Nd5
+19 > +0.00 00:32 18990K Qf3 Qxf3 Rxf3 Be2 Rf8 Bg4 Bb4 Bf5 Rf7 Be6 Rf8 Bf5
Nodes: 19001715
-Nodes/second: 604630
+Nodes/second: 591493
Best move: Qf3
Ponder move: Qxf3
So Uly could have used depth 7 here and saved people computer time.
The change:
Code: Select all
--- search.cpp 2011-04-13 23:46:13.063061007 -0700
+++ search.cpp-after 2011-04-13 23:42:45.393061006 -0700
@@ -811,6 +811,7 @@
// Sort the moves before to (re)search
rml.set_non_pv_scores(pos);
rml.sort();
+ int bestMoveIndex = 0;
// Step 10. Loop through all moves in the root move list
for (int i = 0; i < (int)rml.size() && !StopRequest; i++)
@@ -944,12 +945,22 @@
// Step 17. Check for new best move
if (value <= alpha && i >= MultiPV)
+ {
rml[i].pv_score = -VALUE_INFINITE;
+
+ if (ss->bestMove == move)
+ {
+ // If we're reverting a fail-high, send the GUI another
+ // "lower bound" line with the former PV.
+ cout << rml[bestMoveIndex].pv_info_to_uci(pos, alpha-1, alpha) << endl;
+ }
+ }
else
{
// PV move or new best move!
// Update PV
+ bestMoveIndex = i;
ss->bestMove = move;
rml[i].pv_score = value;
rml[i].extract_pv_from_tt(pos);
BTW, inside the new if clause, should we reset ss->bestMove to what it was before the fail-high SF is no longer trusting? What's the effect of setting it at the root?