mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 11:39:15 +00:00
Sync qsearch with search
So to have the same layout and be as much similar as possible. The only functional change is that now we try ttMove as first also in PV nodes and at the end we save the ttMove, as it happens in search. This should have almost zero impact on ELO but it seems the correct thing to do. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
dba072c449
commit
5b21c10afb
1 changed files with 42 additions and 48 deletions
|
@ -1400,7 +1400,7 @@ namespace {
|
|||
const int FutilityMoveCountMargin = 3 + (1 << (3 * int(depth) / 8));
|
||||
const int FutilityValueMargin = 112 * bitScanReverse32(int(depth) * int(depth) / 2);
|
||||
|
||||
// Enhance position with TT value if possible
|
||||
// Enhance score accuracy with TT value if possible
|
||||
futilityValue = staticValue + FutilityValueMargin;
|
||||
staticValue = refine_eval(tte, staticValue, ply);
|
||||
|
||||
|
@ -1492,8 +1492,8 @@ namespace {
|
|||
if (move == excludedMove)
|
||||
continue;
|
||||
|
||||
singleEvasion = (isCheck && mp.number_of_evasions() == 1);
|
||||
moveIsCheck = pos.move_is_check(move, ci);
|
||||
singleEvasion = (isCheck && mp.number_of_evasions() == 1);
|
||||
captureOrPromotion = pos.move_is_capture_or_promotion(move);
|
||||
|
||||
// Decide the new search depth
|
||||
|
@ -1606,9 +1606,9 @@ namespace {
|
|||
break;
|
||||
}
|
||||
|
||||
// All legal moves have been searched. A special case: If there were
|
||||
// All legal moves have been searched. A special case: If there were
|
||||
// no legal moves, it must be mate or stalemate.
|
||||
if (moveCount == 0)
|
||||
if (!moveCount)
|
||||
return excludedMove ? beta - 1 : (pos.is_check() ? value_mated_in(ply) : VALUE_DRAW);
|
||||
|
||||
// If the search is not aborted, update the transposition table,
|
||||
|
@ -1622,12 +1622,13 @@ namespace {
|
|||
{
|
||||
BetaCounter.add(pos.side_to_move(), depth, threadID);
|
||||
move = ss[ply].pv[ply];
|
||||
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
|
||||
if (!pos.move_is_capture_or_promotion(move))
|
||||
{
|
||||
update_history(pos, move, depth, movesSearched, moveCount);
|
||||
update_killers(move, ss[ply]);
|
||||
}
|
||||
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
|
||||
|
||||
}
|
||||
|
||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||
|
@ -1652,7 +1653,7 @@ namespace {
|
|||
EvalInfo ei;
|
||||
StateInfo st;
|
||||
Move ttMove, move;
|
||||
Value staticValue, bestValue, value, futilityValue;
|
||||
Value staticValue, bestValue, value, futilityBase, futilityValue;
|
||||
bool isCheck, enoughMaterial, moveIsCheck;
|
||||
const TTEntry* tte = NULL;
|
||||
int moveCount = 0;
|
||||
|
@ -1669,39 +1670,33 @@ namespace {
|
|||
if (pos.is_draw())
|
||||
return VALUE_DRAW;
|
||||
|
||||
// Transposition table lookup, only when not in PV
|
||||
if (!pvNode)
|
||||
{
|
||||
tte = TT.retrieve(pos.get_key());
|
||||
if (tte && ok_to_use_TT(tte, depth, beta, ply))
|
||||
{
|
||||
assert(tte->type() != VALUE_TYPE_EVAL);
|
||||
if (ply >= PLY_MAX - 1)
|
||||
return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
|
||||
|
||||
return value_from_tt(tte->value(), ply);
|
||||
}
|
||||
}
|
||||
// Transposition table lookup. At PV nodes, we don't use the TT for
|
||||
// pruning, but only for move ordering.
|
||||
tte = TT.retrieve(pos.get_key());
|
||||
ttMove = (tte ? tte->move() : MOVE_NONE);
|
||||
|
||||
if (!pvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
|
||||
{
|
||||
assert(tte->type() != VALUE_TYPE_EVAL);
|
||||
|
||||
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
||||
return value_from_tt(tte->value(), ply);
|
||||
}
|
||||
|
||||
isCheck = pos.is_check();
|
||||
ei.futilityMargin = Value(0); // Manually initialize futilityMargin
|
||||
|
||||
// Evaluate the position statically
|
||||
if (isCheck)
|
||||
staticValue = -VALUE_INFINITE;
|
||||
|
||||
else if (tte && (tte->type() & VALUE_TYPE_EVAL))
|
||||
{
|
||||
// Use the cached evaluation score if possible
|
||||
assert(ei.futilityMargin == Value(0));
|
||||
|
||||
staticValue = value_from_tt(tte->value(), ply);
|
||||
}
|
||||
else
|
||||
staticValue = evaluate(pos, ei, threadID);
|
||||
|
||||
if (ply >= PLY_MAX - 1)
|
||||
return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
|
||||
|
||||
// Initialize "stand pat score", and return it immediately if it is
|
||||
// at least beta.
|
||||
bestValue = staticValue;
|
||||
|
@ -1724,6 +1719,7 @@ namespace {
|
|||
MovePicker mp = MovePicker(pos, ttMove, depth, H);
|
||||
CheckInfo ci(pos);
|
||||
enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
|
||||
futilityBase = staticValue + FutilityMarginQS + ei.futilityMargin;
|
||||
|
||||
// Loop through the moves until no moves remain or a beta cutoff
|
||||
// occurs.
|
||||
|
@ -1732,11 +1728,12 @@ namespace {
|
|||
{
|
||||
assert(move_is_ok(move));
|
||||
|
||||
moveIsCheck = pos.move_is_check(move, ci);
|
||||
|
||||
// Update current move
|
||||
moveCount++;
|
||||
ss[ply].currentMove = move;
|
||||
|
||||
moveIsCheck = pos.move_is_check(move, ci);
|
||||
|
||||
// Futility pruning
|
||||
if ( enoughMaterial
|
||||
&& !isCheck
|
||||
|
@ -1746,12 +1743,9 @@ namespace {
|
|||
&& !move_is_promotion(move)
|
||||
&& !pos.move_is_passed_pawn_push(move))
|
||||
{
|
||||
futilityValue = staticValue
|
||||
+ Max(pos.midgame_value_of_piece_on(move_to(move)),
|
||||
pos.endgame_value_of_piece_on(move_to(move)))
|
||||
+ (move_is_ep(move) ? PawnValueEndgame : Value(0))
|
||||
+ FutilityMarginQS
|
||||
+ ei.futilityMargin;
|
||||
futilityValue = futilityBase
|
||||
+ pos.endgame_value_of_piece_on(move_to(move))
|
||||
+ (move_is_ep(move) ? PawnValueEndgame : Value(0));
|
||||
|
||||
if (futilityValue < alpha)
|
||||
{
|
||||
|
@ -1787,31 +1781,31 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// All legal moves have been searched. A special case: If we're in check
|
||||
// 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 && pos.is_check()) // Mate!
|
||||
return value_mated_in(ply);
|
||||
|
||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||
|
||||
// Update transposition table
|
||||
move = ss[ply].pv[ply];
|
||||
if (!pvNode)
|
||||
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
|
||||
if (bestValue < beta)
|
||||
{
|
||||
// If bestValue isn't changed it means it is still the static evaluation of
|
||||
// the node, so keep this info to avoid a future costly evaluation() call.
|
||||
// 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.
|
||||
ValueType type = (bestValue == staticValue && !ei.futilityMargin ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
|
||||
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
|
||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
move = ss[ply].pv[ply];
|
||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
|
||||
|
||||
if (bestValue < beta)
|
||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
|
||||
else
|
||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
|
||||
// Update killers only for good checking moves
|
||||
if (!pos.move_is_capture_or_promotion(move))
|
||||
update_killers(move, ss[ply]);
|
||||
}
|
||||
|
||||
// Update killers only for good check moves
|
||||
if (alpha >= beta && !pos.move_is_capture_or_promotion(move))
|
||||
update_killers(move, ss[ply]);
|
||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||
|
||||
return bestValue;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue