It is more clear and should be a bit faster too.
Reverted also previous optimization patch because
seems do not increase actual speed.
No functional change.
Signed-off-by: Marco Costalba <mcostalba@gmail.com>
EvalInfo ei;
StateInfo st;
Move ttMove, move;
EvalInfo ei;
StateInfo st;
Move ttMove, move;
- Value staticValue, bestValue, value, futilityBase;
- bool isCheck, enoughMaterial, moveIsCheck, evasionPrunable;
- const TTEntry* tte = NULL;
- int moveCount = 0;
- int ply = pos.ply();
+ Value bestValue, value, futilityValue, futilityBase;
+ bool isCheck, deepChecks, enoughMaterial, moveIsCheck, evasionPrunable;
+ const TTEntry* tte;
- Value futilityValue = VALUE_INFINITE;
TM.incrementNodeCounter(pos.thread());
TM.incrementNodeCounter(pos.thread());
+ ss->pv[ply] = ss->pv[ply + 1] = ss->currentMove = MOVE_NONE;
+ ss->eval = VALUE_NONE;
// Check for an instant draw or maximum ply reached
if (pos.is_draw() || ply >= PLY_MAX - 1)
// Check for an instant draw or maximum ply reached
if (pos.is_draw() || ply >= PLY_MAX - 1)
// Evaluate the position statically
if (isCheck)
// Evaluate the position statically
if (isCheck)
- staticValue = -VALUE_INFINITE;
- else if (tte && tte->static_value() != VALUE_NONE)
- staticValue = tte->static_value();
- ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+ bestValue = futilityBase = -VALUE_INFINITE;
+ deepChecks = enoughMaterial = false;
- staticValue = evaluate(pos, ei);
-
- if (!isCheck)
- ss->eval = staticValue;
- update_gains(pos, (ss-1)->currentMove, (ss-1)->eval, ss->eval);
- }
+ if (tte && tte->static_value() != VALUE_NONE)
+ {
+ ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+ bestValue = tte->static_value();
+ }
+ else
+ bestValue = evaluate(pos, ei);
- // Initialize "stand pat score", and return it immediately if it is
- // at least beta.
- bestValue = staticValue;
+ ss->eval = bestValue;
+ update_gains(pos, (ss-1)->currentMove, (ss-1)->eval, ss->eval);
- if (bestValue >= beta)
- {
- // Store the score to avoid a future costly evaluation() call
- if (!isCheck && !tte)
- TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, Depth(-127*OnePly), MOVE_NONE, ss->eval, ei.kingDanger[pos.side_to_move()]);
+ // Stand pat. Return immediately if static value is at least beta
+ if (bestValue >= beta)
+ {
+ if (!tte) // FIXME, remove condition
+ TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, Depth(-127*OnePly), MOVE_NONE, ss->eval, ei.kingDanger[pos.side_to_move()]);
+
+ return bestValue;
+ }
+ if (PvNode && bestValue > alpha)
+ alpha = bestValue;
- if (PvNode && bestValue > alpha)
- alpha = bestValue;
+ // If we are near beta then try to get a cutoff pushing checks a bit further
+ deepChecks = (depth == -OnePly && bestValue >= beta - PawnValueMidgame / 8);
- // If we are near beta then try to get a cutoff pushing checks a bit further
- bool deepChecks = (depth == -OnePly && staticValue >= beta - PawnValueMidgame / 8);
+ // Futility pruning parameters, not needed when in check
+ futilityBase = bestValue + FutilityMarginQS + ei.kingDanger[pos.side_to_move()];
+ enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
+ }
// Initialize a MovePicker object for the current position, and prepare
// to search the moves. Because the depth is <= 0 here, only captures,
// Initialize a MovePicker object for the current position, and prepare
// to search the moves. Because the depth is <= 0 here, only captures,
// and we are near beta) will be generated.
MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H);
CheckInfo ci(pos);
// and we are near beta) will be generated.
MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H);
CheckInfo ci(pos);
- enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
- futilityBase = staticValue + FutilityMarginQS + ei.kingDanger[pos.side_to_move()];
// Loop through the moves until no moves remain or a beta cutoff occurs
while ( alpha < beta
// Loop through the moves until no moves remain or a beta cutoff occurs
while ( alpha < beta
moveIsCheck = pos.move_is_check(move, ci);
moveIsCheck = pos.move_is_check(move, ci);
- // Update current move
- moveCount++;
- ss->currentMove = move;
-
// Futility pruning
if ( !PvNode
// Futility pruning
if ( !PvNode
&& !isCheck
&& !moveIsCheck
&& move != ttMove
&& !isCheck
&& !moveIsCheck
&& move != ttMove
&& !move_is_promotion(move)
&& !pos.move_is_passed_pawn_push(move))
{
&& !move_is_promotion(move)
&& !pos.move_is_passed_pawn_push(move))
{
- // Can only decrease from previous move because of
- // MVV ordering so we don't need to recheck.
- if (futilityValue < alpha)
- continue;
-
futilityValue = futilityBase
+ pos.endgame_value_of_piece_on(move_to(move))
+ (move_is_ep(move) ? PawnValueEndgame : Value(0));
futilityValue = futilityBase
+ pos.endgame_value_of_piece_on(move_to(move))
+ (move_is_ep(move) ? PawnValueEndgame : Value(0));
&& pos.see_sign(move) < 0)
continue;
&& pos.see_sign(move) < 0)
continue;
+ // Update current move
+ ss->currentMove = move;
+
// Make and search the move
pos.do_move(move, st, ci, moveIsCheck);
value = -qsearch<PvNode>(pos, ss+1, -beta, -alpha, depth-OnePly);
// Make and search the move
pos.do_move(move, st, ci, moveIsCheck);
value = -qsearch<PvNode>(pos, ss+1, -beta, -alpha, depth-OnePly);
// All legal moves have been searched. A special case: If we're in check
// and no legal moves were found, it is checkmate.
// All legal moves have been searched. A special case: If we're in check
// and no legal moves were found, it is checkmate.
- if (!moveCount && isCheck) // Mate!
+ if (isCheck && bestValue == -VALUE_INFINITE)
return value_mated_in(ply);
// Update transposition table
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
if (bestValue <= oldAlpha)
return value_mated_in(ply);
// Update transposition table
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
if (bestValue <= oldAlpha)
- {
- // If bestValue isn't changed it means it is still the static evaluation
- // of the node, so keep this info to avoid a future evaluation() call.
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, d, MOVE_NONE, ss->eval, ei.kingDanger[pos.side_to_move()]);
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[ply];
else if (bestValue >= beta)
{
move = ss->pv[ply];