#include <cassert>
#include <cmath>
#include <cstring>
-#include <exception>
#include <iostream>
#include <sstream>
bool refutes(const Position& pos, Move first, Move second);
string uci_pv(const Position& pos, int depth, Value alpha, Value beta);
- class stop : public std::exception {};
-
struct Skill {
Skill(int l) : level(l), best(MOVE_NONE) {}
~Skill() {
// Init futility move count array
for (d = 0; d < 32; d++)
{
- FutilityMoveCounts[1][d] = int(3.001 + 0.3 * pow(double(d), 1.8));
- FutilityMoveCounts[0][d] = d < 5 ? FutilityMoveCounts[1][d]
- : 3 * FutilityMoveCounts[1][d] / 4;
+ FutilityMoveCounts[0][d] = int(3.001 + 0.3 * pow(double(d ), 1.8)) * (d < 5 ? 4 : 3) / 4;
+ FutilityMoveCounts[1][d] = int(3.001 + 0.3 * pow(double(d + 0.98), 1.8));
}
}
void id_loop(Position& pos) {
- Stack stack[MAX_PLY_PLUS_3], *ss = stack+2; // To allow referencing (ss-2)
+ Stack stack[MAX_PLY_PLUS_6], *ss = stack+2; // To allow referencing (ss-2)
int depth, prevBestMoveChanges;
Value bestValue, alpha, beta, delta;
// research with bigger window until not failing high/low anymore.
while (true)
{
- try {
- bestValue = search<Root>(pos, ss, alpha, beta, depth * ONE_PLY, false);
- } catch (stop&) {}
+ bestValue = search<Root>(pos, ss, alpha, beta, depth * ONE_PLY, false);
// Bring to front the best move. It is critical that sorting is
// done with a stable algorithm because all the values but the first
if (PvNode && thisThread->maxPly < ss->ply)
thisThread->maxPly = ss->ply;
- if (Signals.stop || thisThread->cutoff_occurred())
- throw stop();
-
if (!RootNode)
{
// Step 2. Check for aborted search and immediate draw
- if (pos.is_draw() || ss->ply > MAX_PLY)
+ if (Signals.stop || pos.is_draw() || ss->ply > MAX_PLY)
return DrawValue[pos.side_to_move()];
// Step 3. Mate distance pruning. Even if we mate at the next move our score
// Step 8. Null move search with verification search (is omitted in PV nodes)
if ( !PvNode
&& !ss->skipNullMove
- && depth > ONE_PLY
+ && depth >= 2 * ONE_PLY
&& eval >= beta
&& abs(beta) < VALUE_MATE_IN_MAX_PLY
&& pos.non_pawn_material(pos.side_to_move()))
alpha = splitPoint->alpha;
}
+ // Finished searching the move. If Signals.stop is true, the search
+ // was aborted because the user interrupted the search or because we
+ // ran out of time. In this case, the return value of the search cannot
+ // be trusted, and we don't update the best move and/or PV.
+ if (Signals.stop || thisThread->cutoff_occurred())
+ return value; // To avoid returning VALUE_INFINITE
+
if (RootNode)
{
RootMove& rm = *std::find(RootMoves.begin(), RootMoves.end(), move);
&& !givesCheck
&& move != ttMove
&& type_of(move) != PROMOTION
+ && futilityBase > -VALUE_KNOWN_WIN
&& !pos.is_passed_pawn_push(move))
{
futilityValue = futilityBase
void RootMove::extract_pv_from_tt(Position& pos) {
- StateInfo state[MAX_PLY_PLUS_3], *st = state;
+ StateInfo state[MAX_PLY_PLUS_6], *st = state;
const TTEntry* tte;
int ply = 0;
Move m = pv[0];
void RootMove::insert_pv_in_tt(Position& pos) {
- StateInfo state[MAX_PLY_PLUS_3], *st = state;
+ StateInfo state[MAX_PLY_PLUS_6], *st = state;
const TTEntry* tte;
int ply = 0;
Threads.mutex.unlock();
- Stack stack[MAX_PLY_PLUS_3], *ss = stack+2; // To allow referencing (ss-2)
+ Stack stack[MAX_PLY_PLUS_6], *ss = stack+2; // To allow referencing (ss-2)
Position pos(*sp->pos, this);
std::memcpy(ss-2, sp->ss-2, 5 * sizeof(Stack));
activePosition = &pos;
- try {
- switch (sp->nodeType) {
- case Root:
- search<SplitPointRoot>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode);
- break;
- case PV:
- search<SplitPointPV>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode);
- break;
- case NonPV:
- search<SplitPointNonPV>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode);
- break;
- default:
- assert(false);
- }
-
- assert(searching);
- }
- catch (stop&) {
- sp->mutex.lock(); // Exception is thrown out of lock
+ switch (sp->nodeType) {
+ case Root:
+ search<SplitPointRoot>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode);
+ break;
+ case PV:
+ search<SplitPointPV>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode);
+ break;
+ case NonPV:
+ search<SplitPointNonPV>(pos, ss, sp->alpha, sp->beta, sp->depth, sp->cutNode);
+ break;
+ default:
+ assert(false);
}
+ assert(searching);
+
searching = false;
activePosition = NULL;
sp->slavesMask &= ~(1ULL << idx);