cm-chess 2.1.8 → 2.2.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 +5 -5
- package/src/cm-chess/Chess.js +17 -6
- package/test/TestChess.js +55 -44
- package/test/TestFen.js +7 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cm-chess",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.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.
|
|
28
|
-
"cm-pgn": "^2.1.
|
|
29
|
-
"modrator": "^1.1
|
|
27
|
+
"chess.mjs": "^1.2.0",
|
|
28
|
+
"cm-pgn": "^2.1.9",
|
|
29
|
+
"modrator": "^1.2.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"teevi": "^2.1.
|
|
32
|
+
"teevi": "^2.1.11"
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/cm-chess/Chess.js
CHANGED
|
@@ -143,13 +143,13 @@ export class Chess {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
/**
|
|
146
|
-
* @returns {
|
|
146
|
+
* @returns {null|move} the last move of the main variation or `null`, if no move was made
|
|
147
147
|
*/
|
|
148
148
|
lastMove() {
|
|
149
149
|
if (this.pgn.history.moves.length > 0) {
|
|
150
150
|
return this.pgn.history.moves[this.pgn.history.moves.length - 1]
|
|
151
151
|
} else {
|
|
152
|
-
return
|
|
152
|
+
return null
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -185,22 +185,33 @@ export class Chess {
|
|
|
185
185
|
* @param move
|
|
186
186
|
* @param previousMove optional, the previous move (for variations)
|
|
187
187
|
* @param sloppy to allow sloppy SAN
|
|
188
|
-
* @returns {{}|
|
|
188
|
+
* @returns {{}|null}
|
|
189
189
|
*/
|
|
190
190
|
move(move, previousMove = undefined, sloppy = true) {
|
|
191
191
|
try {
|
|
192
192
|
return this.pgn.history.addMove(move, previousMove, sloppy)
|
|
193
193
|
} catch (e) {
|
|
194
|
-
return
|
|
194
|
+
return null
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Don't make a move, just validate, if it would be a correct move
|
|
200
|
+
* @param move
|
|
201
|
+
* @param previousMove optional, the previous move (for variations)
|
|
202
|
+
* @param sloppy to allow sloppy SAN
|
|
203
|
+
* @returns the move object or null if not valid
|
|
204
|
+
*/
|
|
205
|
+
validateMove(move, previousMove = undefined, sloppy = true) {
|
|
206
|
+
return this.pgn.history.validateMove(move, previousMove, sloppy)
|
|
207
|
+
}
|
|
208
|
+
|
|
198
209
|
/**
|
|
199
210
|
* This one is not fully implemented in cm-pgn. For now, it just uses pgn() of chess.js.
|
|
200
211
|
* @returns {string} the PGN of the game.
|
|
201
212
|
*/
|
|
202
213
|
renderPgn() {
|
|
203
|
-
// TODO create pgn with variations, annotations, nags (for now just render main
|
|
214
|
+
// TODO create pgn with variations, annotations, nags (for now just render main variation)
|
|
204
215
|
const chess = new ChessJs(this.setUpFen())
|
|
205
216
|
const moves = this.pgn.history.moves
|
|
206
217
|
for (const move of moves) {
|
|
@@ -239,7 +250,7 @@ export class Chess {
|
|
|
239
250
|
}
|
|
240
251
|
|
|
241
252
|
/**
|
|
242
|
-
* @returns {string} "b" or "w" the color to move in the main
|
|
253
|
+
* @returns {string} "b" or "w" the color to move in the main variation
|
|
243
254
|
*/
|
|
244
255
|
turn() {
|
|
245
256
|
let factor = 0
|
package/test/TestChess.js
CHANGED
|
@@ -8,16 +8,16 @@ describe("Chess", function () {
|
|
|
8
8
|
|
|
9
9
|
it("should create empty Chess", () => {
|
|
10
10
|
const chess = new Chess()
|
|
11
|
-
assert.
|
|
12
|
-
assert.
|
|
13
|
-
assert.
|
|
11
|
+
assert.equal(chess.history().length, 0)
|
|
12
|
+
assert.equal(Object.keys(chess.header()).length, 0)
|
|
13
|
+
assert.equal(chess.fen(), FEN.start)
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
it("should load a game from FEN", function () {
|
|
17
17
|
const fen = "4k3/pppppppp/8/8/8/8/PPPPPPPP/4K3 w - - 0 1"
|
|
18
18
|
const chess = new Chess(fen)
|
|
19
|
-
assert.
|
|
20
|
-
assert.
|
|
19
|
+
assert.equal(chess.pgn.header.tags[TAGS.FEN], fen)
|
|
20
|
+
assert.equal(chess.fen(), fen)
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
it("should load a pgn with SetUp and FEN", function () {
|
|
@@ -26,9 +26,9 @@ describe("Chess", function () {
|
|
|
26
26
|
|
|
27
27
|
1. e4 (1. d4 {Die Variante} d5) e5 {Ein Kommentar} 2. a3`
|
|
28
28
|
const chess = new Chess({pgn: pgn})
|
|
29
|
-
assert.
|
|
29
|
+
assert.equal(chess.move("Nc6"), null)
|
|
30
30
|
const result = chess.move("h6")
|
|
31
|
-
assert.
|
|
31
|
+
assert.equal(result.fen, "4k3/pppp1pp1/7p/4p3/4P3/P7/1PPP1PPP/4K3 w - - 0 3")
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
it("should load a pgn", function () {
|
|
@@ -48,13 +48,13 @@ describe("Chess", function () {
|
|
|
48
48
|
11.Bf4 b5 12.a4 Bb7 13.Re1 Nd5 14.Bg3 Kc8 15.axb5 cxb5 16.Qd3 Bc6
|
|
49
49
|
17.Bf5 exf5 18.Rxe7 Bxe7 19.c4 1-0`
|
|
50
50
|
chess.loadPgn(pgn)
|
|
51
|
-
assert.
|
|
52
|
-
assert.
|
|
51
|
+
assert.equal(chess.history().length, 37)
|
|
52
|
+
assert.equal(chess.header()[TAGS.White], "Deep Blue")
|
|
53
53
|
const firstMove = chess.history()[0]
|
|
54
|
-
assert.
|
|
55
|
-
assert.
|
|
56
|
-
assert.
|
|
57
|
-
assert.
|
|
54
|
+
assert.equal(firstMove.color, "w")
|
|
55
|
+
assert.equal(firstMove.san, "e4")
|
|
56
|
+
assert.equal(firstMove.fen, "rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1")
|
|
57
|
+
assert.equal(chess.history()[19].commentAfter, "Kasparov schüttelt kurz den Kopf")
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
it("should load a pgn with SetUp", () => {
|
|
@@ -68,7 +68,7 @@ describe("Chess", function () {
|
|
|
68
68
|
1. Qc1 Qe6 2. Qxc7
|
|
69
69
|
0-1`
|
|
70
70
|
const chess = new Chess({pgn: pgn})
|
|
71
|
-
assert.
|
|
71
|
+
assert.equal(chess.history()[2].san, "Qxc7")
|
|
72
72
|
})
|
|
73
73
|
|
|
74
74
|
it('should parse stappenmethode weekly.pgn', () => {
|
|
@@ -88,9 +88,9 @@ describe("Chess", function () {
|
|
|
88
88
|
1... Bf8 (1... Qf8? 2. Qxf8+ Bxf8 3. exd4) 2. exd4 Qxd4+ {%Q} 3. Kh1 Bh3
|
|
89
89
|
0-1`
|
|
90
90
|
chess.loadPgn(pgn)
|
|
91
|
-
assert.
|
|
92
|
-
assert.
|
|
93
|
-
assert.
|
|
91
|
+
assert.equal(5, chess.pgn.history.moves.length)
|
|
92
|
+
assert.equal("Schaak opheffen", chess.pgn.header.tags[TAGS.White])
|
|
93
|
+
assert.equal("app 037-1", chess.pgn.header.tags[TAGS.Annotator])
|
|
94
94
|
})
|
|
95
95
|
|
|
96
96
|
it('should allow traverse through moves', () => {
|
|
@@ -101,18 +101,18 @@ describe("Chess", function () {
|
|
|
101
101
|
1. Qc5+ Kd3 2. Qc2+ Kd4 3. Qd2+ Bd3 4. Qe3+ Kxe3 (4... Kc3 5. Qc1+ Kb3 6. Qa3+ Kc4 7. Qb4+ Kd5 8. Qc5#) 5. Bc5#
|
|
102
102
|
1-0`
|
|
103
103
|
chess.loadPgn(pgn)
|
|
104
|
-
assert.
|
|
104
|
+
assert.equal(chess.turn(), COLOR.black)
|
|
105
105
|
const firstMove = chess.history()[0]
|
|
106
|
-
assert.
|
|
106
|
+
assert.equal(firstMove.san, "Qc5+")
|
|
107
107
|
const secondMove = firstMove.next
|
|
108
|
-
assert.
|
|
109
|
-
assert.
|
|
110
|
-
assert.
|
|
111
|
-
assert.
|
|
112
|
-
assert.
|
|
113
|
-
assert.
|
|
108
|
+
assert.equal(secondMove.san, "Kd3")
|
|
109
|
+
assert.equal(chess.lastMove().san, "Bc5#")
|
|
110
|
+
assert.equal(chess.gameOver(), true)
|
|
111
|
+
assert.equal(chess.lastMove().inCheckmate, true)
|
|
112
|
+
assert.equal(chess.inCheckmate(), true)
|
|
113
|
+
assert.equal(chess.inDraw(), false)
|
|
114
114
|
// TODO result, 1-0 is missing
|
|
115
|
-
assert.
|
|
115
|
+
assert.equal(chess.renderPgn(), `[SetUp "1"]
|
|
116
116
|
[FEN "8/8/b2Bq3/7Q/3kp3/5pP1/8/3K4 w - - 0 1"]
|
|
117
117
|
|
|
118
118
|
1. Qc5+ Kd3 2. Qc2+ Kd4 3. Qd2+ Bd3 4. Qe3+ Kxe3 5. Bc5#`)
|
|
@@ -120,38 +120,39 @@ describe("Chess", function () {
|
|
|
120
120
|
|
|
121
121
|
it('should add move at the end of the history', () => {
|
|
122
122
|
const chess = new Chess()
|
|
123
|
-
assert.
|
|
123
|
+
assert.equal(chess.turn(), COLOR.white)
|
|
124
124
|
chess.move("e4")
|
|
125
|
-
assert.
|
|
126
|
-
assert.
|
|
125
|
+
assert.equal(chess.turn(), COLOR.black)
|
|
126
|
+
assert.equal(chess.history()[0].san, "e4")
|
|
127
127
|
chess.move("e5")
|
|
128
|
-
assert.
|
|
128
|
+
assert.equal(chess.turn(), COLOR.white)
|
|
129
129
|
})
|
|
130
130
|
|
|
131
131
|
it('should provide correct turn after loading a FEN', () => {
|
|
132
132
|
const chess = new Chess()
|
|
133
133
|
chess.load('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1')
|
|
134
|
-
assert.
|
|
134
|
+
assert.equal(chess.turn(), COLOR.black)
|
|
135
135
|
})
|
|
136
136
|
|
|
137
|
-
it('invalid move should return `
|
|
137
|
+
it('invalid move should return `null`', () => {
|
|
138
138
|
const chess = new Chess()
|
|
139
139
|
chess.load('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1')
|
|
140
|
-
assert.
|
|
140
|
+
assert.equal(chess.turn(), COLOR.black)
|
|
141
|
+
// assert.notEqual(chess.validateMove("a1"), null)
|
|
141
142
|
const move = chess.move("a1")
|
|
142
|
-
assert.
|
|
143
|
+
assert.equal(move, null)
|
|
143
144
|
})
|
|
144
145
|
|
|
145
146
|
it('should return pieces', () => {
|
|
146
147
|
const chess = new Chess()
|
|
147
|
-
assert.
|
|
148
|
+
assert.equal(chess.pieces().length, 32)
|
|
148
149
|
const pgn = `[SetUp "1"]
|
|
149
150
|
[FEN "8/8/b2Bq3/7Q/3kp3/5pP1/8/3K4 w - - 0 1"]
|
|
150
151
|
|
|
151
152
|
1. Qc5+ Kd3 2. Qc2+ Kd4 3. Qd2+ Bd3 4. Qe3+ Kxe3 (4... Kc3 5. Qc1+ Kb3 6. Qa3+ Kc4 7. Qb4+ Kd5 8. Qc5#) 5. Bc5#
|
|
152
153
|
1-0`
|
|
153
154
|
chess.loadPgn(pgn)
|
|
154
|
-
assert.
|
|
155
|
+
assert.equal(chess.pieces("k").length, 2)
|
|
155
156
|
})
|
|
156
157
|
|
|
157
158
|
it('should undo lastMove', () => {
|
|
@@ -162,9 +163,9 @@ describe("Chess", function () {
|
|
|
162
163
|
1. Qc5+ Kd3 2. Qc2+ Kd4 3. Qd2+ Bd3 4. Qe3+ Kxe3 (4... Kc3 5. Qc1+ Kb3 6. Qa3+ Kc4 7. Qb4+ Kd5 8. Qc5#) 5. Bc5#
|
|
163
164
|
1-0`
|
|
164
165
|
chess.loadPgn(pgn)
|
|
165
|
-
assert.
|
|
166
|
+
assert.equal(chess.history().length, 9)
|
|
166
167
|
chess.undo()
|
|
167
|
-
assert.
|
|
168
|
+
assert.equal(chess.history().length, 8)
|
|
168
169
|
})
|
|
169
170
|
|
|
170
171
|
it('should undo more moves', () => {
|
|
@@ -177,10 +178,10 @@ describe("Chess", function () {
|
|
|
177
178
|
chess.loadPgn(pgn)
|
|
178
179
|
chess.undo(chess.history()[5])
|
|
179
180
|
// console.log(chess.history());
|
|
180
|
-
assert.
|
|
181
|
-
assert.
|
|
182
|
-
assert.
|
|
183
|
-
assert.
|
|
181
|
+
assert.equal(chess.history().length, 5)
|
|
182
|
+
assert.equal(chess.plyCount(), 5)
|
|
183
|
+
assert.equal(chess.fenOfPly(0), "8/8/b2Bq3/7Q/3kp3/5pP1/8/3K4 w - - 0 1")
|
|
184
|
+
assert.equal(chess.fenOfPly(3), "8/8/b2Bq3/8/4p3/3k1pP1/2Q5/3K4 b - - 3 2")
|
|
184
185
|
})
|
|
185
186
|
|
|
186
187
|
it("should not load incorrect FEN", function () {
|
|
@@ -203,10 +204,20 @@ describe("Chess", function () {
|
|
|
203
204
|
it("should load different PGNs and then work correctly", function () {
|
|
204
205
|
const fen = "ppppkppp/pppppppp/pppppppp/pppppppp/8/8/8/RNBQKBNR w KQ - 0 1"
|
|
205
206
|
const chess = new Chess({fen: fen})
|
|
206
|
-
assert.true(chess.move("e4") ===
|
|
207
|
-
assert.true(chess.move("Ke2") !==
|
|
207
|
+
assert.true(chess.move("e4") === null)
|
|
208
|
+
assert.true(chess.move("Ke2") !== null)
|
|
208
209
|
chess.load(FEN.start)
|
|
209
210
|
assert.true(chess.move("e4"))
|
|
210
211
|
})
|
|
211
212
|
|
|
213
|
+
it("should validate Moves", function() {
|
|
214
|
+
const chess = new Chess()
|
|
215
|
+
assert.notEqual(chess.validateMove("e4"), null)
|
|
216
|
+
assert.notEqual(chess.validateMove("e3"), null)
|
|
217
|
+
assert.notEqual(chess.validateMove("Nf3"), null)
|
|
218
|
+
assert.equal(chess.validateMove("xyz"), null)
|
|
219
|
+
assert.equal(chess.validateMove("e6"), null)
|
|
220
|
+
|
|
221
|
+
})
|
|
222
|
+
|
|
212
223
|
})
|
package/test/TestFen.js
CHANGED
|
@@ -5,11 +5,11 @@ describe("Fen", function () {
|
|
|
5
5
|
|
|
6
6
|
it("should parse a fen", () => {
|
|
7
7
|
const fen = new Fen("rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2")
|
|
8
|
-
assert.
|
|
9
|
-
assert.
|
|
10
|
-
assert.
|
|
11
|
-
assert.
|
|
12
|
-
assert.
|
|
13
|
-
assert.
|
|
8
|
+
assert.equal(fen.position, "rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R")
|
|
9
|
+
assert.equal(fen.colorToPlay, "b")
|
|
10
|
+
assert.equal(fen.castlings.length, 4)
|
|
11
|
+
assert.equal(fen.enPassantTargetSquare, undefined)
|
|
12
|
+
assert.equal(fen.plyClock, 1)
|
|
13
|
+
assert.equal(fen.moveNumber, 2)
|
|
14
14
|
})
|
|
15
|
-
})
|
|
15
|
+
})
|