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.
- 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 +31 -29
- package/.eslintrc.json +0 -16
- package/.github/workflows/main.yml +0 -20
- package/CHANGELOG.md +0 -587
- 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 -943
- 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 -773
- package/webpack.config.js +0 -12
package/README.md
CHANGED
|
@@ -1,338 +1,719 @@
|
|
|
1
1
|
# JS-CHESS-ENGINE
|
|
2
|
+
|
|
2
3
|

|
|
3
|
-

|
|
4
|
-

|
|
5
|
-
[](https://standardjs.com)
|
|
6
4
|
[](https://opensource.org/licenses/MIT)
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
Complete TypeScript chess engine without dependencies for Node.js >=24 and browsers. Includes configurable AI with difficulty levels 1-5.
|
|
7
|
+
|
|
8
|
+
**⚠️ Upgrading from v1?** See [Breaking Changes](#breaking-changes-from-v1) section at the end of this document
|
|
11
9
|
|
|
12
10
|
## Install
|
|
11
|
+
|
|
13
12
|
**Install with npm**
|
|
14
13
|
|
|
15
|
-
```
|
|
14
|
+
```bash
|
|
15
|
+
npm i js-chess-engine --save
|
|
16
|
+
```
|
|
16
17
|
|
|
17
18
|
**or install with yarn**
|
|
18
19
|
|
|
19
|
-
```
|
|
20
|
+
```bash
|
|
21
|
+
yarn add js-chess-engine
|
|
22
|
+
```
|
|
20
23
|
|
|
21
|
-
**
|
|
24
|
+
**Node.js Requirement:** Node.js >=24 is required for v2.
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
const jsChessEngine = require('js-chess-engine')
|
|
25
|
-
const game = new jsChessEngine.Game()
|
|
26
|
-
game.printToConsole()
|
|
27
|
-
```
|
|
28
|
-
more about [importing](#import) this library.
|
|
29
|
-
## Examples
|
|
30
|
-
**js-chess-engine-app** - React application example with js-chess-engine REST API backend (without persistent storage) - [GitHub](https://github.com/josefjadrny/js-chess-engine-app) or [LIVE DEMO](http://chess.nadsenyvyvojar.cz/)
|
|
26
|
+
## Import
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
[Simple Fastify server](example/server.mjs) <BR/>
|
|
34
|
-
[Console](example/console.mjs) <BR/>
|
|
35
|
-
[PC vs PC match](example/aiMatch.mjs) <BR/>
|
|
28
|
+
### TypeScript / ESM
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
```typescript
|
|
31
|
+
// Import Game class and stateless functions
|
|
32
|
+
import { Game, moves, status, move, aiMove, getFen } from 'js-chess-engine'
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const game = new
|
|
34
|
+
// Import types for TypeScript
|
|
35
|
+
import type { BoardConfig, PieceSymbol, MovesMap, AILevel } from 'js-chess-engine'
|
|
36
|
+
|
|
37
|
+
const game = new Game()
|
|
45
38
|
```
|
|
46
39
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const
|
|
40
|
+
### CommonJS (Node.js)
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
const { Game, moves, status, move, aiMove, getFen } = require('js-chess-engine')
|
|
44
|
+
|
|
45
|
+
const game = new Game()
|
|
51
46
|
```
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
### React / Modern JavaScript
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { Game } from 'js-chess-engine'
|
|
52
|
+
import type { BoardConfig, MovesMap } from 'js-chess-engine'
|
|
53
|
+
|
|
56
54
|
const game = new Game()
|
|
55
|
+
const allMoves: MovesMap = game.moves()
|
|
57
56
|
```
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
## Examples
|
|
60
59
|
|
|
61
|
-
**
|
|
62
|
-
- [With in-memory](#option-1---with-in-memory)
|
|
63
|
-
- [Without in-memory (on-the-fly)](#option-2---without-in-memory)
|
|
60
|
+
**js-chess-engine-app** - React application example with js-chess-engine REST API backend (without persistent storage) - [GitHub](https://github.com/josefjadrny/js-chess-engine-app) or [LIVE DEMO](http://chess.josefjadrny.info/)
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
**Note:** Additional examples for v2 (server, console, AI match) will be added in a future release.
|
|
63
|
+
|
|
64
|
+
## Documentation
|
|
65
|
+
|
|
66
|
+
You have two options for using this engine:
|
|
67
|
+
|
|
68
|
+
- [Option 1 - With in-memory (Game class)](#option-1---with-in-memory)
|
|
69
|
+
- [Option 2 - Without in-memory (Stateless functions)](#option-2---without-in-memory)
|
|
66
70
|
|
|
67
71
|
### Option 1 - With in-memory
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
|
|
73
|
+
Use the Game class to create and manage a chess game. In this mode, the game state is cached in memory for better performance.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { Game } from 'js-chess-engine'
|
|
77
|
+
import type { BoardConfig, MovesMap } from 'js-chess-engine'
|
|
78
|
+
|
|
79
|
+
const game = new Game()
|
|
72
80
|
```
|
|
73
81
|
|
|
74
|
-
You can
|
|
75
|
-
In this mode, many things on the chessboard are cached (in-memory), so it is faster.
|
|
76
|
-
You can still export your game to JSON or FEN and you can use this JSON or FEN to continue your game later.
|
|
82
|
+
You can export your game to JSON or FEN at any time and use these formats to restore your game later.
|
|
77
83
|
|
|
78
|
-
#### API
|
|
84
|
+
#### API Description
|
|
79
85
|
|
|
80
86
|
**constructor**
|
|
81
87
|
|
|
82
|
-
`new Game(configuration)` - Create a new game
|
|
88
|
+
`new Game(configuration)` - Create a new game with optional initial configuration.
|
|
89
|
+
|
|
90
|
+
Params:
|
|
91
|
+
- `configuration` BoardConfig | string (_optional_) - Chess board [configuration](#board-configuration) (JSON object or FEN string). Default is standard starting position.
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { Game } from 'js-chess-engine'
|
|
95
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
96
|
+
|
|
97
|
+
// New game with starting position
|
|
98
|
+
const game1 = new Game()
|
|
83
99
|
|
|
84
|
-
|
|
85
|
-
|
|
100
|
+
// From FEN string
|
|
101
|
+
const game2 = new Game('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1')
|
|
102
|
+
|
|
103
|
+
// From BoardConfig object
|
|
104
|
+
const config: BoardConfig = { /* ... */ }
|
|
105
|
+
const game3 = new Game(config)
|
|
106
|
+
```
|
|
86
107
|
|
|
87
108
|
**move**
|
|
88
109
|
|
|
89
|
-
`game.move(from, to)` - Perform a move on
|
|
110
|
+
`game.move(from, to)` - Perform a move on the chessboard and recalculate game state. **Returns full BoardConfig object** (breaking change from v1).
|
|
111
|
+
|
|
112
|
+
Params:
|
|
113
|
+
- `from` string (_mandatory_) - Starting square (case-insensitive, e.g., 'E2' or 'e2')
|
|
114
|
+
- `to` string (_mandatory_) - Destination square (case-insensitive, e.g., 'E4' or 'e4')
|
|
115
|
+
|
|
116
|
+
Returns: `BoardConfig` - Full board configuration after the move
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
90
120
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
121
|
+
const newConfig: BoardConfig = game.move('E2', 'E4')
|
|
122
|
+
console.log(newConfig.pieces) // {"E4": "P", "E1": "K", ...}
|
|
123
|
+
```
|
|
94
124
|
|
|
95
125
|
**moves**
|
|
96
126
|
|
|
97
|
-
`game.moves(from)` -
|
|
127
|
+
`game.moves(from?)` - Get all legal moves for the current player. Optionally filter by a specific square.
|
|
128
|
+
|
|
129
|
+
Params:
|
|
130
|
+
- `from` string (_optional_) - Square to filter moves from (case-insensitive, e.g., 'E2'). If omitted, returns moves for all pieces.
|
|
131
|
+
|
|
132
|
+
Returns: `MovesMap` - Object mapping from-squares to arrays of to-squares
|
|
98
133
|
|
|
99
|
-
|
|
100
|
-
|
|
134
|
+
```typescript
|
|
135
|
+
import type { MovesMap } from 'js-chess-engine'
|
|
136
|
+
|
|
137
|
+
// Get all moves (no parameter)
|
|
138
|
+
const allMoves: MovesMap = game.moves()
|
|
139
|
+
// {"E2": ["E3", "E4"], "B1": ["A3", "C3"], ...}
|
|
140
|
+
|
|
141
|
+
// Get moves for specific square
|
|
142
|
+
const pawnMoves: MovesMap = game.moves('E2')
|
|
143
|
+
// {"E2": ["E3", "E4"]}
|
|
144
|
+
```
|
|
101
145
|
|
|
102
146
|
**setPiece**
|
|
103
147
|
|
|
104
|
-
`game.setPiece(location, piece)` -
|
|
148
|
+
`game.setPiece(location, piece)` - Add or replace a chess piece at the specified location.
|
|
105
149
|
|
|
106
|
-
Params
|
|
107
|
-
- `location`
|
|
108
|
-
- `piece`
|
|
150
|
+
Params:
|
|
151
|
+
- `location` string (_mandatory_) - Square location (case-insensitive, e.g., 'E2')
|
|
152
|
+
- `piece` PieceSymbol (_mandatory_) - Piece symbol using FEN notation (K, Q, R, B, N, P for white; k, q, r, b, n, p for black)
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import type { PieceSymbol } from 'js-chess-engine'
|
|
156
|
+
|
|
157
|
+
const piece: PieceSymbol = 'Q'
|
|
158
|
+
game.setPiece('E5', piece)
|
|
159
|
+
```
|
|
109
160
|
|
|
110
161
|
**removePiece**
|
|
111
162
|
|
|
112
|
-
`game.removePiece(location)` - Remove piece
|
|
163
|
+
`game.removePiece(location)` - Remove a piece from the specified location.
|
|
113
164
|
|
|
114
|
-
Params
|
|
115
|
-
- `location`
|
|
165
|
+
Params:
|
|
166
|
+
- `location` string (_mandatory_) - Square location (case-insensitive, e.g., 'E2')
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
game.removePiece('E5')
|
|
170
|
+
```
|
|
116
171
|
|
|
117
172
|
**aiMove**
|
|
118
173
|
|
|
119
|
-
`game.aiMove(level)` -
|
|
174
|
+
`game.aiMove(level)` - Calculate and perform the best move for the current player using AI. **Returns only the move** (v1 API compatible).
|
|
120
175
|
|
|
121
|
-
Params
|
|
122
|
-
|
|
176
|
+
Params:
|
|
177
|
+
- `level` AILevel (_optional_) - AI difficulty level (1-5). See [Computer AI](#computer-ai) section. Default: 3
|
|
178
|
+
|
|
179
|
+
Returns: `HistoryEntry` - The played move (e.g., `{"E2": "E4"}`)
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import type { HistoryEntry, AILevel } from 'js-chess-engine'
|
|
183
|
+
|
|
184
|
+
const level: AILevel = 4
|
|
185
|
+
const move: HistoryEntry = game.aiMove(level)
|
|
186
|
+
console.log(move) // {"E2": "E4"}
|
|
187
|
+
|
|
188
|
+
// To get board state after move, use exportJson()
|
|
189
|
+
const board = game.exportJson()
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**ai**
|
|
193
|
+
|
|
194
|
+
`game.ai(options?)` - Calculate the best move using AI. **Returns both the move and board state**.
|
|
195
|
+
|
|
196
|
+
Params:
|
|
197
|
+
- `options` object (_optional_) - Configuration options:
|
|
198
|
+
- `level` number (_optional_) - AI difficulty level (1-5). See [Computer AI](#computer-ai) section. Default: `3`
|
|
199
|
+
- `play` boolean (_optional_) - Whether to apply the move to the game. Default: `true`. If `false`, returns the move without modifying the game state, and `board` will contain the current state (before the move).
|
|
200
|
+
- `ttSizeMB` number (_optional_) - Transposition table size in MB (0 to disable, 0.25-256). Default: **auto-scaled by AI level**. See [Auto-Scaling Transposition Table](#transposition-table) for details.
|
|
201
|
+
|
|
202
|
+
Returns: `{ move: HistoryEntry, board: BoardConfig }` - Object containing the move and board state (current state if `play=false`, updated state if `play=true`)
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import type { HistoryEntry, BoardConfig } from 'js-chess-engine'
|
|
206
|
+
|
|
207
|
+
// Play the move (default behavior)
|
|
208
|
+
const result1 = game.ai({ level: 4 })
|
|
209
|
+
console.log(result1.move) // {"E2": "E4"}
|
|
210
|
+
console.log(result1.board.turn) // "black" (updated after move)
|
|
211
|
+
|
|
212
|
+
// Analysis mode: get move without applying it
|
|
213
|
+
const result2 = game.ai({ level: 4, play: false })
|
|
214
|
+
console.log(result2.move) // {"E2": "E4"}
|
|
215
|
+
console.log(result2.board.turn) // "white" (current state, before move)
|
|
216
|
+
|
|
217
|
+
// Use default level 3
|
|
218
|
+
const result3 = game.ai()
|
|
219
|
+
console.log(result3.move) // AI move with level 3
|
|
220
|
+
|
|
221
|
+
// TT size auto-scales by level (see Auto-Scaling Transposition Table section)
|
|
222
|
+
const result4 = game.ai({ level: 5 })
|
|
223
|
+
console.log(result4.move) // Level 5: 64 MB Node.js / 32 MB browser (auto)
|
|
224
|
+
|
|
225
|
+
// Override TT size manually if needed
|
|
226
|
+
const result5 = game.ai({ level: 3, ttSizeMB: 128 })
|
|
227
|
+
console.log(result5.move) // Force 128MB cache
|
|
228
|
+
|
|
229
|
+
// Ultra-lightweight mode for low-end devices
|
|
230
|
+
const result6 = game.ai({ level: 2, ttSizeMB: 0.5 })
|
|
231
|
+
console.log(result6.move) // Force 512KB cache
|
|
232
|
+
```
|
|
123
233
|
|
|
124
234
|
**getHistory**
|
|
125
235
|
|
|
126
|
-
`game.getHistory(
|
|
236
|
+
`game.getHistory()` - Get all played moves with board states.
|
|
127
237
|
|
|
128
|
-
|
|
238
|
+
Returns: Array of objects containing move and resulting board configuration
|
|
129
239
|
|
|
130
|
-
|
|
131
|
-
|
|
240
|
+
```typescript
|
|
241
|
+
const history = game.getHistory()
|
|
242
|
+
// [
|
|
243
|
+
// { move: {"E2": "E4"}, pieces: {...}, turn: "black", ... },
|
|
244
|
+
// { move: {"E7": "E5"}, pieces: {...}, turn: "white", ... }
|
|
245
|
+
// ]
|
|
246
|
+
```
|
|
132
247
|
|
|
133
248
|
**printToConsole**
|
|
134
249
|
|
|
135
|
-
`game.printToConsole()` - Print
|
|
250
|
+
`game.printToConsole()` - Print an ASCII representation of the chessboard to console.
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
game.printToConsole()
|
|
254
|
+
// +---+---+---+---+---+---+---+---+
|
|
255
|
+
// 8 | r | n | b | q | k | b | n | r |
|
|
256
|
+
// +---+---+---+---+---+---+---+---+
|
|
257
|
+
// 7 | p | p | p | p | p | p | p | p |
|
|
258
|
+
// +---+---+---+---+---+---+---+---+
|
|
259
|
+
// ...
|
|
260
|
+
```
|
|
136
261
|
|
|
137
262
|
**exportJson**
|
|
138
263
|
|
|
139
|
-
`game.exportJson()` -
|
|
264
|
+
`game.exportJson()` - Export current game state as a JSON BoardConfig object.
|
|
265
|
+
|
|
266
|
+
Returns: `BoardConfig` - Full board configuration
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
270
|
+
|
|
271
|
+
const config: BoardConfig = game.exportJson()
|
|
272
|
+
```
|
|
140
273
|
|
|
141
274
|
**exportFEN**
|
|
142
275
|
|
|
143
|
-
`game.exportFEN()` -
|
|
276
|
+
`game.exportFEN()` - Export current game state as a FEN string.
|
|
144
277
|
|
|
145
|
-
|
|
278
|
+
Returns: string - [FEN notation](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation)
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
const fen: string = game.exportFEN()
|
|
282
|
+
// "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1"
|
|
283
|
+
```
|
|
146
284
|
|
|
147
285
|
### Option 2 - Without in-memory
|
|
148
|
-
It is possible to avoid using a Game object and call stateless functions directly. Every function needs configuration of your chessboard to work properly.
|
|
149
|
-
This approach needs little more computing time to create and calculate everything from scratch for every call.
|
|
150
|
-
But this can be handy in stateless environments.
|
|
151
286
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
287
|
+
Call stateless functions directly without creating a Game object. This is ideal for serverless environments or when you want to manage state externally.
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
import { move, moves, status, aiMove, ai, getFen } from 'js-chess-engine'
|
|
291
|
+
import type { BoardConfig, MovesMap } from 'js-chess-engine'
|
|
155
292
|
```
|
|
156
|
-
|
|
293
|
+
|
|
294
|
+
These functions require a board configuration for each call (either a BoardConfig object or FEN string).
|
|
295
|
+
|
|
296
|
+
#### API Description
|
|
157
297
|
|
|
158
298
|
**moves**
|
|
159
299
|
|
|
160
|
-
`moves(boardConfiguration)` -
|
|
300
|
+
`moves(boardConfiguration)` - Get all legal moves for the current player.
|
|
301
|
+
|
|
302
|
+
Params:
|
|
303
|
+
- `boardConfiguration` BoardConfig | string (_mandatory_) - Board [configuration](#board-configuration) (JSON object or FEN string)
|
|
304
|
+
|
|
305
|
+
Returns: `MovesMap` - Object mapping from-squares to arrays of to-squares
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
import { moves } from 'js-chess-engine'
|
|
309
|
+
import type { MovesMap, BoardConfig } from 'js-chess-engine'
|
|
161
310
|
|
|
162
|
-
|
|
163
|
-
|
|
311
|
+
// From BoardConfig object
|
|
312
|
+
const config: BoardConfig = { /* ... */ }
|
|
313
|
+
const allMoves: MovesMap = moves(config)
|
|
314
|
+
// {"E2": ["E3", "E4"], "B1": ["A3", "C3"], ...}
|
|
315
|
+
|
|
316
|
+
// From FEN string
|
|
317
|
+
const fenMoves: MovesMap = moves('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1')
|
|
318
|
+
```
|
|
164
319
|
|
|
165
320
|
**status**
|
|
166
321
|
|
|
167
|
-
`status(boardConfiguration)` -
|
|
322
|
+
`status(boardConfiguration)` - Get calculated board configuration with current game status. Useful for converting FEN to JSON.
|
|
323
|
+
|
|
324
|
+
Params:
|
|
325
|
+
- `boardConfiguration` BoardConfig | string (_mandatory_) - Board [configuration](#board-configuration)
|
|
326
|
+
|
|
327
|
+
Returns: `BoardConfig` - Full board configuration with status
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
import { status } from 'js-chess-engine'
|
|
331
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
168
332
|
|
|
169
|
-
|
|
170
|
-
|
|
333
|
+
// Convert FEN to JSON
|
|
334
|
+
const config: BoardConfig = status('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1')
|
|
335
|
+
console.log(config.turn) // "black"
|
|
336
|
+
console.log(config.check) // false
|
|
337
|
+
console.log(config.checkMate) // false
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**getFen**
|
|
341
|
+
|
|
342
|
+
`getFen(boardConfiguration)` - Convert board configuration to FEN string.
|
|
171
343
|
|
|
172
|
-
|
|
344
|
+
Params:
|
|
345
|
+
- `boardConfiguration` BoardConfig | string (_mandatory_) - Board [configuration](#board-configuration)
|
|
173
346
|
|
|
174
|
-
|
|
347
|
+
Returns: string - [FEN notation](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation)
|
|
175
348
|
|
|
176
|
-
|
|
177
|
-
|
|
349
|
+
```typescript
|
|
350
|
+
import { getFen } from 'js-chess-engine'
|
|
351
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
352
|
+
|
|
353
|
+
const config: BoardConfig = { /* ... */ }
|
|
354
|
+
const fen: string = getFen(config)
|
|
355
|
+
```
|
|
178
356
|
|
|
179
357
|
**move**
|
|
180
358
|
|
|
181
|
-
`move(boardConfiguration, from, to)` - Perform a move
|
|
359
|
+
`move(boardConfiguration, from, to)` - Perform a move and get the new board state. **Returns full BoardConfig object** (breaking change from v1).
|
|
182
360
|
|
|
183
|
-
Params
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
361
|
+
Params:
|
|
362
|
+
- `boardConfiguration` BoardConfig | string (_mandatory_) - Board [configuration](#board-configuration)
|
|
363
|
+
- `from` string (_mandatory_) - Starting square (case-insensitive)
|
|
364
|
+
- `to` string (_mandatory_) - Destination square (case-insensitive)
|
|
365
|
+
|
|
366
|
+
Returns: `BoardConfig` - Full board configuration after the move
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { move } from 'js-chess-engine'
|
|
370
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
371
|
+
|
|
372
|
+
// Move from FEN string
|
|
373
|
+
const config1: BoardConfig = move('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1', 'E2', 'E4')
|
|
374
|
+
|
|
375
|
+
// Move on existing config
|
|
376
|
+
const config2: BoardConfig = move(config1, 'E7', 'E5')
|
|
377
|
+
```
|
|
187
378
|
|
|
188
379
|
**aiMove**
|
|
189
380
|
|
|
190
|
-
`aiMove(boardConfiguration, level)` -
|
|
381
|
+
`aiMove(boardConfiguration, level)` - Calculate and return the best move using AI. **Returns only the move** (v1 API compatible).
|
|
382
|
+
|
|
383
|
+
Params:
|
|
384
|
+
- `boardConfiguration` BoardConfig | string (_mandatory_) - Board [configuration](#board-configuration)
|
|
385
|
+
- `level` AILevel (_optional_) - AI difficulty level (1-5). Default: 3
|
|
386
|
+
|
|
387
|
+
Returns: `HistoryEntry` - The played move (e.g., `{"E2": "E4"}`)
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
import { aiMove } from 'js-chess-engine'
|
|
391
|
+
import type { HistoryEntry, AILevel } from 'js-chess-engine'
|
|
392
|
+
|
|
393
|
+
const fen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
|
|
394
|
+
const level: AILevel = 4
|
|
395
|
+
const move: HistoryEntry = aiMove(fen, level)
|
|
396
|
+
console.log(move) // {"E2": "E4"}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**ai**
|
|
191
400
|
|
|
192
|
-
|
|
193
|
-
- `boardConfiguration` Object or String (_mandatory_) - Is a chess board [configuration](#board-configuration). Default value is a configuration for new game.
|
|
194
|
-
- `level` Integer (_optional_) - Computer player skill from 0 to 3. Read more about [computer AI](#computer-ai). Default 2.
|
|
401
|
+
`ai(boardConfiguration, options?)` - Calculate the best move using AI. **Returns both the move and board state**.
|
|
195
402
|
|
|
196
|
-
|
|
403
|
+
Params:
|
|
404
|
+
- `boardConfiguration` BoardConfig | string (_mandatory_) - Board [configuration](#board-configuration)
|
|
405
|
+
- `options` object (_optional_) - Configuration options:
|
|
406
|
+
- `level` number (_optional_) - AI difficulty level (1-5). Default: `3`
|
|
407
|
+
- `play` boolean (_optional_) - Whether to apply the move to the board. Default: `true`. If `false`, returns the move without modifying the board state, and `board` will contain the current state (before the move).
|
|
408
|
+
- `ttSizeMB` number (_optional_) - Transposition table size in MB (0 to disable, 0.25-256). Default: **auto-scaled by AI level**. See [Auto-Scaling Transposition Table](#transposition-table) for details.
|
|
409
|
+
|
|
410
|
+
Returns: `{ move: HistoryEntry, board: BoardConfig }` - Object containing the move and board state (current state if `play=false`, updated state if `play=true`)
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
import { ai } from 'js-chess-engine'
|
|
414
|
+
import type { HistoryEntry, BoardConfig } from 'js-chess-engine'
|
|
415
|
+
|
|
416
|
+
const fen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
|
|
417
|
+
|
|
418
|
+
// Play the move (default behavior)
|
|
419
|
+
const result1 = ai(fen, { level: 4 })
|
|
420
|
+
console.log(result1.move) // {"E2": "E4"}
|
|
421
|
+
console.log(result1.board.turn) // "black" (updated after move)
|
|
422
|
+
|
|
423
|
+
// Analysis mode: get move without applying it
|
|
424
|
+
const result2 = ai(fen, { level: 4, play: false })
|
|
425
|
+
console.log(result2.move) // {"E2": "E4"}
|
|
426
|
+
console.log(result2.board.turn) // "white" (current state, before move)
|
|
427
|
+
|
|
428
|
+
// Use default level 3
|
|
429
|
+
const result3 = ai(fen)
|
|
430
|
+
console.log(result3.move) // AI move with level 3
|
|
431
|
+
|
|
432
|
+
// TT size auto-scales by level (see Auto-Scaling Transposition Table section)
|
|
433
|
+
const result4 = ai(fen, { level: 5 })
|
|
434
|
+
console.log(result4.move) // Level 5: 64 MB Node.js / 32 MB browser (auto)
|
|
435
|
+
|
|
436
|
+
// Override TT size manually if needed
|
|
437
|
+
const result5 = ai(fen, { level: 3, ttSizeMB: 128 })
|
|
438
|
+
console.log(result5.move) // Force 128MB cache
|
|
439
|
+
|
|
440
|
+
// Ultra-lightweight mode for low-end devices
|
|
441
|
+
const result6 = ai(fen, { level: 2, ttSizeMB: 0.5 })
|
|
442
|
+
console.log(result6.move) // Force 512KB cache
|
|
443
|
+
```
|
|
197
444
|
|
|
198
445
|
### Board Configuration
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
```
|
|
207
|
-
{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
"
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
"
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
"fullMove": 1
|
|
446
|
+
|
|
447
|
+
Board configuration can be represented as either a JSON object (BoardConfig) or a FEN string.
|
|
448
|
+
|
|
449
|
+
#### JSON Format
|
|
450
|
+
|
|
451
|
+
The JSON format is convenient for modern applications where state is represented as objects (React, Redux, etc.).
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
import type { BoardConfig } from 'js-chess-engine'
|
|
455
|
+
|
|
456
|
+
const config: BoardConfig = {
|
|
457
|
+
"turn": "black",
|
|
458
|
+
"pieces": {
|
|
459
|
+
"E1": "K",
|
|
460
|
+
"C1": "B",
|
|
461
|
+
"E8": "k"
|
|
462
|
+
},
|
|
463
|
+
"isFinished": false,
|
|
464
|
+
"check": false,
|
|
465
|
+
"checkMate": false,
|
|
466
|
+
"castling": {
|
|
467
|
+
"whiteLong": true,
|
|
468
|
+
"whiteShort": true,
|
|
469
|
+
"blackLong": true,
|
|
470
|
+
"blackShort": true
|
|
471
|
+
},
|
|
472
|
+
"enPassant": "E6",
|
|
473
|
+
"halfMove": 0,
|
|
474
|
+
"fullMove": 1
|
|
229
475
|
}
|
|
230
476
|
```
|
|
231
477
|
|
|
232
|
-
**turn** - Player
|
|
478
|
+
**turn** - Player to move next. Values: `"white"` (default) or `"black"`
|
|
233
479
|
|
|
234
|
-
**isFinished** - `true` when
|
|
480
|
+
**isFinished** - `true` when the game is over (checkmate or stalemate). Default: `false`
|
|
235
481
|
|
|
236
|
-
**check** - `true` when
|
|
482
|
+
**check** - `true` when the current player is in check. Default: `false`
|
|
237
483
|
|
|
238
|
-
**checkMate** - `true` when
|
|
484
|
+
**checkMate** - `true` when the current player is checkmated. Default: `false`
|
|
239
485
|
|
|
240
|
-
**castling** -
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
**enPassant** - If a pawn has just made a two-square move, this is the position "behind" the pawn.
|
|
247
|
-
This is an indicator for [enPassant](https://en.wikipedia.org/wiki/En_passant) special pawn move. Default `null`.
|
|
486
|
+
**castling** - Castling availability for each side. `true` means castling is still possible. Default: all `true`
|
|
487
|
+
- `whiteLong` (queenside) - White king moves from E1 to C1
|
|
488
|
+
- `whiteShort` (kingside) - White king moves from E1 to G1
|
|
489
|
+
- `blackLong` (queenside) - Black king moves from E8 to C8
|
|
490
|
+
- `blackShort` (kingside) - Black king moves from E8 to G8
|
|
248
491
|
|
|
249
|
-
**
|
|
492
|
+
**enPassant** - If a pawn just made a two-square move, this is the square "behind" the pawn for [en passant](https://en.wikipedia.org/wiki/En_passant) capture. Default: `null`
|
|
250
493
|
|
|
251
|
-
**
|
|
252
|
-
|
|
253
|
-
**
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
494
|
+
**halfMove** - Number of halfmoves since the last capture or pawn advance. Used for the [fifty-move rule](https://en.wikipedia.org/wiki/Fifty-move_rule). Default: `0`
|
|
495
|
+
|
|
496
|
+
**fullMove** - Full move number. Starts at 1 and increments after Black's move. Default: `1`
|
|
497
|
+
|
|
498
|
+
**pieces** - Pieces on the board using FEN notation:
|
|
499
|
+
|
|
500
|
+
| Piece | White | Black |
|
|
501
|
+
| :----: | :---: | :---: |
|
|
502
|
+
| Pawn | P | p |
|
|
503
|
+
| Knight | N | n |
|
|
504
|
+
| Bishop | B | b |
|
|
505
|
+
| Rook | R | r |
|
|
506
|
+
| Queen | Q | q |
|
|
507
|
+
| King | K | k |
|
|
508
|
+
|
|
509
|
+
#### FEN Format
|
|
510
|
+
|
|
511
|
+
You can also use [Forsyth–Edwards Notation (FEN)](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation):
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
import { move } from 'js-chess-engine'
|
|
515
|
+
|
|
516
|
+
const fen = 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
|
|
517
|
+
const newConfig = move(fen, 'H7', 'H5')
|
|
518
|
+
console.log(newConfig)
|
|
519
|
+
// BoardConfig object with updated position
|
|
260
520
|
```
|
|
261
|
-
Means A7 can move to A6 and A5. B7 can move to B6 and B5.
|
|
262
521
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
|
268
|
-
|
|
|
269
|
-
|
|
|
270
|
-
|
|
|
271
|
-
|
|
|
522
|
+
### Computer AI
|
|
523
|
+
|
|
524
|
+
The engine includes a sophisticated AI based on the Minimax algorithm with alpha-beta pruning, enhanced with advanced performance optimizations. There are five difficulty levels:
|
|
525
|
+
|
|
526
|
+
| Level | Alias | Description | Search Depth | Avg. Time |
|
|
527
|
+
| :---: | :---------------- | :----------------------------------- | :----------: | :-------: |
|
|
528
|
+
| 1 | Beginner | Very weak play, minimal lookahead | 1-2 ply | <10ms |
|
|
529
|
+
| 2 | Easy | Suitable for new chess players | 2-3 ply | ~50ms |
|
|
530
|
+
| 3 | Intermediate | Balanced difficulty (default) | 3-4 ply | ~300ms |
|
|
531
|
+
| 4 | Advanced | Strong play with deeper search | 4-5 ply | ~2s |
|
|
532
|
+
| 5 | Expert | Maximum difficulty and search depth | 5-6 ply | ~7s |
|
|
272
533
|
|
|
534
|
+
**Note:** Performance varies based on hardware and position complexity. Times shown are approximate averages on modern hardware.
|
|
273
535
|
|
|
274
|
-
|
|
275
|
-
|
|
536
|
+
```typescript
|
|
537
|
+
import { Game } from 'js-chess-engine'
|
|
538
|
+
import type { AILevel } from 'js-chess-engine'
|
|
276
539
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
//
|
|
540
|
+
const game = new Game()
|
|
541
|
+
|
|
542
|
+
// Different difficulty levels
|
|
543
|
+
game.aiMove(1) // Beginner
|
|
544
|
+
game.aiMove(2) // Easy
|
|
545
|
+
game.aiMove(3) // Intermediate (default)
|
|
546
|
+
game.aiMove(4) // Advanced
|
|
547
|
+
game.aiMove(5) // Expert
|
|
283
548
|
```
|
|
284
549
|
|
|
285
|
-
|
|
550
|
+
**Implementation Highlights:**
|
|
551
|
+
- Alpha-beta pruning with transposition table (auto-scales by AI level for optimal memory usage)
|
|
552
|
+
- Advanced move ordering (PV moves, MVV-LVA captures, killer moves)
|
|
553
|
+
- Iterative deepening for optimal move ordering
|
|
554
|
+
- Position evaluation with material balance and piece-square tables
|
|
555
|
+
- 65% performance improvement over baseline implementation
|
|
556
|
+
- Smart environment detection and level-based memory scaling for optimal performance across platforms
|
|
286
557
|
|
|
287
|
-
|
|
558
|
+
#### Auto-Scaling Transposition Table (Smart Memory Management) {#transposition-table}
|
|
559
|
+
|
|
560
|
+
The engine automatically adjusts cache size based on AI level and environment:
|
|
561
|
+
|
|
562
|
+
| AI Level | Node.js Cache | Browser Cache | Use Case |
|
|
563
|
+
| :------: | :-----------: | :-----------: | :--------------------------- |
|
|
564
|
+
| 1 | 2 MB | 1 MB | Lightweight, fast responses |
|
|
565
|
+
| 2 | 4 MB | 2 MB | Mobile-friendly performance |
|
|
566
|
+
| 3 | 16 MB | 8 MB | Balanced (default) |
|
|
567
|
+
| 4 | 32 MB | 16 MB | Strong tactical play |
|
|
568
|
+
| 5 | 64 MB | 32 MB | Maximum strength |
|
|
569
|
+
|
|
570
|
+
Lower levels use less memory for faster responses, higher levels use more for better move quality. Browser cache sizes are appropriate for modern devices (2024+). Override with `ttSizeMB` option if needed.
|
|
571
|
+
|
|
572
|
+
📚 **[Complete AI Implementation Guide →](docs/AI_IMPLEMENTATION.md)**
|
|
573
|
+
|
|
574
|
+
For comprehensive technical documentation including algorithms, data structures, optimization techniques, and developer guides, see the AI implementation documentation.
|
|
575
|
+
|
|
576
|
+
## Hints
|
|
577
|
+
|
|
578
|
+
- **Pawn Promotion:** When a pawn reaches the opposite end of the board, it is automatically promoted to a Queen. If you want the player to choose the promotion piece in your application, use the `setPiece()` method to replace the queen with the desired piece.
|
|
288
579
|
|
|
289
|
-
|
|
580
|
+
- **Castling:** Castling moves are included in the moves returned by `moves()`. When a king moves two squares (castling), the rook automatically moves as well.
|
|
290
581
|
|
|
291
|
-
|
|
292
|
-
| :-: | :-:| :-:| :-:| :-:|
|
|
293
|
-
| 0 |Well-trained monkey| 1-2 | None | <0.01 |
|
|
294
|
-
| 1 |Beginner| 2-4 | Very low | <0.1 |
|
|
295
|
-
| 2 |Intermediate| 2-4 | Low | 0.7 |
|
|
296
|
-
| 3 |Advanced| 3-5 | Medium | 4.6 |
|
|
297
|
-
| 4 |Experienced| 4-5 | High | 9.5 |
|
|
582
|
+
- **Fifty-Move Rule:** The `halfMove` counter is calculated automatically, but the [fifty-move rule](https://en.wikipedia.org/wiki/Fifty-move_rule) is not enforced by the engine. You can implement this rule in your application if needed.
|
|
298
583
|
|
|
299
|
-
|
|
300
|
-
T3.nano is a low-cost machine with 0.5 GiB RAM and basic CPU performance. Please note, amount of time needed for calculations heavily depends on in-game situation (number of chess pieces still on a chessboard).
|
|
584
|
+
## TypeScript Support
|
|
301
585
|
|
|
302
|
-
|
|
586
|
+
Version 2.0 is written entirely in TypeScript and exports all necessary types:
|
|
303
587
|
|
|
304
|
-
|
|
588
|
+
```typescript
|
|
589
|
+
import { Game } from 'js-chess-engine'
|
|
590
|
+
import type {
|
|
591
|
+
// Board types
|
|
592
|
+
BoardConfig,
|
|
593
|
+
PieceSymbol,
|
|
594
|
+
Square,
|
|
595
|
+
Color,
|
|
596
|
+
MovesMap,
|
|
597
|
+
CastlingRights,
|
|
598
|
+
HistoryEntry,
|
|
305
599
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
For in-memory approach please check **setPiece** function.
|
|
309
|
-
- Castling can be played by a King. You can receive this special move with `moves` call.
|
|
310
|
-
When a move is recognized as a castling - played with a king across two chess fields, rook moves automatically with a king.
|
|
311
|
-
- Halfmoves are calculated on the server, but the [fifty-move rule](https://en.wikipedia.org/wiki/Fifty-move_rule) is not handled by a server. You can handle this situation in your app if you need to.
|
|
600
|
+
// AI types
|
|
601
|
+
AILevel,
|
|
312
602
|
|
|
313
|
-
|
|
603
|
+
// Piece types
|
|
604
|
+
PieceType
|
|
605
|
+
} from 'js-chess-engine'
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
See `/src/types/board.types.ts` and `/src/types/ai.types.ts` for complete type definitions.
|
|
314
609
|
|
|
315
610
|
## Collaboration
|
|
316
611
|
|
|
317
|
-
**Collaborators are welcome.** Please
|
|
612
|
+
**Collaborators are welcome.** Please ensure your code passes TypeScript type checking and all tests before submitting a pull request:
|
|
318
613
|
|
|
319
|
-
|
|
614
|
+
```bash
|
|
615
|
+
npm run typecheck # TypeScript type checking
|
|
616
|
+
npm run test # Run test suite
|
|
617
|
+
```
|
|
320
618
|
|
|
321
|
-
|
|
619
|
+
If possible, use commit message prefixes like `feat:` or `fix:` - the changelog is generated from these.
|
|
322
620
|
|
|
323
621
|
## TODO
|
|
324
|
-
- Calculation and result caching
|
|
325
|
-
- Forsyth–Edwards Notation (FEN) validation
|
|
326
622
|
|
|
327
|
-
|
|
623
|
+
- FEN validation
|
|
624
|
+
- Additional endgame tablebase support
|
|
328
625
|
|
|
329
626
|
## CHANGELOG
|
|
330
|
-
Changelog can be found [HERE](CHANGELOG.md) .
|
|
331
627
|
|
|
332
|
-
|
|
628
|
+
Changelog can be found [HERE](CHANGELOG.md).
|
|
333
629
|
|
|
334
630
|
## In conclusion - why another chess engine?
|
|
631
|
+
|
|
335
632
|
I am not a chess pro. My father is.
|
|
336
|
-
|
|
337
|
-
My father told me
|
|
338
|
-
|
|
633
|
+
|
|
634
|
+
When I was ten, I had an Atari (with Turbo Basic), and I was hoping for a new PC. My father told me: "Make me a computer program which beats me in chess, and I'll buy you a new PC."
|
|
635
|
+
|
|
636
|
+
Obviously, it was a trap and I failed. Twenty years later, it came back to my mind, and I decided to finish what I started. This is version 2.0 - a complete TypeScript rewrite with improved performance and architecture.
|
|
637
|
+
|
|
638
|
+
## Breaking Changes from v1
|
|
639
|
+
|
|
640
|
+
Version 2.0 is a complete TypeScript rewrite with significant API changes. While method names remain the same, **several return types have changed**:
|
|
641
|
+
|
|
642
|
+
### 1. `moves(square)` Return Type Changed
|
|
643
|
+
|
|
644
|
+
**v1 Behavior:**
|
|
645
|
+
|
|
646
|
+
```javascript
|
|
647
|
+
const game = new Game()
|
|
648
|
+
game.moves('E2') // Returns array: ["E3", "E4"]
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
**v2 Behavior:**
|
|
652
|
+
|
|
653
|
+
```typescript
|
|
654
|
+
const game = new Game()
|
|
655
|
+
game.moves('E2') // Returns object: {"E2": ["E3", "E4"]}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
### 2. `move()` Return Type Changed
|
|
659
|
+
|
|
660
|
+
**v1 Behavior:**
|
|
661
|
+
|
|
662
|
+
```javascript
|
|
663
|
+
game.move('E2', 'E4') // Returns move object: {"E2": "E4"}
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
**v2 Behavior:**
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
game.move('E2', 'E4') // Returns full BoardConfig object
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
### 3. `aiMove()` API - Now v1 Compatible ✅
|
|
673
|
+
|
|
674
|
+
The `aiMove()` function has been **restored to v1 API compatibility**.
|
|
675
|
+
|
|
676
|
+
**v1 Behavior:**
|
|
677
|
+
|
|
678
|
+
```javascript
|
|
679
|
+
aiMove(config, 2) // Returns move object: {"E2": "E4"}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
**v2 Behavior (Current):**
|
|
683
|
+
|
|
684
|
+
```typescript
|
|
685
|
+
aiMove(config, 3) // Returns move object: {"E2": "E4"} ✅ v1 compatible
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
**New `ai()` function** - For users who need both move and board state:
|
|
689
|
+
|
|
690
|
+
```typescript
|
|
691
|
+
ai(config, 3) // Returns: { move: {"E2": "E4"}, board: {...} }
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### 4. AI Difficulty Levels Changed
|
|
695
|
+
|
|
696
|
+
- **v1:** Levels 0-4 (0=easiest, 4=hardest)
|
|
697
|
+
- **v2:** Levels 1-5 (1=easiest, 5=hardest)
|
|
698
|
+
|
|
699
|
+
**Migration:**
|
|
700
|
+
- Level 0 → Level 1 (Beginner)
|
|
701
|
+
- Level 1 → Level 2 (Easy)
|
|
702
|
+
- Level 2 → Level 3 (Intermediate, default)
|
|
703
|
+
- Level 3 → Level 4 (Advanced)
|
|
704
|
+
- Level 4 → Level 5 (Expert)
|
|
705
|
+
|
|
706
|
+
The default level has changed from `2` to `3` to maintain similar difficulty in the middle range.
|
|
707
|
+
|
|
708
|
+
### 5. Node.js Version Requirement
|
|
709
|
+
|
|
710
|
+
- **v1:** Node.js >=20 <21
|
|
711
|
+
- **v2:** Node.js >=24
|
|
712
|
+
|
|
713
|
+
### What Stayed the Same
|
|
714
|
+
|
|
715
|
+
- ✅ Game class constructor signature
|
|
716
|
+
- ✅ Method names (move, moves, aiMove, etc.)
|
|
717
|
+
- ✅ Board formats (JSON and FEN)
|
|
718
|
+
- ✅ Chess rules (castling, en passant, promotions)
|
|
719
|
+
- ✅ Square notation (case-insensitive: 'E2' or 'e2')
|