js-chess-engine 1.0.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +586 -205
  2. package/dist/adapters/APIAdapter.d.ts +88 -0
  3. package/dist/adapters/APIAdapter.d.ts.map +1 -0
  4. package/dist/adapters/APIAdapter.js +225 -0
  5. package/dist/adapters/APIAdapter.js.map +1 -0
  6. package/dist/ai/AIEngine.d.ts +42 -0
  7. package/dist/ai/AIEngine.d.ts.map +1 -0
  8. package/dist/ai/AIEngine.js +62 -0
  9. package/dist/ai/AIEngine.js.map +1 -0
  10. package/dist/ai/Evaluator.d.ts +48 -0
  11. package/dist/ai/Evaluator.d.ts.map +1 -0
  12. package/dist/ai/Evaluator.js +248 -0
  13. package/dist/ai/Evaluator.js.map +1 -0
  14. package/dist/ai/MoveOrdering.d.ts +60 -0
  15. package/dist/ai/MoveOrdering.d.ts.map +1 -0
  16. package/dist/ai/MoveOrdering.js +173 -0
  17. package/dist/ai/MoveOrdering.js.map +1 -0
  18. package/dist/ai/Search.d.ts +62 -0
  19. package/dist/ai/Search.d.ts.map +1 -0
  20. package/dist/ai/Search.js +340 -0
  21. package/dist/ai/Search.js.map +1 -0
  22. package/dist/ai/TranspositionTable.d.ts +100 -0
  23. package/dist/ai/TranspositionTable.d.ts.map +1 -0
  24. package/dist/ai/TranspositionTable.js +176 -0
  25. package/dist/ai/TranspositionTable.js.map +1 -0
  26. package/dist/core/AttackDetector.d.ts +52 -0
  27. package/dist/core/AttackDetector.d.ts.map +1 -0
  28. package/dist/core/AttackDetector.js +397 -0
  29. package/dist/core/AttackDetector.js.map +1 -0
  30. package/dist/core/Board.d.ts +109 -0
  31. package/dist/core/Board.d.ts.map +1 -0
  32. package/dist/core/Board.js +410 -0
  33. package/dist/core/Board.js.map +1 -0
  34. package/dist/core/MoveGenerator.d.ts +48 -0
  35. package/dist/core/MoveGenerator.d.ts.map +1 -0
  36. package/dist/core/MoveGenerator.js +678 -0
  37. package/dist/core/MoveGenerator.js.map +1 -0
  38. package/dist/core/Position.d.ts +135 -0
  39. package/dist/core/Position.d.ts.map +1 -0
  40. package/dist/core/Position.js +351 -0
  41. package/dist/core/Position.js.map +1 -0
  42. package/dist/core/index.d.ts +9 -0
  43. package/dist/core/index.d.ts.map +1 -0
  44. package/dist/core/index.js +25 -0
  45. package/dist/core/index.js.map +1 -0
  46. package/dist/core/zobrist.d.ts +93 -0
  47. package/dist/core/zobrist.d.ts.map +1 -0
  48. package/dist/core/zobrist.js +273 -0
  49. package/dist/core/zobrist.js.map +1 -0
  50. package/dist/index.d.ts +154 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +353 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/types/ai.types.d.ts +97 -0
  55. package/dist/types/ai.types.d.ts.map +1 -0
  56. package/dist/types/ai.types.js +17 -0
  57. package/dist/types/ai.types.js.map +1 -0
  58. package/dist/types/board.types.d.ts +140 -0
  59. package/dist/types/board.types.d.ts.map +1 -0
  60. package/dist/types/board.types.js +34 -0
  61. package/dist/types/board.types.js.map +1 -0
  62. package/dist/types/index.d.ts +7 -0
  63. package/dist/types/index.d.ts.map +1 -0
  64. package/dist/types/index.js +26 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/types/move.types.d.ts +70 -0
  67. package/dist/types/move.types.d.ts.map +1 -0
  68. package/dist/types/move.types.js +53 -0
  69. package/dist/types/move.types.js.map +1 -0
  70. package/dist/utils/constants.d.ts +123 -0
  71. package/dist/utils/constants.d.ts.map +1 -0
  72. package/dist/utils/constants.js +259 -0
  73. package/dist/utils/constants.js.map +1 -0
  74. package/dist/utils/conversion.d.ts +152 -0
  75. package/dist/utils/conversion.d.ts.map +1 -0
  76. package/dist/utils/conversion.js +288 -0
  77. package/dist/utils/conversion.js.map +1 -0
  78. package/dist/utils/environment.d.ts +33 -0
  79. package/dist/utils/environment.d.ts.map +1 -0
  80. package/dist/utils/environment.js +71 -0
  81. package/dist/utils/environment.js.map +1 -0
  82. package/dist/utils/fen.d.ts +28 -0
  83. package/dist/utils/fen.d.ts.map +1 -0
  84. package/dist/utils/fen.js +203 -0
  85. package/dist/utils/fen.js.map +1 -0
  86. package/package.json +31 -29
  87. package/.eslintrc.json +0 -16
  88. package/.github/workflows/main.yml +0 -20
  89. package/CHANGELOG.md +0 -587
  90. package/dist/js-chess-engine.js +0 -1
  91. package/example/aiMatch.mjs +0 -21
  92. package/example/console.mjs +0 -37
  93. package/example/server.mjs +0 -27
  94. package/lib/Board.mjs +0 -943
  95. package/lib/const/board.mjs +0 -838
  96. package/lib/js-chess-engine.mjs +0 -99
  97. package/lib/utils.mjs +0 -154
  98. package/test/.eslintrc.json +0 -11
  99. package/test/ai.test.mjs +0 -132
  100. package/test/badge.svg +0 -1
  101. package/test/importExport.mjs +0 -108
  102. package/test/moves.test.mjs +0 -773
  103. package/webpack.config.js +0 -12
