From 4b703b142946ae03f03ca75738d927fd44a69b39 Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Tue, 9 Jul 2013 08:01:51 +0200 Subject: [PATCH] Revert previous patch Unfortunatly a reverse test at long TC failed: master^ vs master LLR: 1.37 (-2.94,2.94) Total: 33682 W: 6294 L: 6071 D: 21317 So becuase short TC score is 50% there is a good possibility patch is not scalable. So revert it. bench: 4507288 --- src/search.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index f24f33b9..220fff5e 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -100,6 +100,7 @@ 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); @@ -689,15 +690,18 @@ 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 return a fail + // 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 // 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 - && nullValue < beta - Value(128)) + && threatMove != MOVE_NONE + && allows(pos, (ss-1)->currentMove, threatMove)) return alpha; - - threatMove = (ss+1)->currentMove; } } @@ -1373,6 +1377,47 @@ 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). -- 2.39.2