This commit is contained in:
Maciej Caderek
2022-01-16 05:20:19 +01:00
parent e1767fd48c
commit 7052c74171
7 changed files with 168 additions and 40 deletions

View File

@@ -1,4 +1,5 @@
import { Chess, ChessInstance, Move } from "chess.js";
import { cleanPGN } from "./PGNHelpers";
class Game {
private game: ChessInstance;
@@ -12,33 +13,8 @@ class Game {
this.moves = [];
}
private cleanPGN(pgn: string) {
const game = new Chess();
game.load_pgn(pgn);
game.delete_comments();
const [_, moves] = game.pgn().split("\n\n");
const header = Object.entries(game.header())
.filter(([key]) =>
[
"event",
"site",
"white",
"black",
"date",
"result",
"opening",
].includes(key.toLowerCase())
)
.map(([key, val]) => `[${key} "${val}"]`)
.sort()
.join("\n");
return [header, moves].join("\n\n");
}
loadPGN(pgn: string) {
this.game.load_pgn(this.cleanPGN(pgn));
this.game.load_pgn(cleanPGN(pgn));
this.game.delete_comments();
this.moves = this.game.history({ verbose: true });
this.currentPly = 0;

79
src/game/PGNHelpers.ts Normal file
View File

@@ -0,0 +1,79 @@
import { Chess } from "chess.js";
const PGN_KEYS_TO_SHORT = {
Event: "E",
Site: "S",
White: "W",
Black: "B",
Date: "D",
Result: "R",
FEN: "F",
};
const PGN_KEYS = Object.keys(PGN_KEYS_TO_SHORT);
const PGN_KEYS_TO_LONG = Object.fromEntries(
Object.entries(PGN_KEYS_TO_SHORT).map(([long, short]) => [short, long])
);
const cleanPGN = (pgn: string) => {
const game = new Chess();
game.load_pgn(pgn);
game.delete_comments();
const [_, moves] = game.pgn().split("\n\n");
const header = Object.entries(game.header())
.filter(([key]) => PGN_KEYS.includes(key))
.map(([key, val]) => `[${key} "${val}"]`)
.sort()
.join("\n");
return [header, moves].join("\n\n");
};
const compressPGN = (pgn: string) => {
const game = new Chess();
game.load_pgn(pgn);
const moves = game.history().join(" ");
const header = Object.entries(game.header())
.filter(([key]) => PGN_KEYS.includes(key))
.map(([key, val]) => `${key[0].toUpperCase()} ${val}`)
.sort()
.join("\n");
return btoa([header, moves].join("\n\n"));
};
const decompressPGN = (compressedPGN: string) => {
const [headerRaw, movesRaw] = atob(compressedPGN).split("\n\n");
let result;
const header = headerRaw
.split("\n")
.map((entry) => {
const [shortKey, ...data] = entry.split(" ");
const value = data.join(" ");
if (shortKey === "R") {
result = value;
}
return `[${PGN_KEYS_TO_LONG[shortKey]} "${value}"]`;
})
.join("\n");
const moves =
movesRaw
.split(" ")
.map((move, index) =>
index % 2 === 0 ? `${index / 2 + 1}. ${move}` : move
)
.join(" ") + ` ${result}`;
return [header, moves].join("\n\n");
};
export { cleanPGN, compressPGN, decompressPGN };