Simplify "fail high upon reduction" in null search
authorMarco Costalba <mcostalba@gmail.com>
Mon, 8 Jul 2013 05:23:30 +0000 (07:23 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 8 Jul 2013 05:23:30 +0000 (07:23 +0200)
Do not use threat move to detect the condition. This
let us to retire the big allows() function.

Test at short TC was within 50% score:
LLR: -2.95 (-2.94,2.94)
Total: 38272 W: 7941 L: 7940 D: 22391

To be verified with reverse long TC

bench: 4191565

src/search.cpp

index 220fff5e10d03e50e74e4052c2f3c9f97bbfd380..f24f33b91cfb48d63eb1ec60e81c7d90caff663b 100644 (file)
@@ -100,7 +100,6 @@ namespace {
   Value value_to_tt(Value v, int ply);
   Value value_from_tt(Value v, int ply);
   bool check_is_dangerous(const Position& pos, Move move, Value futilityBase, Value beta);
-  bool allows(const Position& pos, Move first, Move second);
   bool refutes(const Position& pos, Move first, Move second);
   string uci_pv(const Position& pos, int depth, Value alpha, Value beta);
 
@@ -690,18 +689,15 @@ namespace {
         else
         {
             // The null move failed low, which means that we may be faced with
-            // some kind of threat. If the previous move was reduced, check if
-            // the move that refuted the null move was somehow connected to the
-            // move which was reduced. If a connection is found, return a fail
+            // some kind of threat. If the previous move was reduced return a fail
             // low score (which will cause the reduced move to fail high in the
             // parent node, which will trigger a re-search with full depth).
-            threatMove = (ss+1)->currentMove;
-
             if (   depth < 5 * ONE_PLY
                 && (ss-1)->reduction
-                && threatMove != MOVE_NONE
-                && allows(pos, (ss-1)->currentMove, threatMove))
+                && nullValue < beta - Value(128))
                 return alpha;
+
+            threatMove = (ss+1)->currentMove;
         }
     }
 
@@ -1377,47 +1373,6 @@ split_point_start: // At split points actual search starts from here
   }
 
 
-  // allows() tests whether the 'first' move at previous ply somehow makes the
-  // 'second' move possible, for instance if the moving piece is the same in
-  // both moves. Normally the second move is the threat (the best move returned
-  // from a null search that fails low).
-
-  bool allows(const Position& pos, Move first, Move second) {
-
-    assert(is_ok(first));
-    assert(is_ok(second));
-    assert(color_of(pos.piece_on(from_sq(second))) == ~pos.side_to_move());
-    assert(color_of(pos.piece_on(to_sq(first))) == ~pos.side_to_move());
-
-    Square m1from = from_sq(first);
-    Square m2from = from_sq(second);
-    Square m1to = to_sq(first);
-    Square m2to = to_sq(second);
-
-    // The piece is the same or second's destination was vacated by the first move
-    if (m1to == m2from || m2to == m1from)
-        return true;
-
-    // Second one moves through the square vacated by first one
-    if (between_bb(m2from, m2to) & m1from)
-      return true;
-
-    // Second's destination is defended by the first move's piece
-    Bitboard m1att = pos.attacks_from(pos.piece_on(m1to), m1to, pos.pieces() ^ m2from);
-    if (m1att & m2to)
-        return true;
-
-    // Second move gives a discovered check through the first's checking piece
-    if (m1att & pos.king_square(pos.side_to_move()))
-    {
-        assert(between_bb(m1to, pos.king_square(pos.side_to_move())) & m2from);
-        return true;
-    }
-
-    return false;
-  }
-
-
   // refutes() tests whether a 'first' move is able to defend against a 'second'
   // opponent's move. In this case will not be pruned. Normally the second move
   // is the threat (the best move returned from a null search that fails low).