js-chess-engine 1.0.3 → 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.
- package/README.md +586 -205
- package/dist/adapters/APIAdapter.d.ts +88 -0
- package/dist/adapters/APIAdapter.d.ts.map +1 -0
- package/dist/adapters/APIAdapter.js +225 -0
- package/dist/adapters/APIAdapter.js.map +1 -0
- package/dist/ai/AIEngine.d.ts +42 -0
- package/dist/ai/AIEngine.d.ts.map +1 -0
- package/dist/ai/AIEngine.js +62 -0
- package/dist/ai/AIEngine.js.map +1 -0
- package/dist/ai/Evaluator.d.ts +48 -0
- package/dist/ai/Evaluator.d.ts.map +1 -0
- package/dist/ai/Evaluator.js +248 -0
- package/dist/ai/Evaluator.js.map +1 -0
- package/dist/ai/MoveOrdering.d.ts +60 -0
- package/dist/ai/MoveOrdering.d.ts.map +1 -0
- package/dist/ai/MoveOrdering.js +173 -0
- package/dist/ai/MoveOrdering.js.map +1 -0
- package/dist/ai/Search.d.ts +62 -0
- package/dist/ai/Search.d.ts.map +1 -0
- package/dist/ai/Search.js +340 -0
- package/dist/ai/Search.js.map +1 -0
- package/dist/ai/TranspositionTable.d.ts +100 -0
- package/dist/ai/TranspositionTable.d.ts.map +1 -0
- package/dist/ai/TranspositionTable.js +176 -0
- package/dist/ai/TranspositionTable.js.map +1 -0
- package/dist/core/AttackDetector.d.ts +52 -0
- package/dist/core/AttackDetector.d.ts.map +1 -0
- package/dist/core/AttackDetector.js +397 -0
- package/dist/core/AttackDetector.js.map +1 -0
- package/dist/core/Board.d.ts +109 -0
- package/dist/core/Board.d.ts.map +1 -0
- package/dist/core/Board.js +410 -0
- package/dist/core/Board.js.map +1 -0
- package/dist/core/MoveGenerator.d.ts +48 -0
- package/dist/core/MoveGenerator.d.ts.map +1 -0
- package/dist/core/MoveGenerator.js +678 -0
- package/dist/core/MoveGenerator.js.map +1 -0
- package/dist/core/Position.d.ts +135 -0
- package/dist/core/Position.d.ts.map +1 -0
- package/dist/core/Position.js +351 -0
- package/dist/core/Position.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +25 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/zobrist.d.ts +93 -0
- package/dist/core/zobrist.d.ts.map +1 -0
- package/dist/core/zobrist.js +273 -0
- package/dist/core/zobrist.js.map +1 -0
- package/dist/index.d.ts +154 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +353 -0
- package/dist/index.js.map +1 -0
- package/dist/types/ai.types.d.ts +97 -0
- package/dist/types/ai.types.d.ts.map +1 -0
- package/dist/types/ai.types.js +17 -0
- package/dist/types/ai.types.js.map +1 -0
- package/dist/types/board.types.d.ts +140 -0
- package/dist/types/board.types.d.ts.map +1 -0
- package/dist/types/board.types.js +34 -0
- package/dist/types/board.types.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +26 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/move.types.d.ts +70 -0
- package/dist/types/move.types.d.ts.map +1 -0
- package/dist/types/move.types.js +53 -0
- package/dist/types/move.types.js.map +1 -0
- package/dist/utils/constants.d.ts +123 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +259 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/conversion.d.ts +152 -0
- package/dist/utils/conversion.d.ts.map +1 -0
- package/dist/utils/conversion.js +288 -0
- package/dist/utils/conversion.js.map +1 -0
- package/dist/utils/environment.d.ts +33 -0
- package/dist/utils/environment.d.ts.map +1 -0
- package/dist/utils/environment.js +71 -0
- package/dist/utils/environment.js.map +1 -0
- package/dist/utils/fen.d.ts +28 -0
- package/dist/utils/fen.d.ts.map +1 -0
- package/dist/utils/fen.js +203 -0
- package/dist/utils/fen.js.map +1 -0
- package/package.json +29 -30
- package/.eslintrc.json +0 -16
- package/.github/workflows/main.yml +0 -20
- package/.nvmrc +0 -1
- package/CHANGELOG.md +0 -597
- package/dist/js-chess-engine.js +0 -1
- package/example/aiMatch.mjs +0 -21
- package/example/console.mjs +0 -37
- package/example/server.mjs +0 -27
- package/lib/Board.mjs +0 -946
- package/lib/const/board.mjs +0 -838
- package/lib/js-chess-engine.mjs +0 -99
- package/lib/utils.mjs +0 -154
- package/test/.eslintrc.json +0 -11
- package/test/ai.test.mjs +0 -132
- package/test/badge.svg +0 -1
- package/test/importExport.mjs +0 -108
- package/test/moves.test.mjs +0 -798
- 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":";AAAA;;;;;GAKG;;;AAEH,oCAAuF;AACvF,yDAA8E;AAC9E,2DAAuD;AACvD,2CAA8D;AAE9D,6DAAuE;AACvE,iDAAyD;AAEzD;;GAEG;AACH,MAAa,MAAM;IACP,aAAa,GAAW,CAAC,CAAC;IAC1B,kBAAkB,CAA4B;IAC9C,WAAW,CAAc;IACzB,gBAAgB,GAAY,IAAI,CAAC;IAEzC,YAAY,WAAmB,EAAE;QAC7B,6BAA6B;QAC7B,IAAI,CAAC,kBAAkB,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,uCAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAW,CAAC;QACxF,IAAI,CAAC,WAAW,GAAG,IAAI,0BAAW,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,OAAgB;QAC7B,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK;QACD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CACR,KAAoB,EACpB,SAAiB,EACjB,aAAqB;QAErB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC;QACxC,CAAC;QACD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;QAE/B,2BAA2B;QAC3B,MAAM,KAAK,GAAG,IAAA,kCAAkB,EAAC,KAAK,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,CAAC,iBAAiB;QAClC,CAAC;QAED,wDAAwD;QACxD,uDAAuD;QACvD,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,GAAG,EAAE;YACzC,CAAC,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE;YAC1B,CAAC,CAAC,CAAC,CAAC;QAER,IAAI,QAAQ,GAAiB,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,SAAS,GAAG,qBAAS,CAAC;QAE1B,mDAAmD;QACnD,kDAAkD;QAClD,IAAI,IAAI,CAAC,gBAAgB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YACzC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC7C,IAAI,CAAC,WAAW,CACZ,KAAK,EACL,WAAW,EACX,KAAK,EACL,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,aAAa,CAAC,EAClC,KAAK,CACR,CAAC;YACN,CAAC;QACL,CAAC;QAED,wEAAwE;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,kBAAkB;YAC3D,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC;YACxD,CAAC,CAAC,IAAI,CAAC;QAEX,4CAA4C;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB;YACtC,CAAC,CAAC,IAAA,yBAAU,EAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC,KAAK,CAAC;QAEZ,wBAAwB;QACxB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAC9B,+DAA+D;YAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACxC,IAAA,iCAAiB,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAEnC,0CAA0C;YAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;YAE5C,qDAAqD;YACrD,MAAM,YAAY,GAAG,UAAU;gBAC3B,CAAC,CAAC,qBAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;gBAC5C,CAAC,CAAC,IAAI,CAAC;YAEX,2DAA2D;YAC3D,IAAI,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC1D,0DAA0D;gBAC1D,OAAO;oBACH,IAAI;oBACJ,KAAK,EAAE,qBAAS;oBAChB,KAAK,EAAE,SAAS;oBAChB,aAAa,EAAE,IAAI,CAAC,aAAa;iBACpC,CAAC;YACN,CAAC;YAED,qDAAqD;YACrD,8EAA8E;YAC9E,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,gBAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC3D,MAAM,gBAAgB,GAClB,IAAI,CAAC,cAAc,KAAK,aAAK,CAAC,WAAW;oBACzC,IAAI,CAAC,cAAc,KAAK,aAAK,CAAC,WAAW,CAAC;gBAE9C,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACpB,wDAAwD;oBACxD,SAAS;gBACb,CAAC;YACL,CAAC;YAED,mBAAmB;YACnB,MAAM,KAAK,GACP,CAAC,IAAI,CAAC,SAAS,CACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,CAAC,EAAE,YAAY;YACf,UAAU,EACV,YAAY,EACZ,qBAAS,EACT,qBAAS,CACZ,CAAC;YAEN,+DAA+D;YAC/D,IAAI,UAAU,GAAG,KAAK,CAAC;YAEvB,oEAAoE;YACpE,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,qBAAS,GAAG,GAAG,EAAE,CAAC;gBACpC,uBAAuB;gBACvB,MAAM,eAAe,GAAG,qBAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;oBAC9D,qBAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;gBAE3C,6CAA6C;gBAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,YAAY,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;gBAElE,UAAU,GAAG,KAAK,GAAG,eAAe,GAAG,MAAM,CAAC;YAClD,CAAC;YAED,mBAAmB;YACnB,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;gBACzB,SAAS,GAAG,UAAU,CAAC;gBACvB,QAAQ,GAAG,IAAI,CAAC;YACpB,CAAC;QACL,CAAC;QAED,8CAA8C;QAC9C,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACnD,IAAI,CAAC,kBAAkB,CAAC,KAAK,CACzB,KAAK,CAAC,WAAW,EACjB,SAAS,EACT,SAAS,EACT,gCAAW,CAAC,KAAK,EACjB,QAAQ,CACX,CAAC;QACN,CAAC;QAED,OAAO;YACH,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,SAAS;YAChB,aAAa,EAAE,IAAI,CAAC,aAAa;SACpC,CAAC;IACN,CAAC;IAED;;OAEG;IACK,WAAW,CACf,KAAoB,EACpB,WAA0B,EAC1B,SAAiB,EACjB,aAAqB,EACrB,KAAqB;QAErB,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB;YAClC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC;YACxD,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,YAAY,GAAG,IAAA,yBAAU,EAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAEpE,IAAI,QAAQ,GAAiB,YAAY,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,SAAS,GAAG,qBAAS,CAAC;QAE1B,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACxC,IAAA,iCAAiB,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAEnC,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;YAC5C,MAAM,YAAY,GAAG,UAAU;gBAC3B,CAAC,CAAC,qBAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;gBAC5C,CAAC,CAAC,IAAI,CAAC;YAEX,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,CACzB,SAAS,EACT,WAAW,EACX,SAAS,EACT,aAAa,EACb,CAAC,EACD,UAAU,EACV,YAAY,EACZ,qBAAS,EACT,qBAAS,CACZ,CAAC;YAEF,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;gBACpB,SAAS,GAAG,KAAK,CAAC;gBAClB,QAAQ,GAAG,IAAI,CAAC;YACpB,CAAC;QACL,CAAC;QAED,qDAAqD;QACrD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,kBAAkB,CAAC,KAAK,CACzB,KAAK,CAAC,WAAW,EACjB,SAAS,EACT,SAAS,EACT,gCAAW,CAAC,KAAK,EACjB,QAAQ,CACX,CAAC;QACN,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,SAAS,CACb,KAAoB,EACpB,eAA8B,EAC9B,SAAiB,EACjB,aAAqB,EACrB,KAAa,EACb,UAAmB,EACnB,YAA0B,EAC1B,KAAY,EACZ,IAAW;QAEX,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,wBAAwB;QACxB,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACzC,OAAO,qBAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;QAED,2CAA2C;QAC3C,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CACzC,KAAK,CAAC,WAAW,EACjB,SAAS,GAAG,KAAK,GAAG,CAAC,EACrB,KAAK,EACL,IAAI,CACP,CAAC;YAEF,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI,SAAS,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;gBACpD,wBAAwB;gBACxB,IAAI,OAAO,CAAC,IAAI,KAAK,gCAAW,CAAC,KAAK,EAAE,CAAC;oBACrC,OAAO,OAAO,CAAC,KAAK,CAAC;gBACzB,CAAC;gBACD,IAAI,OAAO,CAAC,IAAI,KAAK,gCAAW,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;oBACpE,OAAO,OAAO,CAAC,KAAK,CAAC;gBACzB,CAAC;gBACD,IAAI,OAAO,CAAC,IAAI,KAAK,gCAAW,CAAC,WAAW,IAAI,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC;oBACrE,OAAO,OAAO,CAAC,KAAK,CAAC;gBACzB,CAAC;YACL,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,MAAM,OAAO,GAAG,IAAA,8BAAa,EAAC,KAAK,CAAC,CAAC;QAErC,mDAAmD;QACnD,IAAI,KAAK,GAAG,aAAa,IAAI,OAAO,EAAE,CAAC;YACnC,YAAY,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,6CAA6C;aACxC,IAAI,KAAK,GAAG,SAAS,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG,aAAa,CAAC,EAAE,CAAC;YAClE,YAAY,GAAG,IAAI,CAAC;QACxB,CAAC;QAED,gCAAgC;QAChC,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBACxB,OAAO,YAAY,CAAC;YACxB,CAAC;YACD,OAAO,qBAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACtD,CAAC;QAED,uBAAuB;QACvB,MAAM,KAAK,GAAG,IAAA,kCAAkB,EAAC,KAAK,CAAC,CAAC;QAExC,wEAAwE;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,kBAAkB;YAC3D,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC;YACxD,CAAC,CAAC,IAAI,CAAC;QAEX,iCAAiC;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB;YACtC,CAAC,CAAC,IAAA,yBAAU,EAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC;YACpD,CAAC,CAAC,KAAK,CAAC;QAEZ,8CAA8C;QAC9C,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC;QACpD,IAAI,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,qBAAS,CAAC,CAAC,CAAC,qBAAS,CAAC;QACrD,IAAI,QAAQ,GAAwB,IAAI,CAAC;QACzC,IAAI,eAAe,GAAG,KAAK,CAAC;QAE5B,mBAAmB;QACnB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAC9B,IAAI,eAAe;gBAAE,MAAM;YAE3B,+DAA+D;YAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACxC,IAAA,iCAAiB,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAEnC,sCAAsC;YACtC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;YAEhD,6BAA6B;YAC7B,MAAM,gBAAgB,GAAG,cAAc;gBACnC,CAAC,CAAC,qBAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;gBAChD,CAAC,CAAC,IAAI,CAAC;YAEX,mBAAmB;YACnB,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CACxB,SAAS,EACT,eAAe,EACf,SAAS,EACT,aAAa,EACb,KAAK,GAAG,CAAC,EACT,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,IAAI,CACP,CAAC;YAEF,6BAA6B;YAC7B,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,qBAAS,GAAG,GAAG,EAAE,CAAC;gBACrC,eAAe,GAAG,IAAI,CAAC;YAC3B,CAAC;YAED,+BAA+B;YAC/B,IAAI,YAAY,EAAE,CAAC;gBACf,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;oBACpB,SAAS,GAAG,KAAK,CAAC;oBAClB,QAAQ,GAAG,IAAI,CAAC;gBACpB,CAAC;gBACD,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;oBACpB,SAAS,GAAG,KAAK,CAAC;oBAClB,QAAQ,GAAG,IAAI,CAAC;gBACpB,CAAC;gBACD,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACjC,CAAC;YAED,oBAAoB;YACpB,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;gBAChB,sDAAsD;gBACtD,IAAI,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,gBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC5D,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACxC,CAAC;gBACD,MAAM,CAAC,QAAQ;YACnB,CAAC;QACL,CAAC;QAED,8CAA8C;QAC9C,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,kBAAkB,IAAI,QAAQ,EAAE,CAAC;YAC/D,IAAI,SAAsB,CAAC;YAC3B,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;gBACrB,SAAS,GAAG,gCAAW,CAAC,WAAW,CAAC;YACxC,CAAC;iBAAM,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;gBAC3B,SAAS,GAAG,gCAAW,CAAC,WAAW,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACJ,SAAS,GAAG,gCAAW,CAAC,KAAK,CAAC;YAClC,CAAC;YAED,IAAI,CAAC,kBAAkB,CAAC,KAAK,CACzB,KAAK,CAAC,WAAW,EACjB,SAAS,GAAG,KAAK,GAAG,CAAC,EACrB,SAAS,EACT,SAAS,EACT,QAAQ,CACX,CAAC;QACN,CAAC;QAED,OAAO,SAAS,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACK,SAAS,CAAC,KAAoB;QAClC,OAAO;YACH,OAAO,EAAE,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YACrC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,cAAc,EAAE,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE;YAC3C,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;SACjC,CAAC;IACN,CAAC;CACJ;AAlcD,wBAkcC"}
|
|
@@ -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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"}
|