pgn-manager 1.0.1 → 1.1.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 +8 -7
- package/dist/index.d.ts +95 -5
- package/dist/index.js +114 -5
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -6,7 +6,6 @@ A powerful TypeScript/JavaScript library for managing chess PGN (Portable Game N
|
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
8
|
[](https://www.npmjs.com/package/pgn-manager)
|
|
9
|
-
[](https://coveralls.io/github/username/pgn-manager?branch=main)
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
## Features ✨
|
|
@@ -58,14 +57,16 @@ const headers = manager.headers;
|
|
|
58
57
|
|
|
59
58
|
### Methods
|
|
60
59
|
- `getMove(moveNumber: number)`: Get move by number
|
|
61
|
-
- `getMoveNumber(
|
|
62
|
-
- `nextMove(
|
|
63
|
-
- `previousMove(
|
|
64
|
-
- `hasNextMove(
|
|
60
|
+
- `getMoveNumber(moveOrMoveId: Move | number)`: Get number for a move
|
|
61
|
+
- `nextMove(moveOrMoveId: Move | number)`: Get next move in the sequence
|
|
62
|
+
- `previousMove(moveOrMoveId: Move | number)`: Get previous move
|
|
63
|
+
- `hasNextMove(moveOrMoveId: Move | number)`: Check if move has a next move
|
|
65
64
|
- `getFirstMove()`: Get the first move of the game
|
|
66
65
|
- `getLastMove()`: Get the last move of the game
|
|
67
|
-
- `getMoveFen(
|
|
68
|
-
- `getParentRav(
|
|
66
|
+
- `getMoveFen(moveOrMoveId: Move | number)`: Get FEN position after move
|
|
67
|
+
- `getParentRav(moveOrMoveId: Move | number)`: Get parent variation for move
|
|
68
|
+
- `getChessJSInstance(moveOrMoveId: Move | number)`: Get or create a ChessJS instance for the position after the specified move
|
|
69
|
+
- `getMoveColor(moveOrMoveId: Move | number)`: Gets the color of the player who made the move ("w" for white or "b" for black)
|
|
69
70
|
|
|
70
71
|
## Examples 🎯
|
|
71
72
|
|
package/dist/index.d.ts
CHANGED
|
@@ -2,26 +2,116 @@ import { ParsedPGN, Move, Rav, Header } from "pgn-parser";
|
|
|
2
2
|
export declare const FEN_START_POSITION = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
|
3
3
|
export declare const FEN_EMPTY_POSITION = "8/8/8/8/8/8/8/8";
|
|
4
4
|
declare class PGNManager {
|
|
5
|
+
/** The raw PGN string input */
|
|
5
6
|
private rawPGN;
|
|
7
|
+
/** The parsed PGN game object */
|
|
6
8
|
private game;
|
|
9
|
+
/** Array of moves in traversal order */
|
|
7
10
|
private sortedMoves;
|
|
11
|
+
/** Map of moves to their FEN position strings */
|
|
8
12
|
private moveFen;
|
|
13
|
+
/** Map of moves to their parent variations (or null for mainline) */
|
|
9
14
|
private moveParent;
|
|
15
|
+
/** Map of variations to their parent moves */
|
|
10
16
|
private ravParent;
|
|
17
|
+
/** Map of moves to the color of the player who made the move */
|
|
18
|
+
private moveColor;
|
|
19
|
+
/**
|
|
20
|
+
* Creates a new PGNManager instance
|
|
21
|
+
* @param pgn - The PGN string to parse and manage
|
|
22
|
+
*/
|
|
11
23
|
constructor(pgn: string);
|
|
24
|
+
/**
|
|
25
|
+
* Initializes the game traversal starting from the initial position
|
|
26
|
+
* @param game - The parsed PGN game object
|
|
27
|
+
*/
|
|
12
28
|
private dfOnGame;
|
|
29
|
+
/**
|
|
30
|
+
* Performs depth-first traversal of the game moves and variations
|
|
31
|
+
* @param move - The current move being processed
|
|
32
|
+
* @param parent - The parent RAV (variation) containing the move
|
|
33
|
+
* @param chessGame - The chess instance for the current position
|
|
34
|
+
*/
|
|
13
35
|
private dfsOnGame;
|
|
36
|
+
/**
|
|
37
|
+
* Gets the raw PGN string
|
|
38
|
+
* @returns The original PGN string
|
|
39
|
+
*/
|
|
14
40
|
get pgn(): string;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the parsed PGN object
|
|
43
|
+
* @returns The parsed PGN game object
|
|
44
|
+
*/
|
|
15
45
|
get parsedPGN(): ParsedPGN;
|
|
46
|
+
/**
|
|
47
|
+
* Gets the game headers
|
|
48
|
+
* @returns Array of game headers
|
|
49
|
+
*/
|
|
16
50
|
get headers(): Array<Header>;
|
|
51
|
+
/**
|
|
52
|
+
* Gets a move by its number in the sequence
|
|
53
|
+
* @param moveNumber - The 1-based index of the move
|
|
54
|
+
* @returns The move object at the specified position
|
|
55
|
+
*/
|
|
17
56
|
getMove: (moveNumber: number) => Move;
|
|
57
|
+
/**
|
|
58
|
+
* Gets the number of a move in the sequence
|
|
59
|
+
* @param move - The move object
|
|
60
|
+
* @returns The 1-based index of the move
|
|
61
|
+
*/
|
|
18
62
|
getMoveNumber: (move: Move) => number;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Gets the next move in the sequence
|
|
65
|
+
* @param moveOrId - The current move object or move number
|
|
66
|
+
* @returns The next move in the sequence
|
|
67
|
+
* @throws Error if there are no moves in the game
|
|
68
|
+
*/
|
|
69
|
+
nextMove: (moveOrId: Move | number | undefined) => Move;
|
|
70
|
+
/**
|
|
71
|
+
* Checks if there is a next move available
|
|
72
|
+
* @param moveOrId - The current move object or move number
|
|
73
|
+
* @returns True if there is a next move, false otherwise
|
|
74
|
+
*/
|
|
75
|
+
hasNextMove: (moveOrId: Move | number) => boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Gets the previous move in the sequence
|
|
78
|
+
* @param moveOrId - The current move object or move number
|
|
79
|
+
* @returns The previous move or undefined if at the start
|
|
80
|
+
* @throws Error if there are no moves or if the move parameter is invalid
|
|
81
|
+
*/
|
|
82
|
+
previousMove: (moveOrId: Move | number) => Move | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Gets the first move in the game
|
|
85
|
+
* @returns The first move
|
|
86
|
+
* @throws Error if there are no moves in the game
|
|
87
|
+
*/
|
|
22
88
|
getFirstMove: () => Move;
|
|
89
|
+
/**
|
|
90
|
+
* Gets the last move in the game
|
|
91
|
+
* @returns The last move
|
|
92
|
+
* @throws Error if there are no moves in the game
|
|
93
|
+
*/
|
|
23
94
|
getLastMove: () => any;
|
|
24
|
-
|
|
25
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Gets the FEN string for a specific move
|
|
97
|
+
* @param moveOrId - The move object or move number
|
|
98
|
+
* @returns The FEN string representing the position after the move
|
|
99
|
+
* @throws Error if the move parameter is invalid
|
|
100
|
+
*/
|
|
101
|
+
getMoveFen: (moveOrId: Move | number) => string;
|
|
102
|
+
/**
|
|
103
|
+
* Gets the parent RAV (variation) for a move
|
|
104
|
+
* @param moveOrId - The move object or move number
|
|
105
|
+
* @returns The parent RAV or null if the move is in the main line
|
|
106
|
+
* @throws Error if the move parameter is invalid
|
|
107
|
+
*/
|
|
108
|
+
getParentRav: (moveOrId: Move | number) => Rav | null;
|
|
109
|
+
/**
|
|
110
|
+
* Gets the color of the player who made the move
|
|
111
|
+
* @param moveOrId - The move object or move ID number
|
|
112
|
+
* @returns "w" for white or "b" for black
|
|
113
|
+
* @throws Error if the move parameter is invalid
|
|
114
|
+
*/
|
|
115
|
+
getMoveColor: (moveOrId: Move | number) => "w" | "b";
|
|
26
116
|
}
|
|
27
117
|
export default PGNManager;
|
package/dist/index.js
CHANGED
|
@@ -7,12 +7,24 @@ const pgn_parser_1 = require("pgn-parser");
|
|
|
7
7
|
exports.FEN_START_POSITION = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
|
8
8
|
exports.FEN_EMPTY_POSITION = "8/8/8/8/8/8/8/8";
|
|
9
9
|
class PGNManager {
|
|
10
|
+
/** The raw PGN string input */
|
|
10
11
|
rawPGN;
|
|
12
|
+
/** The parsed PGN game object */
|
|
11
13
|
game;
|
|
14
|
+
/** Array of moves in traversal order */
|
|
12
15
|
sortedMoves;
|
|
16
|
+
/** Map of moves to their FEN position strings */
|
|
13
17
|
moveFen;
|
|
18
|
+
/** Map of moves to their parent variations (or null for mainline) */
|
|
14
19
|
moveParent;
|
|
20
|
+
/** Map of variations to their parent moves */
|
|
15
21
|
ravParent;
|
|
22
|
+
/** Map of moves to the color of the player who made the move */
|
|
23
|
+
moveColor;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new PGNManager instance
|
|
26
|
+
* @param pgn - The PGN string to parse and manage
|
|
27
|
+
*/
|
|
16
28
|
constructor(pgn) {
|
|
17
29
|
this.rawPGN = pgn;
|
|
18
30
|
this.game = pgn_parser_1.default.parse(pgn + " *")[0];
|
|
@@ -20,8 +32,13 @@ class PGNManager {
|
|
|
20
32
|
this.moveParent = new Map();
|
|
21
33
|
this.ravParent = new Map();
|
|
22
34
|
this.moveFen = new Map();
|
|
35
|
+
this.moveColor = new Map();
|
|
23
36
|
this.dfOnGame(this.game);
|
|
24
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Initializes the game traversal starting from the initial position
|
|
40
|
+
* @param game - The parsed PGN game object
|
|
41
|
+
*/
|
|
25
42
|
dfOnGame = (game) => {
|
|
26
43
|
this.sortedMoves = [];
|
|
27
44
|
var chessGame = new Chess(exports.FEN_START_POSITION);
|
|
@@ -29,6 +46,12 @@ class PGNManager {
|
|
|
29
46
|
this.dfsOnGame(move, game, chessGame);
|
|
30
47
|
}
|
|
31
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Performs depth-first traversal of the game moves and variations
|
|
51
|
+
* @param move - The current move being processed
|
|
52
|
+
* @param parent - The parent RAV (variation) containing the move
|
|
53
|
+
* @param chessGame - The chess instance for the current position
|
|
54
|
+
*/
|
|
32
55
|
dfsOnGame = (move, parent, chessGame) => {
|
|
33
56
|
this.sortedMoves.push(move);
|
|
34
57
|
this.moveParent.set(move, parent);
|
|
@@ -46,26 +69,62 @@ class PGNManager {
|
|
|
46
69
|
!chessGame.move(move.move, { sloppy: true }))
|
|
47
70
|
console.log("Invalid move: " + move.move);
|
|
48
71
|
this.moveFen.set(move, chessGame.fen());
|
|
72
|
+
this.moveColor.set(move, chessGame.turn() === "w" ? "b" : "w");
|
|
49
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* Gets the raw PGN string
|
|
76
|
+
* @returns The original PGN string
|
|
77
|
+
*/
|
|
50
78
|
get pgn() {
|
|
51
79
|
return this.rawPGN;
|
|
52
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Gets the parsed PGN object
|
|
83
|
+
* @returns The parsed PGN game object
|
|
84
|
+
*/
|
|
53
85
|
get parsedPGN() {
|
|
54
86
|
return this.game;
|
|
55
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Gets the game headers
|
|
90
|
+
* @returns Array of game headers
|
|
91
|
+
*/
|
|
56
92
|
get headers() {
|
|
57
93
|
if (!this.game || !this.game.headers)
|
|
58
94
|
return [];
|
|
59
95
|
return this.game.headers;
|
|
60
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Gets a move by its number in the sequence
|
|
99
|
+
* @param moveNumber - The 1-based index of the move
|
|
100
|
+
* @returns The move object at the specified position
|
|
101
|
+
*/
|
|
61
102
|
getMove = (moveNumber) => {
|
|
62
103
|
let move = this.sortedMoves[moveNumber - 1];
|
|
63
104
|
return move;
|
|
64
105
|
};
|
|
106
|
+
/**
|
|
107
|
+
* Gets the number of a move in the sequence
|
|
108
|
+
* @param move - The move object
|
|
109
|
+
* @returns The 1-based index of the move
|
|
110
|
+
*/
|
|
65
111
|
getMoveNumber = (move) => {
|
|
66
112
|
return this.sortedMoves.indexOf(move) + 1;
|
|
67
113
|
};
|
|
68
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Gets the next move in the sequence
|
|
116
|
+
* @param moveOrId - The current move object or move number
|
|
117
|
+
* @returns The next move in the sequence
|
|
118
|
+
* @throws Error if there are no moves in the game
|
|
119
|
+
*/
|
|
120
|
+
nextMove = (moveOrId) => {
|
|
121
|
+
let move;
|
|
122
|
+
if (typeof moveOrId === "number") {
|
|
123
|
+
move = this.getMove(moveOrId);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
move = moveOrId;
|
|
127
|
+
}
|
|
69
128
|
if (!move) {
|
|
70
129
|
if (this.sortedMoves.length == 0) {
|
|
71
130
|
throw Error("No moves in game");
|
|
@@ -92,10 +151,23 @@ class PGNManager {
|
|
|
92
151
|
}
|
|
93
152
|
return tempNextMove;
|
|
94
153
|
};
|
|
95
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Checks if there is a next move available
|
|
156
|
+
* @param moveOrId - The current move object or move number
|
|
157
|
+
* @returns True if there is a next move, false otherwise
|
|
158
|
+
*/
|
|
159
|
+
hasNextMove = (moveOrId) => {
|
|
160
|
+
const move = typeof moveOrId === "number" ? this.getMove(moveOrId) : moveOrId;
|
|
96
161
|
return !move || this.nextMove(move) !== move;
|
|
97
162
|
};
|
|
98
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Gets the previous move in the sequence
|
|
165
|
+
* @param moveOrId - The current move object or move number
|
|
166
|
+
* @returns The previous move or undefined if at the start
|
|
167
|
+
* @throws Error if there are no moves or if the move parameter is invalid
|
|
168
|
+
*/
|
|
169
|
+
previousMove = (moveOrId) => {
|
|
170
|
+
const move = typeof moveOrId === "number" ? this.getMove(moveOrId) : moveOrId;
|
|
99
171
|
if (!move) {
|
|
100
172
|
if (this.sortedMoves.length == 0) {
|
|
101
173
|
throw Error("No moves in game");
|
|
@@ -122,31 +194,68 @@ class PGNManager {
|
|
|
122
194
|
}
|
|
123
195
|
return tempPrevMove;
|
|
124
196
|
};
|
|
197
|
+
/**
|
|
198
|
+
* Gets the first move in the game
|
|
199
|
+
* @returns The first move
|
|
200
|
+
* @throws Error if there are no moves in the game
|
|
201
|
+
*/
|
|
125
202
|
getFirstMove = () => {
|
|
126
203
|
if (this.sortedMoves.length == 0) {
|
|
127
204
|
throw Error("No moves in game");
|
|
128
205
|
}
|
|
129
206
|
return this.sortedMoves[0];
|
|
130
207
|
};
|
|
208
|
+
/**
|
|
209
|
+
* Gets the last move in the game
|
|
210
|
+
* @returns The last move
|
|
211
|
+
* @throws Error if there are no moves in the game
|
|
212
|
+
*/
|
|
131
213
|
getLastMove = () => {
|
|
132
214
|
if (this.sortedMoves.length == 0) {
|
|
133
215
|
throw Error("No moves in game");
|
|
134
216
|
}
|
|
135
217
|
return this.game.moves[this.game.moves.length - 1];
|
|
136
218
|
};
|
|
137
|
-
|
|
219
|
+
/**
|
|
220
|
+
* Gets the FEN string for a specific move
|
|
221
|
+
* @param moveOrId - The move object or move number
|
|
222
|
+
* @returns The FEN string representing the position after the move
|
|
223
|
+
* @throws Error if the move parameter is invalid
|
|
224
|
+
*/
|
|
225
|
+
getMoveFen = (moveOrId) => {
|
|
226
|
+
const move = typeof moveOrId === "number" ? this.getMove(moveOrId) : moveOrId;
|
|
138
227
|
if (!move) {
|
|
139
228
|
throw Error("Invalid 'move' parameter while getting fen");
|
|
140
229
|
}
|
|
141
230
|
let moveFen = this.moveFen.get(move);
|
|
142
231
|
return moveFen ? moveFen : exports.FEN_EMPTY_POSITION;
|
|
143
232
|
};
|
|
144
|
-
|
|
233
|
+
/**
|
|
234
|
+
* Gets the parent RAV (variation) for a move
|
|
235
|
+
* @param moveOrId - The move object or move number
|
|
236
|
+
* @returns The parent RAV or null if the move is in the main line
|
|
237
|
+
* @throws Error if the move parameter is invalid
|
|
238
|
+
*/
|
|
239
|
+
getParentRav = (moveOrId) => {
|
|
240
|
+
const move = typeof moveOrId === "number" ? this.getMove(moveOrId) : moveOrId;
|
|
145
241
|
if (!move) {
|
|
146
242
|
throw Error("Invalid 'move' parameter while getting parent rav");
|
|
147
243
|
}
|
|
148
244
|
let parentRav = this.moveParent.get(move);
|
|
149
245
|
return parentRav ? parentRav : null;
|
|
150
246
|
};
|
|
247
|
+
/**
|
|
248
|
+
* Gets the color of the player who made the move
|
|
249
|
+
* @param moveOrId - The move object or move ID number
|
|
250
|
+
* @returns "w" for white or "b" for black
|
|
251
|
+
* @throws Error if the move parameter is invalid
|
|
252
|
+
*/
|
|
253
|
+
getMoveColor = (moveOrId) => {
|
|
254
|
+
const move = typeof moveOrId === "number" ? this.getMove(moveOrId) : moveOrId;
|
|
255
|
+
if (!move) {
|
|
256
|
+
throw Error("Invalid 'move' parameter while getting move color");
|
|
257
|
+
}
|
|
258
|
+
return this.moveColor.get(move);
|
|
259
|
+
};
|
|
151
260
|
}
|
|
152
261
|
exports.default = PGNManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pgn-manager",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Libraray built on top of chess.js and pgn-parser to load and process PGN files in typescript.",
|
|
5
5
|
"main": "dist/index",
|
|
6
6
|
"typings": "dist/index",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"pgn-parser": "2.1.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
+
"@types/chess.js": "^0.11.2",
|
|
34
35
|
"typescript": "4.5.2"
|
|
35
36
|
},
|
|
36
37
|
"files": [
|