1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 00:33:09 +00:00

Move fail loops out of root_search() to id_loop()

And sync root_search() with search()

After 9384 games Mod - Orig:
1532 - 1433 - 6419  ELO +3 (+- 2.8)

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2011-01-11 09:56:47 +01:00
parent e06c99cad0
commit c17a127c42

View file

@ -556,6 +556,7 @@ namespace {
Depth depth;
Move EasyMove = MOVE_NONE;
Value value, alpha = -VALUE_INFINITE, beta = VALUE_INFINITE;
int researchCountFL, researchCountFH;
// Moves to search are verified, scored and sorted
RootMoveList rml(pos, searchMoves);
@ -612,9 +613,43 @@ namespace {
depth = (Iteration - 2) * ONE_PLY + InitialDepth;
researchCountFL = researchCountFH = 0;
// We start with small aspiration window and in case of fail high/low, we
// research with bigger window until we are not failing high/low anymore.
while (true)
{
// Sort the moves before to (re)search
rml.set_non_pv_scores(pos, rml[0].pv[0], ss);
rml.sort();
// Search to the current depth, rml is updated and sorted
value = root_search(pos, ss, alpha, beta, depth, rml);
if (StopRequest)
break;
assert(value >= alpha);
if (value >= beta)
{
// Prepare for a research after a fail high, each time with a wider window
beta = Min(beta + AspirationDelta * (1 << researchCountFH), VALUE_INFINITE);
researchCountFH++;
}
else if (value <= alpha)
{
AspirationFailLow = true;
StopOnPonderhit = false;
// Prepare for a research after a fail low, each time with a wider window
alpha = Max(alpha - AspirationDelta * (1 << researchCountFL), -VALUE_INFINITE);
researchCountFL++;
}
else
break;
}
if (StopRequest)
break; // Value cannot be trusted. Break out immediately!
@ -685,18 +720,22 @@ namespace {
Value root_search(Position& pos, SearchStack* ss, Value alpha,
Value beta, Depth depth, RootMoveList& rml) {
StateInfo st;
assert(alpha >= -VALUE_INFINITE && alpha <= VALUE_INFINITE);
assert(beta > alpha && beta <= VALUE_INFINITE);
assert(pos.thread() >= 0 && pos.thread() < ThreadsMgr.active_threads());
Move movesSearched[MOVES_MAX];
CheckInfo ci(pos);
int64_t nodes;
StateInfo st;
Key posKey;
Move move;
Depth ext, newDepth;
ValueType vt;
Value value, oldAlpha;
RootMoveList::iterator rm;
bool isCheck, moveIsCheck, captureOrPromotion, dangerous, isPvMove;
int moveCount, researchCountFH, researchCountFL;
int moveCount = 0;
researchCountFH = researchCountFL = 0;
value = -VALUE_INFINITE;
oldAlpha = alpha;
isCheck = pos.is_check();
@ -707,6 +746,7 @@ namespace {
// Step 2. Check for aborted search (omitted at root)
// Step 3. Mate distance pruning (omitted at root)
// Step 4. Transposition table lookup (omitted at root)
posKey = pos.get_key();
// Step 5. Evaluate the position statically
// At root we do this only to get reference value for child nodes
@ -718,19 +758,20 @@ namespace {
// Step 8. Null move search with verification search (omitted at root)
// Step 9. Internal iterative deepening (omitted at root)
// Step extra. Fail low loop
// We start with small aspiration window and in case of fail low, we research
// with bigger window until we are not failing low anymore.
while (1)
{
// Sort the moves before to (re)search
rml.set_non_pv_scores(pos, rml[0].pv[0], ss);
rml.sort();
moveCount = 0;
CheckInfo ci(pos);
int64_t nodes;
RootMoveList::iterator rm = rml.begin();
// Step 10. Loop through all moves in the root move list
for (rm = rml.begin(); rm != rml.end() && !StopRequest; ++rm)
// Step 10. Loop through moves
// Loop through all legal moves until no moves remain or a beta cutoff occurs
while ( alpha < beta
&& rm != rml.end()
&& !StopRequest)
{
move = ss->currentMove = rm->pv[0];
movesSearched[moveCount++] = move;
isPvMove = (moveCount <= MultiPV);
// This is used by time management
FirstRootMove = (rm == rml.begin());
@ -747,12 +788,6 @@ namespace {
<< " time " << current_search_time() << endl;
}
// Pick the next root move, and print the move and the move number to
// the standard output.
move = ss->currentMove = rm->pv[0];
movesSearched[moveCount++] = move;
isPvMove = (moveCount <= MultiPV);
if (current_search_time() >= 1000)
cout << "info currmove " << move
<< " currmovenumber " << moveCount << endl;
@ -765,20 +800,12 @@ namespace {
newDepth = depth + ext;
// Step 12. Futility pruning (omitted at root)
// Step extra. Fail high loop
// If move fails high, we research with bigger window until we are not failing
// high anymore.
value = -VALUE_INFINITE;
while (1)
{
// Step 13. Make the move
pos.do_move(move, st, ci, moveIsCheck);
// Step extra. pv search
// We do pv search for PV moves and when failing high
if (isPvMove || value > alpha)
// We do pv search for PV moves
if (isPvMove)
{
// Aspiration window is disabled in multi-pv case
if (MultiPV > 1)
@ -794,17 +821,19 @@ namespace {
bool doFullDepthSearch = true;
if ( depth >= 3 * ONE_PLY
&& !dangerous
&& !captureOrPromotion
&& !move_is_castle(move))
&& !dangerous
&& !move_is_castle(move)
&& ss->killers[0] != move
&& ss->killers[1] != move)
{
ss->reduction = reduction<PV>(depth, moveCount - MultiPV + 1);
if (ss->reduction)
{
assert(newDepth-ss->reduction >= ONE_PLY);
Depth d = newDepth - ss->reduction;
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, 1);
// Reduced depth non-pv search using alpha as upperbound
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth-ss->reduction, 1);
doFullDepthSearch = (value > alpha);
}
ss->reduction = DEPTH_ZERO; // Restore original reduction
@ -826,33 +855,9 @@ namespace {
// Step 16. Undo move
pos.undo_move(move);
// Can we exit fail high loop ?
if (StopRequest || value < beta)
break;
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
// We are failing high and going to do a research. It's important to update
// the score before research in case we run out of time while researching.
ss->bestMove = move;
rm->pv_score = value;
rm->extract_pv_from_tt(pos);
// Update killers and history only for non capture moves that fails high
if (!pos.move_is_capture_or_promotion(move))
{
update_history(pos, move, depth, movesSearched, moveCount);
update_killers(move, ss->killers);
}
// Inform GUI that PV has changed
cout << rm->pv_info_to_uci(pos, alpha, beta) << endl;
// Prepare for a research after a fail high, each time with a wider window
beta = Min(beta + AspirationDelta * (1 << researchCountFH), VALUE_INFINITE);
researchCountFH++;
} // End of fail high loop
// Finished searching the move. If AbortSearch is true, the search
// Finished searching the move. If StopRequest 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 break out of the loop without updating the best
@ -863,9 +868,6 @@ namespace {
// Remember searched nodes counts for this move
rm->nodes += pos.nodes_searched() - nodes;
assert(value >= -VALUE_INFINITE && value <= VALUE_INFINITE);
assert(value < beta);
// Step 17. Check for new best move
if (!isPvMove && value <= alpha)
rm->pv_score = -VALUE_INFINITE;
@ -903,24 +905,30 @@ namespace {
} // PV move or new best move
assert(alpha >= oldAlpha);
AspirationFailLow = (alpha == oldAlpha);
if (AspirationFailLow && StopOnPonderhit)
StopOnPonderhit = false;
++rm;
} // Root moves loop
// Can we exit fail low loop ?
if (StopRequest || !AspirationFailLow)
break;
// Prepare for a research after a fail low, each time with a wider window
oldAlpha = alpha = Max(alpha - AspirationDelta * (1 << researchCountFL), -VALUE_INFINITE);
researchCountFL++;
// Step 20. Update tables
// If the search is not aborted, update the transposition table,
// history counters, and killer moves.
if (!StopRequest)
{
move = alpha <= oldAlpha ? MOVE_NONE : ss->bestMove;
vt = alpha <= oldAlpha ? VALUE_TYPE_UPPER
: alpha >= beta ? VALUE_TYPE_LOWER : VALUE_TYPE_EXACT;
} // Fail low loop
TT.store(posKey, value_to_tt(alpha, 0), vt, depth, move, ss->eval, ss->evalMargin);
// Update killers and history only for non capture moves that fails high
if ( alpha >= beta
&& !pos.move_is_capture_or_promotion(move))
{
update_history(pos, move, depth, movesSearched, moveCount);
update_killers(move, ss->killers);
}
}
// Sort the moves before to return
rml.sort();
@ -930,6 +938,8 @@ namespace {
for (int i = 0; i < Min(MultiPV, (int)rml.size()); i++)
rml[i].insert_pv_in_tt(pos);
assert(alpha > -VALUE_INFINITE && alpha < VALUE_INFINITE);
return alpha;
}