diff options
Diffstat (limited to 'src/chess.h')
| -rwxr-xr-x | src/chess.h | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/src/chess.h b/src/chess.h index d6d4fa4..9689189 100755 --- a/src/chess.h +++ b/src/chess.h @@ -808,6 +808,8 @@ typedef struct _COUNTERS UINT64 u64TerminalPositionCount; UINT64 u64BetaCutoffs; UINT64 u64BetaCutoffsOnFirstMove; + UINT64 u64CounterMoveTries; // valid counter-move slot existed + UINT64 u64CounterMoveHits; // ...and it was the move that won UINT64 u64NullMoves; UINT64 u64NullMoveSuccess; #ifdef TEST_NULL @@ -932,6 +934,8 @@ typedef struct _PLY_INFO INT iExtensionAmount; FLAG fInCheck; FLAG fInQsearch; + FLAG fPvNode; // this node's own window was wide + MOVE mv; MOVE mvBest; MOVE PV[MAX_PLY_PER_SEARCH]; @@ -997,6 +1001,16 @@ PAWN_HASH_ENTRY; #define NUM_SPLIT_PTRS_IN_CONTEXT (8) +// +// Counter-move table (Crafty-style): keyed by a hash of the *previous* +// move (whatever the opponent just played to reach this node), not by +// ply -- unlike killers, this generalizes across different branches +// that happen to share the same preceding move, anywhere in the tree. +// Sized to MOVE_TO_INDEX's full range so the index is exact, not a +// lossy hash. +// +#define COUNTER_MOVE_TABLE_SIZE (0x20000) + typedef struct _SEARCHER_THREAD_CONTEXT { ULONG uPly; // its distance from root @@ -1008,6 +1022,12 @@ typedef struct _SEARCHER_THREAD_CONTEXT MOVE mvKiller[MAX_PLY_PER_SEARCH][2]; MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2]; MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH]; + MOVE mvCounter[COUNTER_MOVE_TABLE_SIZE][2]; // counter-move table + UCHAR uCounterDepth[COUNTER_MOVE_TABLE_SIZE]; // ply depth slot 0 was set at + COOR cEnprise[MAX_PLY_PER_SEARCH][2]; // en prise piece hints + PIECE pEnprise[MAX_PLY_PER_SEARCH][2]; + COOR cTrapped[MAX_PLY_PER_SEARCH]; // trapped piece hint + PIECE pTrapped[MAX_PLY_PER_SEARCH]; COUNTERS sCounters; ULONG uThreadNumber; SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT]; @@ -1074,6 +1094,10 @@ typedef struct _GAME_OPTIONS FLAG fShouldAnnounceOpening; SCORE iLastEvalScore; UINT64 u64NodesSearched; + UINT64 u64BetaCutoffs; + UINT64 u64BetaCutoffsOnFirstMove; + UINT64 u64CounterMoveTries; + UINT64 u64CounterMoveHits; CHAR szLogfile[SMALL_STRING_LEN_CHAR]; CHAR szEGTBPath[SMALL_STRING_LEN_CHAR]; CHAR szBookName[SMALL_STRING_LEN_CHAR]; @@ -1816,7 +1840,9 @@ TestMakeUnmakeMove(void); #define THIRD_KILLER (0x08000000) #define FOURTH_KILLER (0x04000000) #define GOOD_MOVE (0x02000000) -#define STRIP_OFF_FLAGS (0x00FFFFFF) +#define FIRST_COUNTER_MOVE (0x01000000) +#define SECOND_COUNTER_MOVE (0x00800000) +#define STRIP_OFF_FLAGS (0x007FFFFF) extern const int g_iQKDeltas[9]; extern const int g_iNDeltas[9]; @@ -2317,16 +2343,26 @@ ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, FLAG ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *); -FLAG -WeShouldDoHistoryPruning(IN SCORE iRoughEval, - IN SCORE iAlpha, - IN SCORE iBeta, - IN SEARCHER_THREAD_CONTEXT *ctx, - IN ULONG uRemainingDepth, - IN ULONG uLegalMoves, - IN MOVE mv, - IN ULONG uMoveNum, - IN INT iExtend); +// LMR reduction table -- built once at startup (InitLMRTable, dynamic.c), +// no floating point in the search hot path. [depth in plies][move number, +// clamped]. Value is a ply-fraction in ONE_PLY units, i.e. directly +// usable as a negative iExtend. +#define LMR_TABLE_MAX_MOVES (63) +extern SCORE g_iLMRQuietReduction[MAX_PLY_PER_SEARCH + 1][LMR_TABLE_MAX_MOVES + 1]; + +void +InitLMRTable(void); + +INT +GetLMRReduction(IN SCORE iRoughEval, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN ULONG uLegalMoves, + IN MOVE mv, + IN ULONG uMoveNum, + IN INT iExtend); FLAG WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, @@ -2532,44 +2568,34 @@ void AnalyzeFullHashTable(void); // -// positionhash.c +// dynamic.c -- enprise/trapped piece hints // -// IDEA: store "mate threat" flag in here? -// IDEA: store "king safety" numbers in here? +// Ply-indexed, like killer moves: cheap, lock-free, thread-local hints +// about which piece(s) looked en prise or trapped the last time full +// Eval() (or a fail-high capture) ran at this ply. Not guaranteed +// fresh for the position currently at that ply -- readers must +// re-validate via the recorded PIECE still being on the recorded COOR +// before trusting it (RecordEnprisePiece/RecordTrappedPiece store +// both for exactly this reason). Nice-to-have only: pruning/ordering +// decisions must work correctly with none of this data available. // -typedef struct _POSITION_HASH_ENTRY { - UINT64 u64Sig; - UCHAR cEnprise[2]; - UCHAR uEnpriseCount[2]; - UCHAR cTrapped[2]; -} POSITION_HASH_ENTRY; - -void -InitializePositionHashSystem(void); - void -CleanupPositionHashSystem(void); +RecordEnprisePiece(SEARCHER_THREAD_CONTEXT *ctx, COOR cSquare); void -StoreEnprisePiece(POSITION *pos, COOR cSquare); +RecordEnprisePieceAtPly(SEARCHER_THREAD_CONTEXT *ctx, ULONG uPly, COOR cSquare); void -StoreTrappedPiece(POSITION *pos, COOR cSquare); - -COOR -GetEnprisePiece(POSITION *pos, ULONG uSide); - -ULONG -GetEnpriseCount(POSITION *pos, ULONG uSide); +RecordTrappedPiece(SEARCHER_THREAD_CONTEXT *ctx, COOR cSquare); COOR -GetTrappedPiece(POSITION *pos, ULONG uSide); +FindEnprisePiece(SEARCHER_THREAD_CONTEXT *ctx, ULONG uSide); ULONG -ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide); +ValueOfMaterialInTroubleDespiteMove(SEARCHER_THREAD_CONTEXT *ctx, ULONG uSide); ULONG -ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide); +ValueOfMaterialInTroubleAfterNull(SEARCHER_THREAD_CONTEXT *ctx, ULONG uSide); // // pawnhash.c |
