js-chess-engine 1.0.2 → 2.0.1-rc.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 +387 -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 +27 -28
- 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/lib/js-chess-engine.mjs
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import Board from './Board.mjs'
|
|
2
|
-
import { printToConsole, getFEN } from './utils.mjs'
|
|
3
|
-
|
|
4
|
-
export class Game {
|
|
5
|
-
constructor (configuration) {
|
|
6
|
-
this.board = new Board(configuration)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
move (from, to) {
|
|
10
|
-
from = from.toUpperCase()
|
|
11
|
-
to = to.toUpperCase()
|
|
12
|
-
const possibleMoves = this.board.getMoves()
|
|
13
|
-
if (!possibleMoves[from] || !possibleMoves[from].includes(to)) {
|
|
14
|
-
throw new Error(`Invalid move from ${from} to ${to} for ${this.board.getPlayingColor()}`)
|
|
15
|
-
}
|
|
16
|
-
this.board.addMoveToHistory(from, to)
|
|
17
|
-
this.board.move(from, to)
|
|
18
|
-
return { [from]: to }
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
moves (from = null) {
|
|
22
|
-
return (from ? this.board.getMoves()[from.toUpperCase()] : this.board.getMoves()) || []
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
setPiece (location, piece) {
|
|
26
|
-
this.board.setPiece(location, piece)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
removePiece (location) {
|
|
30
|
-
this.board.removePiece(location)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
aiMove (level = 2) {
|
|
34
|
-
const move = this.board.calculateAiMove(level)
|
|
35
|
-
return this.move(move.from, move.to)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
getHistory (reversed = false) {
|
|
39
|
-
return reversed ? this.board.history.reverse() : this.board.history
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
printToConsole () {
|
|
43
|
-
printToConsole(this.board.configuration)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
exportJson () {
|
|
47
|
-
return this.board.exportJson()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
exportFEN () {
|
|
51
|
-
return getFEN(this.board.configuration)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function moves (config) {
|
|
56
|
-
if (!config) {
|
|
57
|
-
throw new Error('Configuration param required.')
|
|
58
|
-
}
|
|
59
|
-
const game = new Game(config)
|
|
60
|
-
return game.moves()
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function status (config) {
|
|
64
|
-
if (!config) {
|
|
65
|
-
throw new Error('Configuration param required.')
|
|
66
|
-
}
|
|
67
|
-
const game = new Game(config)
|
|
68
|
-
return game.exportJson()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export function getFen (config) {
|
|
72
|
-
if (!config) {
|
|
73
|
-
throw new Error('Configuration param required.')
|
|
74
|
-
}
|
|
75
|
-
const game = new Game(config)
|
|
76
|
-
return game.exportFEN()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function move (config, from, to) {
|
|
80
|
-
if (!config) {
|
|
81
|
-
throw new Error('Configuration param required.')
|
|
82
|
-
}
|
|
83
|
-
const game = new Game(config)
|
|
84
|
-
game.move(from, to)
|
|
85
|
-
if (typeof config === 'object') {
|
|
86
|
-
return game.exportJson()
|
|
87
|
-
} else {
|
|
88
|
-
return game.exportFEN()
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function aiMove (config, level = 2) {
|
|
93
|
-
if (!config) {
|
|
94
|
-
throw new Error('Configuration param required.')
|
|
95
|
-
}
|
|
96
|
-
const game = new Game(config)
|
|
97
|
-
const move = game.board.calculateAiMove(level)
|
|
98
|
-
return { [move.from]: move.to }
|
|
99
|
-
}
|
package/lib/utils.mjs
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { COLUMNS, ROWS, COLORS, PIECES } from './const/board.mjs'
|
|
2
|
-
|
|
3
|
-
export function printToConsole (configuration) {
|
|
4
|
-
process.stdout.write('\n')
|
|
5
|
-
let fieldColor = COLORS.WHITE
|
|
6
|
-
Object.assign([], ROWS).reverse().map(row => {
|
|
7
|
-
process.stdout.write(`${row}`)
|
|
8
|
-
COLUMNS.map(column => {
|
|
9
|
-
switch (configuration.pieces[`${column}${row}`]) {
|
|
10
|
-
case 'K': process.stdout.write('\u265A'); break
|
|
11
|
-
case 'Q': process.stdout.write('\u265B'); break
|
|
12
|
-
case 'R': process.stdout.write('\u265C'); break
|
|
13
|
-
case 'B': process.stdout.write('\u265D'); break
|
|
14
|
-
case 'N': process.stdout.write('\u265E'); break
|
|
15
|
-
case 'P': process.stdout.write('\u265F'); break
|
|
16
|
-
case 'k': process.stdout.write('\u2654'); break
|
|
17
|
-
case 'q': process.stdout.write('\u2655'); break
|
|
18
|
-
case 'r': process.stdout.write('\u2656'); break
|
|
19
|
-
case 'b': process.stdout.write('\u2657'); break
|
|
20
|
-
case 'n': process.stdout.write('\u2658'); break
|
|
21
|
-
case 'p': process.stdout.write('\u2659'); break
|
|
22
|
-
default: process.stdout.write(fieldColor === COLORS.WHITE ? '\u2588' : '\u2591')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
fieldColor = fieldColor === COLORS.WHITE ? COLORS.BLACK : COLORS.WHITE
|
|
26
|
-
})
|
|
27
|
-
fieldColor = fieldColor === COLORS.WHITE ? COLORS.BLACK : COLORS.WHITE
|
|
28
|
-
process.stdout.write('\n')
|
|
29
|
-
})
|
|
30
|
-
process.stdout.write(' ')
|
|
31
|
-
COLUMNS.map(column => {
|
|
32
|
-
process.stdout.write(`${column}`)
|
|
33
|
-
})
|
|
34
|
-
process.stdout.write('\n')
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function getPieceValue (piece) {
|
|
38
|
-
const values = { k: 10, q: 9, r: 5, b: 3, n: 3, p: 1 }
|
|
39
|
-
return values[piece.toLowerCase()] || 0
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function getFEN (configuration) {
|
|
43
|
-
let fen = ''
|
|
44
|
-
Object.assign([], ROWS).reverse().map(row => {
|
|
45
|
-
let emptyFields = 0
|
|
46
|
-
if (row < 8) {
|
|
47
|
-
fen += '/'
|
|
48
|
-
}
|
|
49
|
-
COLUMNS.map(column => {
|
|
50
|
-
const piece = configuration.pieces[`${column}${row}`]
|
|
51
|
-
if (piece) {
|
|
52
|
-
if (emptyFields) {
|
|
53
|
-
fen += emptyFields.toString()
|
|
54
|
-
emptyFields = 0
|
|
55
|
-
}
|
|
56
|
-
fen += piece
|
|
57
|
-
} else {
|
|
58
|
-
emptyFields++
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
fen += `${emptyFields || ''}`
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
fen += configuration.turn === COLORS.WHITE ? ' w ' : ' b '
|
|
65
|
-
|
|
66
|
-
const { whiteShort, whiteLong, blackLong, blackShort } = configuration.castling
|
|
67
|
-
if (!whiteLong && !whiteShort && !blackLong && !blackShort) {
|
|
68
|
-
fen += '-'
|
|
69
|
-
} else {
|
|
70
|
-
if (whiteShort) fen += 'K'
|
|
71
|
-
if (whiteLong) fen += 'Q'
|
|
72
|
-
if (blackShort) fen += 'k'
|
|
73
|
-
if (blackLong) fen += 'q'
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
fen += ` ${configuration.enPassant ? configuration.enPassant.toLowerCase() : '-'}`
|
|
77
|
-
|
|
78
|
-
fen += ` ${configuration.halfMove}`
|
|
79
|
-
|
|
80
|
-
fen += ` ${configuration.fullMove}`
|
|
81
|
-
|
|
82
|
-
return fen
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function getJSONfromFEN (fen = '') {
|
|
86
|
-
const [board, player, castlings, enPassant, halfmove, fullmove] = fen.split(' ')
|
|
87
|
-
|
|
88
|
-
// pieces
|
|
89
|
-
const configuration = {
|
|
90
|
-
pieces: Object.fromEntries(board.split('/').flatMap((row, rowIdx) => {
|
|
91
|
-
let colIdx = 0
|
|
92
|
-
return row.split('').reduce((acc, sign) => {
|
|
93
|
-
const piece = sign.match(/k|b|q|n|p|r/i)
|
|
94
|
-
if (piece) {
|
|
95
|
-
acc.push([`${COLUMNS[colIdx]}${ROWS[7 - rowIdx]}`, piece[0]])
|
|
96
|
-
colIdx += 1
|
|
97
|
-
}
|
|
98
|
-
const squares = sign.match(/[1-8]/)
|
|
99
|
-
if (squares) {
|
|
100
|
-
colIdx += Number(squares)
|
|
101
|
-
}
|
|
102
|
-
return acc
|
|
103
|
-
}, [])
|
|
104
|
-
})),
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// playing player
|
|
108
|
-
if (player === 'b') {
|
|
109
|
-
configuration.turn = COLORS.BLACK
|
|
110
|
-
} else {
|
|
111
|
-
configuration.turn = COLORS.WHITE
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// castlings
|
|
115
|
-
configuration.castling = {
|
|
116
|
-
whiteLong: false,
|
|
117
|
-
whiteShort: false,
|
|
118
|
-
blackLong: false,
|
|
119
|
-
blackShort: false,
|
|
120
|
-
}
|
|
121
|
-
if (castlings.includes('K')) {
|
|
122
|
-
configuration.castling.whiteShort = true
|
|
123
|
-
}
|
|
124
|
-
if (castlings.includes('k')) {
|
|
125
|
-
configuration.castling.blackShort = true
|
|
126
|
-
}
|
|
127
|
-
if (castlings.includes('Q')) {
|
|
128
|
-
configuration.castling.whiteLong = true
|
|
129
|
-
}
|
|
130
|
-
if (castlings.includes('q')) {
|
|
131
|
-
configuration.castling.blackLong = true
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// enPassant
|
|
135
|
-
if (isLocationValid(enPassant)) {
|
|
136
|
-
configuration.enPassant = enPassant.toUpperCase()
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// halfmoves
|
|
140
|
-
configuration.halfMove = parseInt(halfmove)
|
|
141
|
-
|
|
142
|
-
// fullmoves
|
|
143
|
-
configuration.fullMove = parseInt(fullmove)
|
|
144
|
-
|
|
145
|
-
return configuration
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export function isLocationValid (location) {
|
|
149
|
-
return typeof location === 'string' && location.match('^[a-hA-H]{1}[1-8]{1}$')
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function isPieceValid (piece) {
|
|
153
|
-
return Object.values(PIECES).includes(piece)
|
|
154
|
-
}
|
package/test/.eslintrc.json
DELETED
package/test/ai.test.mjs
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import chai from 'chai'
|
|
2
|
-
import { Game } from '../lib/js-chess-engine.mjs'
|
|
3
|
-
|
|
4
|
-
const expect = chai.expect
|
|
5
|
-
|
|
6
|
-
describe('Should properly calculate BEST AI move', function () {
|
|
7
|
-
before(function () {
|
|
8
|
-
this.aiLevel = 4
|
|
9
|
-
console.time('UI test calculated in')
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
after(function () {
|
|
13
|
-
console.timeEnd('UI test calculated in')
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
it('Should do checkmate in one move', function () {
|
|
17
|
-
const game = new Game({
|
|
18
|
-
turn: 'white',
|
|
19
|
-
pieces: {
|
|
20
|
-
E1: 'K',
|
|
21
|
-
A7: 'R',
|
|
22
|
-
B6: 'R',
|
|
23
|
-
E8: 'k',
|
|
24
|
-
},
|
|
25
|
-
})
|
|
26
|
-
game.printToConsole()
|
|
27
|
-
game.aiMove(this.aiLevel)
|
|
28
|
-
expect(game.exportJson().checkMate).to.be.equal(true)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('Should do checkmate in tree moves', function () {
|
|
32
|
-
const game = new Game({
|
|
33
|
-
pieces: {
|
|
34
|
-
E1: 'K',
|
|
35
|
-
A7: 'R',
|
|
36
|
-
A6: 'R',
|
|
37
|
-
E8: 'k',
|
|
38
|
-
},
|
|
39
|
-
})
|
|
40
|
-
game.printToConsole()
|
|
41
|
-
game.aiMove(this.aiLevel)
|
|
42
|
-
game.aiMove(0)
|
|
43
|
-
game.aiMove(this.aiLevel)
|
|
44
|
-
expect(game.exportJson().checkMate).to.be.equal(true)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('Should not end with draw', function () {
|
|
48
|
-
const game = new Game({
|
|
49
|
-
pieces: {
|
|
50
|
-
E3: 'K',
|
|
51
|
-
F2: 'r',
|
|
52
|
-
D6: 'q',
|
|
53
|
-
E8: 'k',
|
|
54
|
-
G3: 'p',
|
|
55
|
-
},
|
|
56
|
-
turn: 'black',
|
|
57
|
-
})
|
|
58
|
-
game.printToConsole()
|
|
59
|
-
game.aiMove(this.aiLevel)
|
|
60
|
-
expect(game.exportJson().isFinished).to.be.equal(false)
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('Should move with knight', function () {
|
|
64
|
-
const game = new Game({
|
|
65
|
-
pieces: {
|
|
66
|
-
E1: 'K',
|
|
67
|
-
D3: 'R',
|
|
68
|
-
A3: 'B',
|
|
69
|
-
H1: 'B',
|
|
70
|
-
C7: 'N',
|
|
71
|
-
G1: 'N',
|
|
72
|
-
A2: 'P',
|
|
73
|
-
B4: 'P',
|
|
74
|
-
D2: 'P',
|
|
75
|
-
F2: 'P',
|
|
76
|
-
F3: 'P',
|
|
77
|
-
H2: 'P',
|
|
78
|
-
F7: 'k',
|
|
79
|
-
H8: 'r',
|
|
80
|
-
F8: 'b',
|
|
81
|
-
G8: 'n',
|
|
82
|
-
B8: 'n',
|
|
83
|
-
A7: 'p',
|
|
84
|
-
G4: 'p',
|
|
85
|
-
H6: 'p',
|
|
86
|
-
},
|
|
87
|
-
turn: 'black',
|
|
88
|
-
})
|
|
89
|
-
game.printToConsole()
|
|
90
|
-
const result = game.board.calculateAiMove(this.aiLevel)
|
|
91
|
-
expect(['B8', 'G8'].includes(result.from)).to.be.equal(true)
|
|
92
|
-
expect(['C6', 'F6'].includes(result.to)).to.be.equal(true)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
it('Should move with pawn', function () {
|
|
96
|
-
const game = new Game({
|
|
97
|
-
pieces: {
|
|
98
|
-
D1: 'Q',
|
|
99
|
-
A1: 'R',
|
|
100
|
-
B2: 'P',
|
|
101
|
-
C2: 'P',
|
|
102
|
-
F2: 'P',
|
|
103
|
-
G2: 'P',
|
|
104
|
-
H2: 'P',
|
|
105
|
-
D8: 'q',
|
|
106
|
-
A8: 'r',
|
|
107
|
-
A7: 'p',
|
|
108
|
-
B7: 'p',
|
|
109
|
-
C7: 'p',
|
|
110
|
-
F7: 'p',
|
|
111
|
-
G7: 'p',
|
|
112
|
-
H7: 'p',
|
|
113
|
-
E4: 'P',
|
|
114
|
-
E5: 'N',
|
|
115
|
-
A3: 'P',
|
|
116
|
-
C5: 'p',
|
|
117
|
-
D5: 'N',
|
|
118
|
-
G8: 'k',
|
|
119
|
-
F8: 'r',
|
|
120
|
-
B5: 'B',
|
|
121
|
-
B8: 'n',
|
|
122
|
-
E6: 'b',
|
|
123
|
-
G1: 'K',
|
|
124
|
-
F1: 'R',
|
|
125
|
-
},
|
|
126
|
-
turn: 'black',
|
|
127
|
-
})
|
|
128
|
-
game.printToConsole()
|
|
129
|
-
const move = game.aiMove(this.aiLevel)
|
|
130
|
-
expect(move).to.be.deep.equal({ C7: 'C6' })
|
|
131
|
-
})
|
|
132
|
-
})
|
package/test/badge.svg
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="83" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="83" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h41v20H0z"/><path fill="#4C1" d="M41 0h42v20H41z"/><path fill="url(#b)" d="M0 0h83v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,Geneva,sans-serif" font-size="11"><text x="20.5" y="15" fill="#010101" fill-opacity=".3">Tests</text><text x="20.5" y="14">Tests</text><text x="61" y="15" fill="#010101" fill-opacity=".3">55/55</text><text x="61" y="14">55/55</text></g></svg>
|
package/test/importExport.mjs
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import chai from 'chai'
|
|
2
|
-
import { Game } from '../lib/js-chess-engine.mjs'
|
|
3
|
-
import { NEW_GAME_BOARD_CONFIG } from '../lib/const/board.mjs'
|
|
4
|
-
|
|
5
|
-
const expect = chai.expect
|
|
6
|
-
|
|
7
|
-
describe('Should properly export FEN', function () {
|
|
8
|
-
it('For new board', function () {
|
|
9
|
-
const expectedFen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
|
|
10
|
-
const game = new Game()
|
|
11
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
12
|
-
})
|
|
13
|
-
it('For new board after E2 to E4', function () {
|
|
14
|
-
const expectedFen = 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
|
|
15
|
-
const game = new Game()
|
|
16
|
-
game.move('E2', 'E4')
|
|
17
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
18
|
-
})
|
|
19
|
-
it('For new board after E2 to E4 and C7 to C5', function () {
|
|
20
|
-
const expectedFen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2'
|
|
21
|
-
const game = new Game()
|
|
22
|
-
game.move('E2', 'E4')
|
|
23
|
-
game.move('C7', 'C5')
|
|
24
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
25
|
-
})
|
|
26
|
-
it('For new board after E2 to E4 and C7 to C5 and E1 to E2', function () {
|
|
27
|
-
const expectedFen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPKPPP/RNBQ1BNR b kq - 1 2'
|
|
28
|
-
const game = new Game()
|
|
29
|
-
game.move('E2', 'E4')
|
|
30
|
-
game.move('C7', 'C5')
|
|
31
|
-
game.move('E1', 'E2')
|
|
32
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
33
|
-
})
|
|
34
|
-
it('For new board after E2 to E4 and C7 to C5 and E1 to E2 and D7 do D6', function () {
|
|
35
|
-
const expectedFen = 'rnbqkbnr/pp2pppp/3p4/2p5/4P3/8/PPPPKPPP/RNBQ1BNR w kq - 0 3'
|
|
36
|
-
const game = new Game()
|
|
37
|
-
game.move('E2', 'E4')
|
|
38
|
-
game.move('C7', 'C5')
|
|
39
|
-
game.move('E1', 'E2')
|
|
40
|
-
game.move('D7', 'D6')
|
|
41
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
42
|
-
})
|
|
43
|
-
it('For new board after E2 to E4 and C7 to C5 and E1 to E2 and D7 do D6 nad G1 to F3', function () {
|
|
44
|
-
const expectedFen = 'rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPPKPPP/RNBQ1B1R b kq - 1 3'
|
|
45
|
-
const game = new Game()
|
|
46
|
-
game.move('E2', 'E4')
|
|
47
|
-
game.move('C7', 'C5')
|
|
48
|
-
game.move('E1', 'E2')
|
|
49
|
-
game.move('D7', 'D6')
|
|
50
|
-
game.move('G1', 'F3')
|
|
51
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
52
|
-
})
|
|
53
|
-
it('For new board after E2 to E4 and C7 to C5 and E1 to E2 and D7 do D6 nad G1 to F3 and E8 to D7', function () {
|
|
54
|
-
const expectedFen = 'rnbq1bnr/pp1kpppp/3p4/2p5/4P3/5N2/PPPPKPPP/RNBQ1B1R w - - 2 4'
|
|
55
|
-
const game = new Game()
|
|
56
|
-
game.move('E2', 'E4')
|
|
57
|
-
game.move('C7', 'C5')
|
|
58
|
-
game.move('E1', 'E2')
|
|
59
|
-
game.move('D7', 'D6')
|
|
60
|
-
game.move('G1', 'F3')
|
|
61
|
-
game.move('E8', 'D7')
|
|
62
|
-
expect(game.exportFEN()).to.be.deep.equal(expectedFen)
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
describe('Should properly import FEN', function () {
|
|
67
|
-
beforeEach(function () {
|
|
68
|
-
this.newGameJson = JSON.parse(JSON.stringify(NEW_GAME_BOARD_CONFIG))
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('For new board', function () {
|
|
72
|
-
const gameFen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'
|
|
73
|
-
const game = new Game(gameFen)
|
|
74
|
-
const expectedConfiguration = this.newGameJson
|
|
75
|
-
|
|
76
|
-
expect(game.board.configuration).to.be.deep.equal(expectedConfiguration)
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('For new board after E2 to E4', function () {
|
|
80
|
-
const gameFen = 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
|
|
81
|
-
const game = new Game(gameFen)
|
|
82
|
-
const expectedConfiguration = this.newGameJson
|
|
83
|
-
expectedConfiguration.turn = 'black'
|
|
84
|
-
expectedConfiguration.pieces.E4 = 'P'
|
|
85
|
-
delete expectedConfiguration.pieces.E2
|
|
86
|
-
expectedConfiguration.enPassant = 'E3'
|
|
87
|
-
|
|
88
|
-
expect(game.board.configuration).to.be.deep.equal(expectedConfiguration)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('For new board after E2 to E4 and C7 to C5 and E1 to E2', function () {
|
|
92
|
-
const gameFen = 'rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPKPPP/RNBQ1BNR b kq - 1 2'
|
|
93
|
-
const game = new Game(gameFen)
|
|
94
|
-
const expectedConfiguration = this.newGameJson
|
|
95
|
-
expectedConfiguration.turn = 'black'
|
|
96
|
-
expectedConfiguration.pieces.E4 = 'P'
|
|
97
|
-
expectedConfiguration.pieces.C5 = 'p'
|
|
98
|
-
expectedConfiguration.pieces.E2 = 'K'
|
|
99
|
-
delete expectedConfiguration.pieces.C7
|
|
100
|
-
delete expectedConfiguration.pieces.E1
|
|
101
|
-
expectedConfiguration.halfMove = 1
|
|
102
|
-
expectedConfiguration.fullMove = 2
|
|
103
|
-
expectedConfiguration.castling.whiteLong = false
|
|
104
|
-
expectedConfiguration.castling.whiteShort = false
|
|
105
|
-
|
|
106
|
-
expect(game.board.configuration).to.be.deep.equal(expectedConfiguration)
|
|
107
|
-
})
|
|
108
|
-
})
|