@@ -0,0 +1,340 @@
1
+ "use strict";
2
+ /**
3
+ * Alpha-beta search implementation for js-chess-engine v2
4
+ *
5
+ * Implements minimax with alpha-beta pruning and extensions for checks and captures.
6
+ * Phase 5: Enhanced with transposition table, move ordering, and iterative deepening.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.Search = void 0;
10
+ const types_1 = require("../types");
11
+ const MoveGenerator_1 = require("../core/MoveGenerator");
12
+ const AttackDetector_1 = require("../core/AttackDetector");
13
+ const Evaluator_1 = require("./Evaluator");
14
+ const TranspositionTable_1 = require("./TranspositionTable");
15
+ const MoveOrdering_1 = require("./MoveOrdering");
16
+ /**
17
+ * Search engine with alpha-beta pruning, transposition table, and move ordering
18
+ */
19
+ class Search {
20
+ nodesSearched = 0;
21
+ transpositionTable;
22
+ killerMoves;
23
+ useOptimizations = true;
24
+ constructor(ttSizeMB = 16) {
25
+ // Only create TT if size > 0
26
+ this.transpositionTable = ttSizeMB > 0 ? new TranspositionTable_1.TranspositionTable(ttSizeMB) : null;
27
+ this.killerMoves = new MoveOrdering_1.KillerMoves();
28
+ }
29
+ /**
30
+ * Enable or disable optimizations (for testing)
31
+ */
32
+ setOptimizations(enabled) {
33
+ this.useOptimizations = enabled;
34
+ }
35
+ /**
36
+ * Clear search data structures
37
+ */
38
+ clear() {
39
+ if (this.transpositionTable) {
40
+ this.transpositionTable.clear();
41
+ }
42
+ this.killerMoves.clear();
43
+ }
44
+ /**
45
+ * Find the best move using alpha-beta search with iterative deepening
46
+ *
47
+ * @param board - Current board position
48
+ * @param baseDepth - Base search depth
49
+ * @param extendedDepth - Extended search depth (for checks and captures)
50
+ * @returns Best move with score
51
+ */
52
+ findBestMove(board, baseDepth, extendedDepth) {
53
+ this.nodesSearched = 0;
54
+ if (this.transpositionTable) {
55
+ this.transpositionTable.newSearch();
56
+ }
57
+ const playerColor = board.turn;
58
+ // Generate all legal moves
59
+ const moves = (0, MoveGenerator_1.generateLegalMoves)(board);
60
+ if (moves.length === 0) {
61
+ return null; // No legal moves
62
+ }
63
+ // Add small random factor to avoid repeating same moves
64
+ // Based on halfmove clock (more randomness in opening)
65
+ const randomFactor = board.halfMoveClock > 10
66
+ ? board.halfMoveClock - 10
67
+ : 1;
68
+ let bestMove = moves[0];
69
+ let bestScore = Evaluator_1.SCORE_MIN;
70
+ // Iterative deepening: search progressively deeper
71
+ // This improves move ordering for deeper searches
72
+ if (this.useOptimizations && baseDepth > 2) {
73
+ for (let depth = 1; depth < baseDepth; depth++) {
74
+ this.searchDepth(board, playerColor, depth, Math.min(depth + 1, extendedDepth), moves);
75
+ }
76
+ }
77
+ // Get PV move from transposition table for move ordering (if available)
78
+ const pvMove = this.useOptimizations && this.transpositionTable
79
+ ? this.transpositionTable.getBestMove(board.zobristHash)
80
+ : null;
81
+ // Order moves for better alpha-beta pruning
82
+ const orderedMoves = this.useOptimizations
83
+ ? (0, MoveOrdering_1.orderMoves)(moves, pvMove, this.killerMoves, 0)
84
+ : moves;
85
+ // Search each root move
86
+ for (const move of orderedMoves) {
87
+ // Make move (generateLegalMoves already filtered for legality)
88
+ const testBoard = this.copyBoard(board);
89
+ (0, MoveGenerator_1.applyMoveComplete)(testBoard, move);
90
+ // Determine if this move captured a piece
91
+ const wasCapture = move.capturedPiece !== 0;
92
+ // Calculate initial score (for capture optimization)
93
+ const initialScore = wasCapture
94
+ ? Evaluator_1.Evaluator.evaluate(testBoard, playerColor)
95
+ : null;
96
+ // Check if this move delivers checkmate (highest priority)
97
+ if (testBoard.isCheckmate && testBoard.turn !== playerColor) {
98
+ // Opponent is in checkmate - immediately return this move
99
+ return {
100
+ move,
101
+ score: Evaluator_1.SCORE_MAX,
102
+ depth: baseDepth,
103
+ nodesSearched: this.nodesSearched,
104
+ };
105
+ }
106
+ // For promotion moves, always prefer queen promotion
107
+ // (Other promotions are rarely optimal except in special tactical situations)
108
+ if ((move.flags & types_1.MoveFlag.PROMOTION) && move.promotionPiece) {
109
+ const isQueenPromotion = move.promotionPiece === types_1.Piece.WHITE_QUEEN ||
110
+ move.promotionPiece === types_1.Piece.BLACK_QUEEN;
111
+ if (!isQueenPromotion) {
112
+ // Skip non-queen promotions (they're almost never best)
113
+ continue;
114
+ }
115
+ }
116
+ // Search this move
117
+ const score = -this.alphaBeta(testBoard, playerColor, baseDepth, extendedDepth, 1, // depth = 1
118
+ wasCapture, initialScore, Evaluator_1.SCORE_MIN, Evaluator_1.SCORE_MAX);
119
+ // For non-checkmate moves, add positional bonus and randomness
120
+ let finalScore = score;
121
+ // Only add randomness for non-decisive moves (not near mate scores)
122
+ if (Math.abs(score) < Evaluator_1.SCORE_MAX - 100) {
123
+ // Add positional bonus
124
+ const positionalBonus = Evaluator_1.Evaluator.evaluate(testBoard, playerColor) -
125
+ Evaluator_1.Evaluator.evaluate(board, playerColor);
126
+ // Add small random factor (v1 compatibility)
127
+ const random = Math.floor(Math.random() * randomFactor * 10) / 10;
128
+ finalScore = score + positionalBonus + random;
129
+ }
130
+ // Update best move
131
+ if (finalScore > bestScore) {
132
+ bestScore = finalScore;
133
+ bestMove = move;
134
+ }
135
+ }
136
+ // Store in transposition table (if available)
137
+ if (this.useOptimizations && this.transpositionTable) {
138
+ this.transpositionTable.store(board.zobristHash, baseDepth, bestScore, TranspositionTable_1.TTEntryType.EXACT, bestMove);
139
+ }
140
+ return {
141
+ move: bestMove,
142
+ score: bestScore,
143
+ depth: baseDepth,
144
+ nodesSearched: this.nodesSearched,
145
+ };
146
+ }
147
+ /**
148
+ * Search at a specific depth (used for iterative deepening)
149
+ */
150
+ searchDepth(board, playerColor, baseDepth, extendedDepth, moves) {
151
+ const pvMove = this.transpositionTable
152
+ ? this.transpositionTable.getBestMove(board.zobristHash)
153
+ : null;
154
+ const orderedMoves = (0, MoveOrdering_1.orderMoves)(moves, pvMove, this.killerMoves, 0);
155
+ let bestMove = orderedMoves[0];
156
+ let bestScore = Evaluator_1.SCORE_MIN;
157
+ for (const move of orderedMoves) {
158
+ const testBoard = this.copyBoard(board);
159
+ (0, MoveGenerator_1.applyMoveComplete)(testBoard, move);
160
+ const wasCapture = move.capturedPiece !== 0;
161
+ const initialScore = wasCapture
162
+ ? Evaluator_1.Evaluator.evaluate(testBoard, playerColor)
163
+ : null;
164
+ const score = -this.alphaBeta(testBoard, playerColor, baseDepth, extendedDepth, 1, wasCapture, initialScore, Evaluator_1.SCORE_MIN, Evaluator_1.SCORE_MAX);
165
+ if (score > bestScore) {
166
+ bestScore = score;
167
+ bestMove = move;
168
+ }
169
+ }
170
+ // Store result in transposition table (if available)
171
+ if (this.transpositionTable) {
172
+ this.transpositionTable.store(board.zobristHash, baseDepth, bestScore, TranspositionTable_1.TTEntryType.EXACT, bestMove);
173
+ }
174
+ }
175
+ /**
176
+ * Alpha-beta search with extensions, transposition table, and move ordering
177
+ *
178
+ * @param board - Current position
179
+ * @param rootPlayerColor - Player color at root (for evaluation perspective)
180
+ * @param baseDepth - Base search depth
181
+ * @param extendedDepth - Extended search depth
182
+ * @param depth - Current depth
183
+ * @param wasCapture - Whether last move was a capture
184
+ * @param initialScore - Initial score (optimization)
185
+ * @param alpha - Alpha bound
186
+ * @param beta - Beta bound
187
+ * @returns Score from current player's perspective
188
+ */
189
+ alphaBeta(board, rootPlayerColor, baseDepth, extendedDepth, depth, wasCapture, initialScore, alpha, beta) {
190
+ this.nodesSearched++;
191
+ // Check if game is over
192
+ if (board.isCheckmate || board.isStalemate) {
193
+ return Evaluator_1.Evaluator.evaluate(board, rootPlayerColor, depth);
194
+ }
195
+ // Probe transposition table (if available)
196
+ if (this.useOptimizations && this.transpositionTable) {
197
+ const ttEntry = this.transpositionTable.probe(board.zobristHash, baseDepth - depth + 1, alpha, beta);
198
+ if (ttEntry && ttEntry.depth >= baseDepth - depth + 1) {
199
+ // We can use this score
200
+ if (ttEntry.type === TranspositionTable_1.TTEntryType.EXACT) {
201
+ return ttEntry.score;
202
+ }
203
+ if (ttEntry.type === TranspositionTable_1.TTEntryType.LOWER_BOUND && ttEntry.score >= beta) {
204
+ return ttEntry.score;
205
+ }
206
+ if (ttEntry.type === TranspositionTable_1.TTEntryType.UPPER_BOUND && ttEntry.score <= alpha) {
207
+ return ttEntry.score;
208
+ }
209
+ }
210
+ }
211
+ // Determine if we should continue searching
212
+ let shouldSearch = false;
213
+ const inCheck = (0, AttackDetector_1.isKingInCheck)(board);
214
+ // Extend search if in check (always search deeper)
215
+ if (depth < extendedDepth && inCheck) {
216
+ shouldSearch = true;
217
+ }
218
+ // Continue base search or extend on captures
219
+ else if (depth < baseDepth || (wasCapture && depth < extendedDepth)) {
220
+ shouldSearch = true;
221
+ }
222
+ // Leaf node - evaluate position
223
+ if (!shouldSearch) {
224
+ if (initialScore !== null) {
225
+ return initialScore;
226
+ }
227
+ return Evaluator_1.Evaluator.evaluate(board, rootPlayerColor);
228
+ }
229
+ // Generate legal moves
230
+ const moves = (0, MoveGenerator_1.generateLegalMoves)(board);
231
+ // Get PV move from transposition table for move ordering (if available)
232
+ const pvMove = this.useOptimizations && this.transpositionTable
233
+ ? this.transpositionTable.getBestMove(board.zobristHash)
234
+ : null;
235
+ // Order moves for better pruning
236
+ const orderedMoves = this.useOptimizations
237
+ ? (0, MoveOrdering_1.orderMoves)(moves, pvMove, this.killerMoves, depth)
238
+ : moves;
239
+ // Determine if we're maximizing or minimizing
240
+ const isMaximizing = board.turn === rootPlayerColor;
241
+ let bestScore = isMaximizing ? Evaluator_1.SCORE_MIN : Evaluator_1.SCORE_MAX;
242
+ let bestMove = null;
243
+ let maxValueReached = false;
244
+ // Search all moves
245
+ for (const move of orderedMoves) {
246
+ if (maxValueReached)
247
+ break;
248
+ // Make move (generateLegalMoves already filtered for legality)
249
+ const testBoard = this.copyBoard(board);
250
+ (0, MoveGenerator_1.applyMoveComplete)(testBoard, move);
251
+ // Check if this move captured a piece
252
+ const moveWasCapture = move.capturedPiece !== 0;
253
+ // Calculate score if capture
254
+ const moveInitialScore = moveWasCapture
255
+ ? Evaluator_1.Evaluator.evaluate(testBoard, rootPlayerColor)
256
+ : null;
257
+ // Recursive search
258
+ const score = this.alphaBeta(testBoard, rootPlayerColor, baseDepth, extendedDepth, depth + 1, moveWasCapture, moveInitialScore, alpha, beta);
259
+ // Check for exact mate found
260
+ if (Math.abs(score) >= Evaluator_1.SCORE_MAX - 100) {
261
+ maxValueReached = true;
262
+ }
263
+ // Update best score and bounds
264
+ if (isMaximizing) {
265
+ if (score > bestScore) {
266
+ bestScore = score;
267
+ bestMove = move;
268
+ }
269
+ alpha = Math.max(alpha, score);
270
+ }
271
+ else {
272
+ if (score < bestScore) {
273
+ bestScore = score;
274
+ bestMove = move;
275
+ }
276
+ beta = Math.min(beta, score);
277
+ }
278
+ // Alpha-beta cutoff
279
+ if (beta <= alpha) {
280
+ // Store killer move (non-captures that caused cutoff)
281
+ if (this.useOptimizations && !(move.flags & types_1.MoveFlag.CAPTURE)) {
282
+ this.killerMoves.store(move, depth);
283
+ }
284
+ break; // Prune
285
+ }
286
+ }
287
+ // Store in transposition table (if available)
288
+ if (this.useOptimizations && this.transpositionTable && bestMove) {
289
+ let entryType;
290
+ if (bestScore <= alpha) {
291
+ entryType = TranspositionTable_1.TTEntryType.UPPER_BOUND;
292
+ }
293
+ else if (bestScore >= beta) {
294
+ entryType = TranspositionTable_1.TTEntryType.LOWER_BOUND;
295
+ }
296
+ else {
297
+ entryType = TranspositionTable_1.TTEntryType.EXACT;
298
+ }
299
+ this.transpositionTable.store(board.zobristHash, baseDepth - depth + 1, bestScore, entryType, bestMove);
300
+ }
301
+ return bestScore;
302
+ }
303
+ /**
304
+ * Copy board for search (fast struct copy)
305
+ *
306
+ * @param board - Board to copy
307
+ * @returns New board instance
308
+ */
309
+ copyBoard(board) {
310
+ return {
311
+ mailbox: new Int8Array(board.mailbox),
312
+ whitePieces: board.whitePieces,
313
+ blackPieces: board.blackPieces,
314
+ allPieces: board.allPieces,
315
+ whitePawns: board.whitePawns,
316
+ whiteKnights: board.whiteKnights,
317
+ whiteBishops: board.whiteBishops,
318
+ whiteRooks: board.whiteRooks,
319
+ whiteQueens: board.whiteQueens,
320
+ whiteKing: board.whiteKing,
321
+ blackPawns: board.blackPawns,
322
+ blackKnights: board.blackKnights,
323
+ blackBishops: board.blackBishops,
324
+ blackRooks: board.blackRooks,
325
+ blackQueens: board.blackQueens,
326
+ blackKing: board.blackKing,
327
+ turn: board.turn,
328
+ castlingRights: { ...board.castlingRights },
329
+ enPassantSquare: board.enPassantSquare,
330
+ halfMoveClock: board.halfMoveClock,
331
+ fullMoveNumber: board.fullMoveNumber,
332
+ zobristHash: board.zobristHash,
333
+ isCheck: board.isCheck,
334
+ isCheckmate: board.isCheckmate,
335
+ isStalemate: board.isStalemate,
336
+ };
337
+ }
338
+ }
339
+ exports.Search = Search;
340
+ //# sourceMappingURL=Search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Search.js","sourceRoot":"","sources":["../../src/ai/Search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Transposition Table for js-chess-engine v2
3
+ *
4
+ * Stores previously evaluated positions to avoid re-computation.
5
+ * Uses Zobrist hashing for position identification.
6
+ */
7
+ import { InternalMove } from '../types';
8
+ import { Score } from '../types/ai.types';
9
+ /**
10
+ * Types of transposition table entries
11
+ */
12
+ export declare enum TTEntryType {
13
+ EXACT = 0,// Exact score
14
+ LOWER_BOUND = 1,// Alpha cutoff (fail-high)
15
+ UPPER_BOUND = 2
16
+ }
17
+ /**
18
+ * Transposition table entry
19
+ */
20
+ export interface TTEntry {
21
+ zobristHash: bigint;
22
+ depth: number;
23
+ score: Score;
24
+ type: TTEntryType;
25
+ bestMove: InternalMove | null;
26
+ age: number;
27
+ }
28
+ /**
29
+ * Transposition Table
30
+ *
31
+ * Implements a hash table with replacement strategy for storing
32
+ * previously evaluated positions.
33
+ */
34
+ export declare class TranspositionTable {
35
+ private table;
36
+ private size;
37
+ private currentAge;
38
+ private hits;
39
+ private misses;
40
+ /**
41
+ * Create a new transposition table
42
+ *
43
+ * @param sizeMB - Size in megabytes (default: 16MB)
44
+ */
45
+ constructor(sizeMB?: number);
46
+ /**
47
+ * Store a position in the transposition table
48
+ *
49
+ * @param zobristHash - Position hash
50
+ * @param depth - Search depth
51
+ * @param score - Position score
52
+ * @param type - Entry type
53
+ * @param bestMove - Best move found
54
+ */
55
+ store(zobristHash: bigint, depth: number, score: Score, type: TTEntryType, bestMove: InternalMove | null): void;
56
+ /**
57
+ * Probe the transposition table
58
+ *
59
+ * @param zobristHash - Position hash
60
+ * @param depth - Current search depth
61
+ * @param alpha - Alpha bound
62
+ * @param beta - Beta bound
63
+ * @returns Entry if found and usable, null otherwise
64
+ */
65
+ probe(zobristHash: bigint, depth: number, alpha: Score, beta: Score): TTEntry | null;
66
+ /**
67
+ * Get best move from transposition table (for move ordering)
68
+ *
69
+ * @param zobristHash - Position hash
70
+ * @returns Best move if found, null otherwise
71
+ */
72
+ getBestMove(zobristHash: bigint): InternalMove | null;
73
+ /**
74
+ * Clear the transposition table
75
+ */
76
+ clear(): void;
77
+ /**
78
+ * Increment search age (call at start of new search)
79
+ */
80
+ newSearch(): void;
81
+ /**
82
+ * Get index for a hash value
83
+ *
84
+ * @param hash - Zobrist hash
85
+ * @returns Table index
86
+ */
87
+ private getIndex;
88
+ /**
89
+ * Get cache statistics
90
+ *
91
+ * @returns Statistics object
92
+ */
93
+ getStats(): {
94
+ hits: number;
95
+ misses: number;
96
+ hitRate: number;
97
+ size: number;
98
+ };
99
+ }
100
+ //# sourceMappingURL=TranspositionTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranspositionTable.d.ts","sourceRoot":"","sources":["../../src/ai/TranspositionTable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;GAEG;AACH,oBAAY,WAAW;IACnB,KAAK,IAAI,CAAO,cAAc;IAC9B,WAAW,IAAI,CAAE,2BAA2B;IAC5C,WAAW,IAAI;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,MAAM,CAAa;IAE3B;;;;OAIG;gBACS,MAAM,GAAE,MAAW;IAW/B;;;;;;;;OAQG;IACH,KAAK,CACD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,YAAY,GAAG,IAAI,GAC9B,IAAI;IA2BP;;;;;;;;OAQG;IACH,KAAK,CACD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,KAAK,GACZ,OAAO,GAAG,IAAI;IA0CjB;;;;;OAKG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAWrD;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,SAAS,IAAI,IAAI;IAIjB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAKhB;;;;OAIG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAW9E"}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Transposition Table for js-chess-engine v2
4
+ *
5
+ * Stores previously evaluated positions to avoid re-computation.
6
+ * Uses Zobrist hashing for position identification.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.TranspositionTable = exports.TTEntryType = void 0;
10
+ /**
11
+ * Types of transposition table entries
12
+ */
13
+ var TTEntryType;
14
+ (function (TTEntryType) {
15
+ TTEntryType[TTEntryType["EXACT"] = 0] = "EXACT";
16
+ TTEntryType[TTEntryType["LOWER_BOUND"] = 1] = "LOWER_BOUND";
17
+ TTEntryType[TTEntryType["UPPER_BOUND"] = 2] = "UPPER_BOUND";
18
+ })(TTEntryType || (exports.TTEntryType = TTEntryType = {}));
19
+ /**
20
+ * Transposition Table
21
+ *
22
+ * Implements a hash table with replacement strategy for storing
23
+ * previously evaluated positions.
24
+ */
25
+ class TranspositionTable {
26
+ table;
27
+ size;
28
+ currentAge = 0;
29
+ hits = 0;
30
+ misses = 0;
31
+ /**
32
+ * Create a new transposition table
33
+ *
34
+ * @param sizeMB - Size in megabytes (default: 16MB)
35
+ */
36
+ constructor(sizeMB = 16) {
37
+ // Each entry is approximately 40 bytes
38
+ const entrySize = 40;
39
+ const bytesPerMB = 1024 * 1024;
40
+ const totalBytes = sizeMB * bytesPerMB;
41
+ // Use power of 2 for efficient modulo with bitwise AND
42
+ this.size = Math.pow(2, Math.floor(Math.log2(totalBytes / entrySize)));
43
+ this.table = new Array(this.size).fill(null);
44
+ }
45
+ /**
46
+ * Store a position in the transposition table
47
+ *
48
+ * @param zobristHash - Position hash
49
+ * @param depth - Search depth
50
+ * @param score - Position score
51
+ * @param type - Entry type
52
+ * @param bestMove - Best move found
53
+ */
54
+ store(zobristHash, depth, score, type, bestMove) {
55
+ const index = this.getIndex(zobristHash);
56
+ const existingEntry = this.table[index];
57
+ // Replacement strategy: always replace if:
58
+ // 1. Slot is empty
59
+ // 2. Same position (hash match)
60
+ // 3. New entry has greater depth
61
+ // 4. Entry is from previous search (old age)
62
+ const shouldReplace = !existingEntry ||
63
+ existingEntry.zobristHash === zobristHash ||
64
+ depth >= existingEntry.depth ||
65
+ existingEntry.age < this.currentAge;
66
+ if (shouldReplace) {
67
+ this.table[index] = {
68
+ zobristHash,
69
+ depth,
70
+ score,
71
+ type,
72
+ bestMove,
73
+ age: this.currentAge,
74
+ };
75
+ }
76
+ }
77
+ /**
78
+ * Probe the transposition table
79
+ *
80
+ * @param zobristHash - Position hash
81
+ * @param depth - Current search depth
82
+ * @param alpha - Alpha bound
83
+ * @param beta - Beta bound
84
+ * @returns Entry if found and usable, null otherwise
85
+ */
86
+ probe(zobristHash, depth, alpha, beta) {
87
+ const index = this.getIndex(zobristHash);
88
+ const entry = this.table[index];
89
+ // Check if entry exists and matches hash
90
+ if (!entry || entry.zobristHash !== zobristHash) {
91
+ this.misses++;
92
+ return null;
93
+ }
94
+ // Entry must be from sufficient depth to be usable
95
+ if (entry.depth < depth) {
96
+ this.misses++;
97
+ return null;
98
+ }
99
+ this.hits++;
100
+ // Check if we can use this score
101
+ switch (entry.type) {
102
+ case TTEntryType.EXACT:
103
+ return entry;
104
+ case TTEntryType.LOWER_BOUND:
105
+ // Fail-high (score >= beta)
106
+ if (entry.score >= beta) {
107
+ return entry;
108
+ }
109
+ break;
110
+ case TTEntryType.UPPER_BOUND:
111
+ // Fail-low (score <= alpha)
112
+ if (entry.score <= alpha) {
113
+ return entry;
114
+ }
115
+ break;
116
+ }
117
+ // Can't use score, but return entry for move ordering
118
+ return entry;
119
+ }
120
+ /**
121
+ * Get best move from transposition table (for move ordering)
122
+ *
123
+ * @param zobristHash - Position hash
124
+ * @returns Best move if found, null otherwise
125
+ */
126
+ getBestMove(zobristHash) {
127
+ const index = this.getIndex(zobristHash);
128
+ const entry = this.table[index];
129
+ if (entry && entry.zobristHash === zobristHash) {
130
+ return entry.bestMove;
131
+ }
132
+ return null;
133
+ }
134
+ /**
135
+ * Clear the transposition table
136
+ */
137
+ clear() {
138
+ this.table.fill(null);
139
+ this.currentAge = 0;
140
+ this.hits = 0;
141
+ this.misses = 0;
142
+ }
143
+ /**
144
+ * Increment search age (call at start of new search)
145
+ */
146
+ newSearch() {
147
+ this.currentAge++;
148
+ }
149
+ /**
150
+ * Get index for a hash value
151
+ *
152
+ * @param hash - Zobrist hash
153
+ * @returns Table index
154
+ */
155
+ getIndex(hash) {
156
+ // Use bitwise AND for fast modulo with power of 2
157
+ return Number(hash & BigInt(this.size - 1));
158
+ }
159
+ /**
160
+ * Get cache statistics
161
+ *
162
+ * @returns Statistics object
163
+ */
164
+ getStats() {
165
+ const total = this.hits + this.misses;
166
+ const hitRate = total > 0 ? this.hits / total : 0;
167
+ return {
168
+ hits: this.hits,
169
+ misses: this.misses,
170
+ hitRate,
171
+ size: this.size,
172
+ };
173
+ }
174
+ }
175
+ exports.TranspositionTable = TranspositionTable;
176
+ //# sourceMappingURL=TranspositionTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranspositionTable.js","sourceRoot":"","sources":["../../src/ai/TranspositionTable.ts"],"names":[],"mappings":"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"}