cm-chess 2.3.4 → 2.4.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/package.json +3 -3
- package/src/cm-chess/Chess.js +61 -15
- package/test/TestChess.js +24 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cm-chess",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Like chess.js, but in ES6 and can handle variations (tree-structured move history)",
|
|
5
5
|
"main": "./src/cm-chess/Chess.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://github.com/shaack/cm-chess#readme",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"chess.mjs": "^1.
|
|
27
|
+
"chess.mjs": "^1.3.1",
|
|
28
28
|
"cm-pgn": "^2.1.9",
|
|
29
29
|
"modrator": "^1.2.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"teevi": "^2.
|
|
32
|
+
"teevi": "^2.2.2"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/cm-chess/Chess.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import {Pgn} from "../../lib/cm-pgn/Pgn.js"
|
|
7
7
|
import {TAGS} from "../../lib/cm-pgn/Header.js"
|
|
8
|
-
import {Chess as ChessJs} from "../../lib/chess.mjs/Chess.js"
|
|
8
|
+
import {Chess as ChessJs, SQUARES} from "../../lib/chess.mjs/Chess.js"
|
|
9
9
|
|
|
10
10
|
export const PIECES = {
|
|
11
11
|
p: {name: "pawn", value: 1},
|
|
@@ -26,6 +26,21 @@ export const FEN = {
|
|
|
26
26
|
start: "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export const EVENT_TYPE = {
|
|
30
|
+
illegalMove: "illegalMove",
|
|
31
|
+
legalMove: "legalMove",
|
|
32
|
+
undoMove: "undoMove",
|
|
33
|
+
initialized: "initialized"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function publishEvent(observers, eventType, data = {}) {
|
|
37
|
+
for (const observer of observers) {
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
observer(eventType, data)
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
29
44
|
/**
|
|
30
45
|
* Like chess.js, but handles variations and is written in ES5
|
|
31
46
|
* Uses chess.js for validation and cm-pgn for the history and PGN header
|
|
@@ -33,12 +48,13 @@ export const FEN = {
|
|
|
33
48
|
export class Chess {
|
|
34
49
|
|
|
35
50
|
constructor(fenOrProps = FEN.start) {
|
|
36
|
-
|
|
51
|
+
this.observers = []
|
|
52
|
+
if (typeof fenOrProps === "string") {
|
|
37
53
|
this.load(fenOrProps)
|
|
38
54
|
} else {
|
|
39
|
-
if(fenOrProps.fen) {
|
|
55
|
+
if (fenOrProps.fen) {
|
|
40
56
|
this.load(fenOrProps.fen)
|
|
41
|
-
} else if(fenOrProps.pgn) {
|
|
57
|
+
} else if (fenOrProps.pgn) {
|
|
42
58
|
this.loadPgn(fenOrProps.pgn)
|
|
43
59
|
} else {
|
|
44
60
|
this.load(FEN.start)
|
|
@@ -49,14 +65,11 @@ export class Chess {
|
|
|
49
65
|
/**
|
|
50
66
|
* @returns {string} the FEN of the last move, or the setUpFen(), if no move was made.
|
|
51
67
|
*/
|
|
52
|
-
fen() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return lastMove.fen
|
|
56
|
-
} else if (this.setUpFen()) {
|
|
57
|
-
return this.setUpFen()
|
|
68
|
+
fen(move = this.lastMove()) {
|
|
69
|
+
if (move) {
|
|
70
|
+
return move.fen
|
|
58
71
|
} else {
|
|
59
|
-
return
|
|
72
|
+
return this.setUpFen()
|
|
60
73
|
}
|
|
61
74
|
}
|
|
62
75
|
|
|
@@ -169,6 +182,7 @@ export class Chess {
|
|
|
169
182
|
} else {
|
|
170
183
|
throw Error("Invalid fen " + fen)
|
|
171
184
|
}
|
|
185
|
+
publishEvent(this.observers, EVENT_TYPE.initialized, {fen: fen})
|
|
172
186
|
}
|
|
173
187
|
|
|
174
188
|
/**
|
|
@@ -178,6 +192,7 @@ export class Chess {
|
|
|
178
192
|
*/
|
|
179
193
|
loadPgn(pgn) {
|
|
180
194
|
this.pgn = new Pgn(pgn)
|
|
195
|
+
publishEvent(this.observers, EVENT_TYPE.initialized, {pgn: pgn})
|
|
181
196
|
}
|
|
182
197
|
|
|
183
198
|
/**
|
|
@@ -189,12 +204,40 @@ export class Chess {
|
|
|
189
204
|
*/
|
|
190
205
|
move(move, previousMove = undefined, sloppy = true) {
|
|
191
206
|
try {
|
|
192
|
-
|
|
207
|
+
const moveResult = this.pgn.history.addMove(move, previousMove, sloppy)
|
|
208
|
+
publishEvent(this.observers, EVENT_TYPE.legalMove, {move: move, previousMove: previousMove})
|
|
209
|
+
return moveResult
|
|
193
210
|
} catch (e) {
|
|
211
|
+
publishEvent(this.observers, EVENT_TYPE.illegalMove, {move: move, previousMove: previousMove})
|
|
194
212
|
return null
|
|
195
213
|
}
|
|
196
214
|
}
|
|
197
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Return all valid moves
|
|
218
|
+
* @param options {{ square: "e2", piece: "n", verbose: true }}
|
|
219
|
+
* Fields with { verbose: true }
|
|
220
|
+
* - `color` indicates the color of the moving piece (w or b).
|
|
221
|
+
* - `from` and `to` fields are from and to squares in algebraic notation.
|
|
222
|
+
* - `piece`, `captured`, and `promotion` fields contain the lowercase representation of the applicable piece (pnbrqk). The captured and promotion fields are only present when the move is a valid capture or promotion.
|
|
223
|
+
* - `san` is the move in Standard Algebraic Notation (SAN).
|
|
224
|
+
* - `flags` field contains one or more of the string values:
|
|
225
|
+
* n - a non-capture
|
|
226
|
+
* b - a pawn push of two squares
|
|
227
|
+
* e - an en passant capture
|
|
228
|
+
* c - a standard capture
|
|
229
|
+
* p - a promotion
|
|
230
|
+
* k - kingside castling
|
|
231
|
+
* q - queenside castling
|
|
232
|
+
* A flags value of pc would mean that a pawn captured a piece on the 8th rank and promoted.
|
|
233
|
+
* @param previousMove
|
|
234
|
+
* @returns {{}}
|
|
235
|
+
*/
|
|
236
|
+
moves(options = undefined, previousMove = this.lastMove()) {
|
|
237
|
+
const chessJs = new ChessJs(this.fen(previousMove))
|
|
238
|
+
return chessJs.moves(options)
|
|
239
|
+
}
|
|
240
|
+
|
|
198
241
|
/**
|
|
199
242
|
* Don't make a move, just validate, if it would be a correct move
|
|
200
243
|
* @param move
|
|
@@ -231,7 +274,7 @@ export class Chess {
|
|
|
231
274
|
const chessJs = move ? new ChessJs(move.fen) : new ChessJs()
|
|
232
275
|
let result = []
|
|
233
276
|
for (let i = 0; i < 64; i++) {
|
|
234
|
-
const square =
|
|
277
|
+
const square = SQUARES[i]
|
|
235
278
|
const piece = chessJs.get(square)
|
|
236
279
|
if (piece) {
|
|
237
280
|
piece.square = square
|
|
@@ -277,6 +320,7 @@ export class Chess {
|
|
|
277
320
|
return element.ply === move.ply
|
|
278
321
|
})
|
|
279
322
|
move.variation = move.variation.splice(index)
|
|
323
|
+
publishEvent(this.observers, EVENT_TYPE.undoMove, {move: move})
|
|
280
324
|
}
|
|
281
325
|
|
|
282
326
|
plyCount() {
|
|
@@ -284,12 +328,14 @@ export class Chess {
|
|
|
284
328
|
}
|
|
285
329
|
|
|
286
330
|
fenOfPly(plyNumber) {
|
|
287
|
-
if(plyNumber > 0) {
|
|
331
|
+
if (plyNumber > 0) {
|
|
288
332
|
return this.history()[plyNumber - 1].fen
|
|
289
333
|
} else {
|
|
290
334
|
return this.setUpFen()
|
|
291
335
|
}
|
|
292
336
|
}
|
|
293
337
|
|
|
294
|
-
|
|
338
|
+
addObserver(callback) {
|
|
339
|
+
this.observers.push(callback)
|
|
340
|
+
}
|
|
295
341
|
}
|
package/test/TestChess.js
CHANGED
|
@@ -217,7 +217,31 @@ describe("Chess", function () {
|
|
|
217
217
|
assert.notEqual(chess.validateMove("Nf3"), null)
|
|
218
218
|
assert.equal(chess.validateMove("xyz"), null)
|
|
219
219
|
assert.equal(chess.validateMove("e6"), null)
|
|
220
|
+
})
|
|
220
221
|
|
|
222
|
+
it("should publish events", function() {
|
|
223
|
+
return new Promise((resolve, reject) => {
|
|
224
|
+
const chess = new Chess()
|
|
225
|
+
chess.addObserver((event, data) => {
|
|
226
|
+
if(event === "legalMove" && data.move === "e4") {
|
|
227
|
+
resolve()
|
|
228
|
+
} else {
|
|
229
|
+
reject("error event")
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
chess.move("e4")
|
|
233
|
+
})
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
it("should provide valid moves", function() {
|
|
237
|
+
const chess = new Chess()
|
|
238
|
+
assert.equal(chess.moves().length, 20)
|
|
239
|
+
chess.move("Nc3")
|
|
240
|
+
assert.equal(chess.moves().length, 20)
|
|
241
|
+
chess.move("e5")
|
|
242
|
+
assert.equal(chess.moves().length, 22)
|
|
243
|
+
assert.equal(JSON.stringify(chess.moves({ square: "e2"})), '["e3","e4"]')
|
|
244
|
+
assert.equal(JSON.stringify(chess.moves({ piece: "n" })), '["Na4","Nb5","Nd5","Ne4","Nb1","Nf3","Nh3"]')
|
|
221
245
|
})
|
|
222
246
|
|
|
223
247
|
})
|