// Init futility margins array
for (d = 0; d < 16; d++) for (mc = 0; mc < 64; mc++)
- FutilityMarginsMatrix[d][mc] = 112 * int(log(double(d * d) / 2) / log(2.0) + 1) - 8 * mc + 45;
+ FutilityMarginsMatrix[d][mc] = 112 * int(log(double(d * d) / 2) / log(2.0) + 1.001) - 8 * mc + 45;
// Init futility move count array
for (d = 0; d < 32; d++)
}
-// SearchStack::init() initializes a search stack. Used at the beginning of a
-// new search from the root.
+// SearchStack::init() initializes a search stack entry.
+// Called at the beginning of search() when starting to examine a new node.
void SearchStack::init() {
- pv[0] = pv[1] = MOVE_NONE;
+ pv[0] = pv[1] = bestMove = MOVE_NONE;
currentMove = threatMove = MOVE_NONE;
reduction = Depth(0);
eval = VALUE_NONE;
}
+// SearchStack::initKillers() initializes killers for a search stack entry
void SearchStack::initKillers() {
mateKiller = MOVE_NONE;
search<PvNode>(pos, ss, alpha, beta, d, ply);
ss->skipNullMove = false;
- ttMove = ss->pv[0];
+ ttMove = ss->bestMove;
tte = TT.retrieve(posKey);
}
if (AbortSearch || TM.thread_should_stop(threadID))
return bestValue;
- if (bestValue <= oldAlpha)
- TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE, ss->eval, ei.kingDanger[pos.side_to_move()]);
+ ValueType f = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT);
+ move = (bestValue <= oldAlpha ? MOVE_NONE : ss->bestMove);
+ TT.store(posKey, value_to_tt(bestValue, ply), f, depth, move, ss->eval, ei.kingDanger[pos.side_to_move()]);
- else if (bestValue >= beta)
+ // Update killers and history only for non capture moves that fails high
+ if (bestValue >= beta)
{
TM.incrementBetaCounter(pos.side_to_move(), depth, threadID);
- move = ss->pv[0];
- TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move, ss->eval, ei.kingDanger[pos.side_to_move()]);
if (!pos.move_is_capture_or_promotion(move))
{
update_history(pos, move, depth, movesSearched, moveCount);
update_killers(move, ss);
}
}
- else
- TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss->pv[0], ss->eval, ei.kingDanger[pos.side_to_move()]);
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
Value oldAlpha = alpha;
TM.incrementNodeCounter(pos.thread());
- ss->pv[0] = ss->pv[1] = ss->currentMove = MOVE_NONE;
+ ss->pv[0] = ss->pv[1] = ss->bestMove = ss->currentMove = MOVE_NONE;
ss->eval = VALUE_NONE;
// Check for an instant draw or maximum ply reached
// Update transposition table
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
- if (bestValue <= oldAlpha)
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, d, MOVE_NONE, ss->eval, ei.kingDanger[pos.side_to_move()]);
- else if (bestValue >= beta)
- {
- move = ss->pv[0];
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move, ss->eval, ei.kingDanger[pos.side_to_move()]);
+ ValueType f = (bestValue <= oldAlpha ? VALUE_TYPE_UPPER : bestValue >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT);
+ TT.store(pos.get_key(), value_to_tt(bestValue, ply), f, d, ss->bestMove, ss->eval, ei.kingDanger[pos.side_to_move()]);
- // Update killers only for good checking moves
- if (!pos.move_is_capture_or_promotion(move))
- update_killers(move, ss);
- }
- else
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss->pv[0], ss->eval, ei.kingDanger[pos.side_to_move()]);
+ // Update killers only for checking moves that fails high
+ if ( bestValue >= beta
+ && !pos.move_is_capture_or_promotion(ss->bestMove))
+ update_killers(ss->bestMove, ss);
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
Move* src = (ss+1)->pv;
Move* dst = ss->pv;
- *dst = ss->currentMove;
+ *dst = ss->bestMove = ss->currentMove;
do
*++dst = *src;
Move* dst = ss->pv;
Move* pdst = pss->pv;
- *dst = *pdst = ss->currentMove;
+ *dst = *pdst = pss->bestMove = ss->bestMove = ss->currentMove;
do
*++dst = *++pdst = *src;
if (*dangerous)
{
- if (moveIsCheck && pos.see_sign(m)>= 0)
+ if (moveIsCheck && pos.see_sign(m) >= 0)
result += CheckExtension[PvNode];
if (singleEvasion)