mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +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 FutilityMoveCountMargin = 3 + (1 << (3 * int(depth) / 8));
|
||||||
const int FutilityValueMargin = 112 * bitScanReverse32(int(depth) * int(depth) / 2);
|
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;
|
futilityValue = staticValue + FutilityValueMargin;
|
||||||
staticValue = refine_eval(tte, staticValue, ply);
|
staticValue = refine_eval(tte, staticValue, ply);
|
||||||
|
|
||||||
|
@ -1492,8 +1492,8 @@ namespace {
|
||||||
if (move == excludedMove)
|
if (move == excludedMove)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
singleEvasion = (isCheck && mp.number_of_evasions() == 1);
|
|
||||||
moveIsCheck = pos.move_is_check(move, ci);
|
moveIsCheck = pos.move_is_check(move, ci);
|
||||||
|
singleEvasion = (isCheck && mp.number_of_evasions() == 1);
|
||||||
captureOrPromotion = pos.move_is_capture_or_promotion(move);
|
captureOrPromotion = pos.move_is_capture_or_promotion(move);
|
||||||
|
|
||||||
// Decide the new search depth
|
// Decide the new search depth
|
||||||
|
@ -1606,9 +1606,9 @@ namespace {
|
||||||
break;
|
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.
|
// 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);
|
return excludedMove ? beta - 1 : (pos.is_check() ? value_mated_in(ply) : VALUE_DRAW);
|
||||||
|
|
||||||
// If the search is not aborted, update the transposition table,
|
// If the search is not aborted, update the transposition table,
|
||||||
|
@ -1622,12 +1622,13 @@ namespace {
|
||||||
{
|
{
|
||||||
BetaCounter.add(pos.side_to_move(), depth, threadID);
|
BetaCounter.add(pos.side_to_move(), depth, threadID);
|
||||||
move = ss[ply].pv[ply];
|
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))
|
if (!pos.move_is_capture_or_promotion(move))
|
||||||
{
|
{
|
||||||
update_history(pos, move, depth, movesSearched, moveCount);
|
update_history(pos, move, depth, movesSearched, moveCount);
|
||||||
update_killers(move, ss[ply]);
|
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);
|
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||||
|
@ -1652,7 +1653,7 @@ namespace {
|
||||||
EvalInfo ei;
|
EvalInfo ei;
|
||||||
StateInfo st;
|
StateInfo st;
|
||||||
Move ttMove, move;
|
Move ttMove, move;
|
||||||
Value staticValue, bestValue, value, futilityValue;
|
Value staticValue, bestValue, value, futilityBase, futilityValue;
|
||||||
bool isCheck, enoughMaterial, moveIsCheck;
|
bool isCheck, enoughMaterial, moveIsCheck;
|
||||||
const TTEntry* tte = NULL;
|
const TTEntry* tte = NULL;
|
||||||
int moveCount = 0;
|
int moveCount = 0;
|
||||||
|
@ -1669,39 +1670,33 @@ namespace {
|
||||||
if (pos.is_draw())
|
if (pos.is_draw())
|
||||||
return VALUE_DRAW;
|
return VALUE_DRAW;
|
||||||
|
|
||||||
// Transposition table lookup, only when not in PV
|
if (ply >= PLY_MAX - 1)
|
||||||
if (!pvNode)
|
return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID);
|
||||||
{
|
|
||||||
tte = TT.retrieve(pos.get_key());
|
|
||||||
if (tte && ok_to_use_TT(tte, depth, beta, ply))
|
|
||||||
{
|
|
||||||
assert(tte->type() != VALUE_TYPE_EVAL);
|
|
||||||
|
|
||||||
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);
|
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();
|
isCheck = pos.is_check();
|
||||||
ei.futilityMargin = Value(0); // Manually initialize futilityMargin
|
ei.futilityMargin = Value(0); // Manually initialize futilityMargin
|
||||||
|
|
||||||
// Evaluate the position statically
|
// Evaluate the position statically
|
||||||
if (isCheck)
|
if (isCheck)
|
||||||
staticValue = -VALUE_INFINITE;
|
staticValue = -VALUE_INFINITE;
|
||||||
|
|
||||||
else if (tte && (tte->type() & VALUE_TYPE_EVAL))
|
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);
|
staticValue = value_from_tt(tte->value(), ply);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
staticValue = evaluate(pos, ei, threadID);
|
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
|
// Initialize "stand pat score", and return it immediately if it is
|
||||||
// at least beta.
|
// at least beta.
|
||||||
bestValue = staticValue;
|
bestValue = staticValue;
|
||||||
|
@ -1724,6 +1719,7 @@ namespace {
|
||||||
MovePicker mp = MovePicker(pos, ttMove, depth, H);
|
MovePicker mp = MovePicker(pos, ttMove, depth, H);
|
||||||
CheckInfo ci(pos);
|
CheckInfo ci(pos);
|
||||||
enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame;
|
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
|
// Loop through the moves until no moves remain or a beta cutoff
|
||||||
// occurs.
|
// occurs.
|
||||||
|
@ -1732,11 +1728,12 @@ namespace {
|
||||||
{
|
{
|
||||||
assert(move_is_ok(move));
|
assert(move_is_ok(move));
|
||||||
|
|
||||||
|
moveIsCheck = pos.move_is_check(move, ci);
|
||||||
|
|
||||||
|
// Update current move
|
||||||
moveCount++;
|
moveCount++;
|
||||||
ss[ply].currentMove = move;
|
ss[ply].currentMove = move;
|
||||||
|
|
||||||
moveIsCheck = pos.move_is_check(move, ci);
|
|
||||||
|
|
||||||
// Futility pruning
|
// Futility pruning
|
||||||
if ( enoughMaterial
|
if ( enoughMaterial
|
||||||
&& !isCheck
|
&& !isCheck
|
||||||
|
@ -1746,12 +1743,9 @@ namespace {
|
||||||
&& !move_is_promotion(move)
|
&& !move_is_promotion(move)
|
||||||
&& !pos.move_is_passed_pawn_push(move))
|
&& !pos.move_is_passed_pawn_push(move))
|
||||||
{
|
{
|
||||||
futilityValue = staticValue
|
futilityValue = futilityBase
|
||||||
+ Max(pos.midgame_value_of_piece_on(move_to(move)),
|
+ pos.endgame_value_of_piece_on(move_to(move))
|
||||||
pos.endgame_value_of_piece_on(move_to(move)))
|
+ (move_is_ep(move) ? PawnValueEndgame : Value(0));
|
||||||
+ (move_is_ep(move) ? PawnValueEndgame : Value(0))
|
|
||||||
+ FutilityMarginQS
|
|
||||||
+ ei.futilityMargin;
|
|
||||||
|
|
||||||
if (futilityValue < alpha)
|
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.
|
// and no legal moves were found, it is checkmate.
|
||||||
if (!moveCount && pos.is_check()) // Mate!
|
if (!moveCount && pos.is_check()) // Mate!
|
||||||
return value_mated_in(ply);
|
return value_mated_in(ply);
|
||||||
|
|
||||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
|
||||||
|
|
||||||
// Update transposition table
|
// Update transposition table
|
||||||
move = ss[ply].pv[ply];
|
Depth d = (depth == Depth(0) ? Depth(0) : Depth(-1));
|
||||||
if (!pvNode)
|
if (bestValue < beta)
|
||||||
{
|
{
|
||||||
// If bestValue isn't changed it means it is still the static evaluation of
|
// If bestValue isn't changed it means it is still the static evaluation
|
||||||
// the node, so keep this info to avoid a future costly evaluation() call.
|
// 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);
|
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)
|
// Update killers only for good checking moves
|
||||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
|
if (!pos.move_is_capture_or_promotion(move))
|
||||||
else
|
update_killers(move, ss[ply]);
|
||||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update killers only for good check moves
|
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||||
if (alpha >= beta && !pos.move_is_capture_or_promotion(move))
|
|
||||||
update_killers(move, ss[ply]);
|
|
||||||
|
|
||||||
return bestValue;
|
return bestValue;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue