StateInfo st;
Move ttMove, move;
Value staticValue, bestValue, value, futilityBase, futilityValue;
- bool isCheck, enoughMaterial, moveIsCheck;
+ bool isCheck, enoughMaterial, moveIsCheck, evasionPrunable;
const TTEntry* tte = NULL;
int moveCount = 0;
bool pvNode = (beta - alpha != 1);
}
}
- // Don't search captures and checks with negative SEE values
- if ( !isCheck
+ // Detect blocking evasions that are candidate to be pruned
+ evasionPrunable = isCheck
+ && bestValue != -VALUE_INFINITE
+ && !pos.move_is_capture(move)
+ && pos.type_of_piece_on(move_from(move)) != KING
+ && !pos.can_castle(pos.side_to_move());
+
+ // Don't search moves with negative SEE values
+ if ( (!isCheck || evasionPrunable)
&& move != ttMove
&& !move_is_promotion(move)
&& pos.see_sign(move) < 0)
// their idle loop. Also copy search stack tail for each slave thread.
for (int i = 0; i < ActiveThreads; i++)
{
+ if (splitPoint->slaves[i])
+ memcpy(splitPoint->sstack[i] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack));
+
if (i == master || splitPoint->slaves[i])
{
- Threads[i].workIsWaiting = true;
Threads[i].stop = false;
+ Threads[i].workIsWaiting = true; // This makes the slave to exit from idle_loop()
}
- if (splitPoint->slaves[i])
- memcpy(splitPoint->sstack[i] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack));
}
// Everything is set up. The master thread enters the idle loop, from