summaryrefslogtreecommitdiff
path: root/src/chess.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/chess.h')
-rwxr-xr-xsrc/chess.h98
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