diff options
Diffstat (limited to 'src/util.c')
| -rwxr-xr-x | src/util.c | 28 |
1 files changed, 28 insertions, 0 deletions
@@ -991,6 +991,9 @@ FinishPVTailFromHash(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv; ULONG uPly = ctx->uPly; ULONG uLen; + ULONG u, uVisited = 0; + UINT64 u64Sig; + UINT64 u64VisitedSigs[MAX_PLY_PER_SEARCH]; #ifdef DEBUG POSITION board; memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); @@ -999,6 +1002,29 @@ FinishPVTailFromHash(SEARCHER_THREAD_CONTEXT *ctx, if (NULL == g_pHashTable) return; do { + // This tail is display-only (cosmetic) -- it walks hash-table + // best-moves one at a time with no relation to the real, + // backed-up search score printed alongside it (that score + // covers only the PV up to the <TT> marker). Unlike the real + // search, there's no natural depth bound here, so a drawish + // position whose hash entries chain back into each other (very + // common in king-shuffle endgames) can loop forever. Break on + // the first repeated position instead of relying on the output + // buffer filling up, which just produces a wall of repeated + // moves that looks like -- but has no actual bearing on -- + // the printed score. + u64Sig = (ctx->sPosition.u64NonPawnSig ^ ctx->sPosition.u64PawnSig); + for (u = 0; u < uVisited; u++) + { + if (u64VisitedSigs[u] == u64Sig) + { + if (uLenRemain > 6) strcat(buf, "<REP>"); + goto unmake; + } + } + ASSERT(uVisited < MAX_PLY_PER_SEARCH); + u64VisitedSigs[uVisited++] = u64Sig; + mv = GetPonderMove(&ctx->sPosition); if (mv.uMove == 0) break; PV[ctx->uPly] = mv; @@ -1014,6 +1040,8 @@ FinishPVTailFromHash(SEARCHER_THREAD_CONTEXT *ctx, } while(1); + unmake: + // // Unmake the moves // |
