cm-chess 3.5.3 → 3.6.1
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 +1 -1
- package/src/Chess.js +34 -13
- package/test/TestChess.js +15 -15
- package/test/TestChess960.js +3 -2
package/package.json
CHANGED
package/src/Chess.js
CHANGED
|
@@ -33,6 +33,18 @@ export const EVENT_TYPE = {
|
|
|
33
33
|
initialized: "initialized"
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export const GAME_VARIANT = {
|
|
37
|
+
standard: "standard",
|
|
38
|
+
chess960: "chess960"
|
|
39
|
+
// kingOfTheHill: "kingOfTheHill",
|
|
40
|
+
// threeCheck: "threeCheck",
|
|
41
|
+
// antichess: "antichess",
|
|
42
|
+
// atomic: "atomic",
|
|
43
|
+
// horde: "horde",
|
|
44
|
+
// racingKings: "racingKings",
|
|
45
|
+
// crazyhouse: "crazyhouse"
|
|
46
|
+
}
|
|
47
|
+
|
|
36
48
|
function publishEvent(observers, event) {
|
|
37
49
|
for (const observer of observers) {
|
|
38
50
|
setTimeout(() => {
|
|
@@ -52,6 +64,7 @@ export class Chess {
|
|
|
52
64
|
* - an object with these properties:
|
|
53
65
|
* fen: a FEN string
|
|
54
66
|
* pgn: a PGN
|
|
67
|
+
* gameVariant:
|
|
55
68
|
* chess960: true, if chess960 are used
|
|
56
69
|
* sloppy: true, if sloppy parsing is allowed
|
|
57
70
|
*/
|
|
@@ -60,10 +73,15 @@ export class Chess {
|
|
|
60
73
|
this.props = {
|
|
61
74
|
fen: undefined, // use a fen or a pgn with setUpFen
|
|
62
75
|
pgn: undefined,
|
|
63
|
-
|
|
76
|
+
gameVariant: GAME_VARIANT.standard,
|
|
77
|
+
chess960: undefined,
|
|
64
78
|
sloppy: true, // sloppy parsing allows small mistakes in SAN
|
|
65
79
|
...props
|
|
66
80
|
}
|
|
81
|
+
if(this.props.chess960 !== undefined) {
|
|
82
|
+
console.warn("props.chess960 is deprecated, use GAME_VARIANT")
|
|
83
|
+
this.props.gameVariant = GAME_VARIANT.chess960
|
|
84
|
+
}
|
|
67
85
|
if (typeof props === "string") {
|
|
68
86
|
console.warn("directly passing a FEN is deprecated, use `{fen: \"" + props + "\"}`")
|
|
69
87
|
this.props.fen = props
|
|
@@ -117,7 +135,7 @@ export class Chess {
|
|
|
117
135
|
if (move) {
|
|
118
136
|
return move.gameOver
|
|
119
137
|
} else {
|
|
120
|
-
return new ChessJs(this.fen(), {chess960: this.props.chess960}).game_over()
|
|
138
|
+
return new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960}).game_over()
|
|
121
139
|
}
|
|
122
140
|
}
|
|
123
141
|
|
|
@@ -129,7 +147,7 @@ export class Chess {
|
|
|
129
147
|
if (move) {
|
|
130
148
|
return move.inDraw === true
|
|
131
149
|
} else {
|
|
132
|
-
return new ChessJs(this.fen(), {chess960: this.props.chess960}).in_draw()
|
|
150
|
+
return new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960}).in_draw()
|
|
133
151
|
}
|
|
134
152
|
}
|
|
135
153
|
|
|
@@ -141,7 +159,7 @@ export class Chess {
|
|
|
141
159
|
if (move) {
|
|
142
160
|
return move.inStalemate === true
|
|
143
161
|
} else {
|
|
144
|
-
return new ChessJs(this.fen(), {chess960: this.props.chess960}).in_stalemate()
|
|
162
|
+
return new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960}).in_stalemate()
|
|
145
163
|
}
|
|
146
164
|
}
|
|
147
165
|
|
|
@@ -153,7 +171,7 @@ export class Chess {
|
|
|
153
171
|
if (move) {
|
|
154
172
|
return move.insufficientMaterial === true
|
|
155
173
|
} else {
|
|
156
|
-
return new ChessJs(this.fen(), {chess960: this.props.chess960}).insufficient_material()
|
|
174
|
+
return new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960}).insufficient_material()
|
|
157
175
|
}
|
|
158
176
|
}
|
|
159
177
|
|
|
@@ -173,7 +191,7 @@ export class Chess {
|
|
|
173
191
|
if (move) {
|
|
174
192
|
return move.inCheckmate === true
|
|
175
193
|
} else {
|
|
176
|
-
return new ChessJs(this.fen(), {chess960: this.props.chess960}).in_checkmate()
|
|
194
|
+
return new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960}).in_checkmate()
|
|
177
195
|
}
|
|
178
196
|
}
|
|
179
197
|
|
|
@@ -185,7 +203,7 @@ export class Chess {
|
|
|
185
203
|
if (move) {
|
|
186
204
|
return move.inCheck === true
|
|
187
205
|
} else {
|
|
188
|
-
return new ChessJs(this.fen(), {chess960: this.props.chess960}).in_check()
|
|
206
|
+
return new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960}).in_check()
|
|
189
207
|
}
|
|
190
208
|
}
|
|
191
209
|
|
|
@@ -213,9 +231,9 @@ export class Chess {
|
|
|
213
231
|
* @param fen
|
|
214
232
|
*/
|
|
215
233
|
load(fen) {
|
|
216
|
-
const chess = new ChessJs(fen, {chess960: this.props.chess960})
|
|
234
|
+
const chess = new ChessJs(fen, {chess960: this.props.gameVariant === GAME_VARIANT.chess960})
|
|
217
235
|
if (chess && chess.fen() === fen) {
|
|
218
|
-
this.pgn = new Pgn(undefined, {chess960: this.props.chess960})
|
|
236
|
+
this.pgn = new Pgn(undefined, {chess960: this.props.gameVariant === GAME_VARIANT.chess960})
|
|
219
237
|
if (fen !== FEN.start) {
|
|
220
238
|
this.pgn.header.tags[TAGS.SetUp] = "1"
|
|
221
239
|
this.pgn.header.tags[TAGS.FEN] = chess.fen()
|
|
@@ -229,12 +247,15 @@ export class Chess {
|
|
|
229
247
|
|
|
230
248
|
/**
|
|
231
249
|
* Load a PGN with variations, NAGs, header and annotations. cm-chess uses cm-pgn
|
|
232
|
-
*
|
|
250
|
+
* for the header and history. See https://github.com/shaack/cm-pgn
|
|
233
251
|
* @param pgn
|
|
234
252
|
* @param sloppy to allow sloppy SAN
|
|
235
253
|
*/
|
|
236
254
|
loadPgn(pgn, sloppy = this.props.sloppy) {
|
|
237
255
|
this.pgn = new Pgn(pgn, {sloppy: sloppy})
|
|
256
|
+
if(this.pgn.props.chess960) {
|
|
257
|
+
this.props.gameVariant = GAME_VARIANT.chess960
|
|
258
|
+
}
|
|
238
259
|
publishEvent(this.observers, {type: EVENT_TYPE.initialized, pgn: pgn})
|
|
239
260
|
}
|
|
240
261
|
|
|
@@ -279,7 +300,7 @@ export class Chess {
|
|
|
279
300
|
* @returns {{}}
|
|
280
301
|
*/
|
|
281
302
|
moves(options = undefined, move = this.lastMove()) {
|
|
282
|
-
const chessJs = new ChessJs(this.fen(move), {chess960: this.props.chess960})
|
|
303
|
+
const chessJs = new ChessJs(this.fen(move), {chess960: this.props.gameVariant === GAME_VARIANT.chess960})
|
|
283
304
|
return chessJs.moves(options)
|
|
284
305
|
}
|
|
285
306
|
|
|
@@ -313,7 +334,7 @@ export class Chess {
|
|
|
313
334
|
* @returns {[]} the pieces (positions) at a specific move
|
|
314
335
|
*/
|
|
315
336
|
pieces(type = undefined, color = undefined, move = this.lastMove()) {
|
|
316
|
-
const chessJs = move ? new ChessJs(move.fen, {chess960: this.props.chess960}) : new ChessJs(this.fen(), {chess960: this.props.chess960})
|
|
337
|
+
const chessJs = move ? new ChessJs(move.fen, {chess960: this.props.gameVariant === GAME_VARIANT.chess960}) : new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960})
|
|
317
338
|
let result = []
|
|
318
339
|
for (let i = 0; i < 64; i++) {
|
|
319
340
|
const square = SQUARES[i]
|
|
@@ -341,7 +362,7 @@ export class Chess {
|
|
|
341
362
|
* @returns {{color: any, type: any}|null}
|
|
342
363
|
*/
|
|
343
364
|
piece(square, move = this.lastMove()) {
|
|
344
|
-
const chessJs = move ? new ChessJs(move.fen, {chess960: this.props.chess960}) : new ChessJs(this.fen(), {chess960: this.props.chess960})
|
|
365
|
+
const chessJs = move ? new ChessJs(move.fen, {chess960: this.props.gameVariant === GAME_VARIANT.chess960}) : new ChessJs(this.fen(), {chess960: this.props.gameVariant === GAME_VARIANT.chess960})
|
|
345
366
|
return chessJs.get(square)
|
|
346
367
|
}
|
|
347
368
|
|
package/test/TestChess.js
CHANGED
|
@@ -8,7 +8,7 @@ import {Chess, COLOR, FEN} from "../src/Chess.js"
|
|
|
8
8
|
describe("Chess", function () {
|
|
9
9
|
|
|
10
10
|
it("should make a black move from FEN and SAN", function () {
|
|
11
|
-
const chess = new Chess("rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq f3 0 2")
|
|
11
|
+
const chess = new Chess({fen: "rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq f3 0 2"})
|
|
12
12
|
const result = chess.move("d5")
|
|
13
13
|
assert.true(result)
|
|
14
14
|
const chess2 = new Chess({fen: "rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq d6 0 3"})
|
|
@@ -25,7 +25,7 @@ describe("Chess", function () {
|
|
|
25
25
|
|
|
26
26
|
it("should load a game from FEN", function () {
|
|
27
27
|
const fen = "4k3/pppppppp/8/8/8/8/PPPPPPPP/4K3 w - - 0 1"
|
|
28
|
-
const chess = new Chess(fen)
|
|
28
|
+
const chess = new Chess({fen: fen})
|
|
29
29
|
assert.equal(chess.pgn.header.tags[TAGS.FEN], fen)
|
|
30
30
|
assert.equal(chess.fen(), fen)
|
|
31
31
|
assert.equal(chess.piece("e1").type, "k")
|
|
@@ -201,7 +201,7 @@ Kc4 7. Qb4+ Kd5 8. Qc5#) 5. Bc5# 1-0`)
|
|
|
201
201
|
it("should not load incorrect FEN", function () {
|
|
202
202
|
const fen = "4k3/pppppppp/8/8/8/8/PPPPPP/4K3 w - - 0 1"
|
|
203
203
|
try {
|
|
204
|
-
new Chess(fen)
|
|
204
|
+
new Chess({fen: fen})
|
|
205
205
|
assert.true(false)
|
|
206
206
|
} catch (e) {
|
|
207
207
|
// OK
|
|
@@ -221,7 +221,7 @@ Kc4 7. Qb4+ Kd5 8. Qc5#) 5. Bc5# 1-0`)
|
|
|
221
221
|
assert.equal(chess.history().length, 0)
|
|
222
222
|
assert.equal(chess.turn(), COLOR.white)
|
|
223
223
|
assert.equal(chess.fen(), fen)
|
|
224
|
-
const result = chess.move("e4")
|
|
224
|
+
const result = chess.move("e4")
|
|
225
225
|
assert.equal(chess.fen(), fen)
|
|
226
226
|
assert.true(result === null)
|
|
227
227
|
assert.true(chess.move("Ke2") !== null)
|
|
@@ -266,26 +266,26 @@ Kc4 7. Qb4+ Kd5 8. Qc5#) 5. Bc5# 1-0`)
|
|
|
266
266
|
})
|
|
267
267
|
|
|
268
268
|
it("should detect a check in a game without moves", function () {
|
|
269
|
-
const chess = new Chess("4k3/1P6/8/b7/6r1/8/pp2PPPP/2R1KBNR w K - 0 1")
|
|
269
|
+
const chess = new Chess({fen: "4k3/1P6/8/b7/6r1/8/pp2PPPP/2R1KBNR w K - 0 1"})
|
|
270
270
|
assert.true(chess.inCheck())
|
|
271
271
|
})
|
|
272
272
|
|
|
273
273
|
// see https://www.chessmail.de/forum/thread.html?key=GINGFqlNiAjf&sv=6
|
|
274
274
|
it("should make a move with sloppy SAN", function () {
|
|
275
|
-
let chess = new Chess("r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44")
|
|
276
|
-
let result = chess.move("R8c7", undefined,false)
|
|
275
|
+
let chess = new Chess({fen: "r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44"})
|
|
276
|
+
let result = chess.move("R8c7", undefined, false)
|
|
277
277
|
assert.true(result !== null)
|
|
278
|
-
chess = new Chess("r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44")
|
|
279
|
-
result = chess.move("Rc8c7", undefined,false)
|
|
278
|
+
chess = new Chess({fen: "r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44"})
|
|
279
|
+
result = chess.move("Rc8c7", undefined, false)
|
|
280
280
|
assert.true(result == null)
|
|
281
|
-
chess = new Chess("r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44")
|
|
282
|
-
result = chess.move("Rc8-c7", undefined,false)
|
|
281
|
+
chess = new Chess({fen: "r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44"})
|
|
282
|
+
result = chess.move("Rc8-c7", undefined, false)
|
|
283
283
|
assert.true(result == null)
|
|
284
|
-
chess = new Chess("r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44")
|
|
285
|
-
result = chess.move("Rc8-c7", undefined,true)
|
|
284
|
+
chess = new Chess({fen: "r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44"})
|
|
285
|
+
result = chess.move("Rc8-c7", undefined, true)
|
|
286
286
|
assert.true(result != null)
|
|
287
|
-
chess = new Chess("r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44")
|
|
288
|
-
result = chess.move("Rc8c7", undefined,true)
|
|
287
|
+
chess = new Chess({fen: "r1R2r1k/1R6/1P2B2p/4pPp1/4N1P1/7P/5P2/2R3K1 w - - 1 44"})
|
|
288
|
+
result = chess.move("Rc8c7", undefined, true)
|
|
289
289
|
assert.true(result != null)
|
|
290
290
|
})
|
|
291
291
|
|
package/test/TestChess960.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* @author Stefan Haack (https://shaack.com)
|
|
3
3
|
*/
|
|
4
4
|
import {describe, it, assert} from "teevi/src/teevi.js"
|
|
5
|
-
import {Chess} from "../src/Chess.js"
|
|
5
|
+
import {Chess, GAME_VARIANT} from "../src/Chess.js"
|
|
6
6
|
|
|
7
7
|
describe("Testing Chess 960", function () {
|
|
8
8
|
|
|
9
9
|
it("should load a chess960 game from a valid chess960 fen and do castling", function () {
|
|
10
10
|
const fen = "nrkbrnbq/pppppppp/8/8/8/8/PPPPPPPP/NRKBRNBQ w KQkq - 0 1"
|
|
11
|
-
const chess = new Chess({
|
|
11
|
+
const chess = new Chess({gameVariant: GAME_VARIANT.chess960})
|
|
12
12
|
chess.load(fen)
|
|
13
13
|
assert.equal(chess.fen(), fen)
|
|
14
14
|
assert.true(chess.move("f4"))
|
|
@@ -58,6 +58,7 @@ N3xd4 exd4 28. Bxd4 Nac5 29. Bxf6 Nxf6 30. c7 b3 31. axb3 Na6 32. Kb1 Nb4
|
|
|
58
58
|
33. Qc4 Ne8 34. Rd8 Qxf5+ 35. Ka1 Nc2+ 36. Qxc2 1-0`
|
|
59
59
|
const chess = new Chess()
|
|
60
60
|
chess.loadPgn(pgn)
|
|
61
|
+
assert.equal(chess.props.gameVariant, GAME_VARIANT.chess960)
|
|
61
62
|
assert.equal(chess.fen(), "2rRn2k/2P3pp/8/pN3q2/8/1P6/1PQ4P/K5R1 b - - 0 36")
|
|
62
63
|
})
|
|
63
64
|
})
|