using Eval::evaluate;
using namespace Search;
+// For some reason argument-dependent lookup (ADL) doesn't work for Android's
+// STLPort, so explicitly qualify following functions.
+using std::count;
+using std::find;
+
namespace {
// Set to true to force running with one thread. Used for debugging
const Depth RazorDepth = 4 * ONE_PLY;
// Dynamic razoring margin based on depth
- inline Value razor_margin(Depth d) { return Value(0x200 + 0x10 * int(d)); }
+ inline Value razor_margin(Depth d) { return Value(512 + 16 * int(d)); }
// Maximum depth for use of dynamic threat detection when null move fails low
const Depth ThreatDepth = 5 * ONE_PLY;
// At Non-PV nodes we do an internal iterative deepening search
// when the static evaluation is bigger then beta - IIDMargin.
- const Value IIDMargin = Value(0x100);
+ const Value IIDMargin = Value(256);
// Minimum depth for use of singular extension
const Depth SingularExtensionDepth[] = { 8 * ONE_PLY, 6 * ONE_PLY };
// Futility margin for quiescence search
- const Value FutilityMarginQS = Value(0x80);
+ const Value FutilityMarginQS = Value(128);
// Futility lookup tables (initialized at startup) and their access functions
Value FutilityMargins[16][64]; // [depth][moveNumber]
}
// Test for a capture that triggers a pawn endgame
- if ( captureOrPromotion
- && type_of(pos.piece_on(to_sq(m))) != PAWN
+ if ( captureOrPromotion
+ && type_of(pos.piece_on(to_sq(m))) != PAWN
+ && !is_special(m)
&& ( pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK)
- - PieceValueMidgame[pos.piece_on(to_sq(m))] == VALUE_ZERO)
- && !is_special(m))
+ - PieceValueMidgame[pos.piece_on(to_sq(m))] == VALUE_ZERO))
return true;
return false;
TT.refresh(tte);
ss->currentMove = ttMove; // Can be MOVE_NONE
- if ( ttValue >= beta
- && ttMove
+ if ( ttValue >= beta
+ && ttMove
&& !pos.is_capture_or_promotion(ttMove)
- && ttMove != ss->killers[0])
+ && ttMove != ss->killers[0])
{
ss->killers[1] = ss->killers[0];
ss->killers[0] = ttMove;
// Update gain for the parent non-capture move given the static position
// evaluation before and after the move.
- if ( (move = (ss-1)->currentMove) != MOVE_NULL
- && (ss-1)->eval != VALUE_NONE
- && ss->eval != VALUE_NONE
+ if ( (move = (ss-1)->currentMove) != MOVE_NULL
+ && (ss-1)->eval != VALUE_NONE
+ && ss->eval != VALUE_NONE
&& !pos.captured_piece_type()
&& !is_special(move))
{
futilityBase = ss->eval + ss->evalMargin;
singularExtensionNode = !RootNode
&& !SpNode
- && depth >= SingularExtensionDepth[PvNode]
- && ttMove != MOVE_NONE
+ && depth >= SingularExtensionDepth[PvNode]
+ && ttMove != MOVE_NONE
&& !excludedMove // Recursive singular search is not allowed
&& (tte->type() & BOUND_LOWER)
- && tte->depth() >= depth - 3 * ONE_PLY;
+ && tte->depth() >= depth - 3 * ONE_PLY;
// Step 11. Loop through moves
// Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs
- while ( bestValue < beta
+ while ( bestValue < beta
&& (move = mp.next_move()) != MOVE_NONE
&& !thisThread->cutoff_occurred()
&& !Signals.stop)
ext = ONE_PLY;
else if (givesCheck && pos.see_sign(move) >= 0)
- ext = PvNode ? ONE_PLY : ONE_PLY / 2;
+ ext = ONE_PLY / 2;
// Singular extension search. If all moves but one fail low on a search of
// (alpha-s, beta-s), and just one fails high on (alpha, beta), then that move
// is singular and should be extended. To verify this we do a reduced search
// on all the other moves but the ttMove, if result is lower than ttValue minus
// a margin then we extend ttMove.
- if ( singularExtensionNode
+ if ( singularExtensionNode
&& !ext
- && move == ttMove
- && pos.pl_move_is_legal(move, ci.pinned))
+ && move == ttMove
+ && pos.pl_move_is_legal(move, ci.pinned))
{
if (abs(ttValue) < VALUE_KNOWN_WIN)
{
// Step 15. Reduced depth search (LMR). If the move fails high will be
// re-searched at full depth.
- if ( depth > 3 * ONE_PLY
+ if ( depth > 3 * ONE_PLY
&& !isPvMove
&& !captureOrPromotion
&& !dangerous
// Step 19. Check for split
if ( !SpNode
- && depth >= Threads.min_split_depth()
- && bestValue < beta
- && Threads.available_slave_exists(thisThread)
+ && depth >= Threads.min_split_depth()
+ && bestValue < beta
+ && Threads.available_slave_exists(thisThread)
&& !Signals.stop
&& !thisThread->cutoff_occurred())
bestValue = Threads.split<FakeSplit>(pos, ss, alpha, beta, bestValue, &bestMove,
// Detect non-capture evasions that are candidate to be pruned
evasionPrunable = !PvNode
- && inCheck
- && bestValue > VALUE_MATED_IN_MAX_PLY
+ && inCheck
+ && bestValue > VALUE_MATED_IN_MAX_PLY
&& !pos.is_capture(move)
&& !pos.can_castle(pos.side_to_move());
// Wake up master thread so to allow it to return from the idle loop in
// case we are the last slave of the split point.
- if ( Threads.use_sleeping_threads()
- && this != sp->master
+ if ( Threads.use_sleeping_threads()
+ && this != sp->master
&& !sp->master->is_searching)
sp->master->wake_up();