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

@@ -19,7 +19,7 @@ const drawPieces = async (
type: PieceType; type: PieceType;
color: PieceColor; color: PieceColor;
}; };
const img = await ImagesCache.get("tatiana", type, color); const img = await ImagesCache.get("cburnett", type, color);
const rank = flipped ? tiles - 1 - y : y; const rank = flipped ? tiles - 1 - y : y;
const file = flipped ? tiles - 1 - x : x; const file = flipped ? tiles - 1 - x : x;
@@ -34,9 +34,11 @@ const drawPieces = async (
} }
if (color === check && type === "k") { if (color === check && type === "k") {
filters.push(`drop-shadow(0 0 ${squareSize * 0.1}px orange)`); filters.push(`drop-shadow(0 0 ${squareSize * 0.07}px #ffa600)`);
filters.push(`drop-shadow(0 0 ${squareSize * 0.07}px #ffa600)`);
} else if (color === mate && type === "k") { } else if (color === mate && type === "k") {
filters.push(`drop-shadow(0 0 ${squareSize * 0.1}px red)`); filters.push(`drop-shadow(0 0 ${squareSize * 0.07}px #ff002f)`);
filters.push(`drop-shadow(0 0 ${squareSize * 0.07}px #ff002f)`);
} }
ctx.filter = filters.length > 0 ? filters.join(" ") : "none"; ctx.filter = filters.length > 0 ? filters.join(" ") : "none";

View File

@@ -3,6 +3,7 @@ import calm from "./calm";
import standard from "./standard"; import standard from "./standard";
import glass from "./glass"; import glass from "./glass";
// import kittens from "./kittens"; // import kittens from "./kittens";
import lichess from "./lichess";
import lila from "./lila"; import lila from "./lila";
import mono from "./mono"; import mono from "./mono";
import peach from "./peach"; import peach from "./peach";
@@ -12,6 +13,7 @@ export default {
calm, calm,
glass, glass,
// kittens, // kittens,
lichess,
lila, lila,
mono, mono,
peach, peach,

View File

@@ -0,0 +1,42 @@
import { Style } from "../../types";
const style: Style = {
name: "Lichess",
background: {
type: "solid",
data: {
color: "transparent",
},
},
dark: {
type: "solid",
data: {
color: "#b58863",
},
},
light: {
type: "solid",
data: {
color: "#f0d9b5",
},
},
moveIndicator: {
type: "solid",
data: {
color: "rgba(155,199,0,0.41)",
},
},
border: null,
// border: {
// type: "solid",
// data: {
// color: "#896d56",
// },
// },
coords: {
lightColor: "#f0d9b5",
darkColor: "#b58863",
},
};
export default style;

View File

@@ -1,4 +1,5 @@
import { Chess, ChessInstance, Move } from "chess.js"; import { Chess, ChessInstance, Move } from "chess.js";
import { cleanPGN } from "./PGNHelpers";
class Game { class Game {
private game: ChessInstance; private game: ChessInstance;
@@ -12,33 +13,8 @@ class Game {
this.moves = []; 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) { loadPGN(pgn: string) {
this.game.load_pgn(this.cleanPGN(pgn)); this.game.load_pgn(cleanPGN(pgn));
this.game.delete_comments(); this.game.delete_comments();
this.moves = this.game.history({ verbose: true }); this.moves = this.game.history({ verbose: true });
this.currentPly = 0; 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 };

View File

@@ -5,18 +5,22 @@ import styles from "./board/styles-board";
import Game from "./game/Game"; import Game from "./game/Game";
import pgns from "./test-data/pgns"; import pgns from "./test-data/pgns";
import createSimpleGIF from "./gif/createSimpleGIF"; import createSimpleGIF from "./gif/createSimpleGIF";
import { compressPGN, decompressPGN } from "./game/PGNHelpers";
const $app = document.querySelector<HTMLImageElement>("#app"); const $app = document.querySelector<HTMLImageElement>("#app");
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const play = async (board: Board, pgn: string, interval: number) => { const play = async (board: Board, pgn: string | null, interval: number) => {
const game = new Game().loadPGN(pgn); const game = new Game();
if (pgn) {
game.loadPGN(pgn);
}
// game.goto(28); // game.goto(28);
await board.render(game.getBoardData()); await board.render(game.getBoardData());
console.log(game.pgn());
while (true) { while (true) {
const move = game.next(); const move = game.next();
@@ -28,7 +32,7 @@ const play = async (board: Board, pgn: string, interval: number) => {
await board.render(game.getBoardData(), move); await board.render(game.getBoardData(), move);
} }
await delay(interval); await delay(interval * 3);
play(board, pgn, interval); play(board, pgn, interval);
}; };
@@ -42,17 +46,21 @@ const createDownloadLink = async (pgn: string, style: Style) => {
}; };
const main = async () => { const main = async () => {
const style = styles.calm; const style = styles.avocado;
// Object.values(styles).forEach((style, i) => {
const hash = window.location.hash;
const pgn = hash === "" ? null : decompressPGN(hash.slice(1));
const board = new Board(8).setStyle(style).setSize(720).showBorder(); const board = new Board(8).setStyle(style).setSize(720).showBorder();
window.location.hash = "#alala";
$app?.appendChild(board.canvas); $app?.appendChild(board.canvas);
play(board, pgns[0], 1000); play(board, pgn, 1000);
// });
// const link = await createDownloadLink(pgns[0], styles.peach); // createDownloadLink(pgns[0], style).then((link) => {
// document.body.appendChild(link); // document.body.appendChild(link);
// });
}; };
main(); main();

View File

@@ -20,6 +20,25 @@ is hanging, the bishop is blocked because of the
Queen.--Fischer} b5 10.Nxb5 cxb5 11.Bxb5+ Nbd7 12.O-O-O Rd8 Queen.--Fischer} b5 10.Nxb5 cxb5 11.Bxb5+ Nbd7 12.O-O-O Rd8
13.Rxd7 Rxd7 14.Rd1 Qe6 15.Bxd7+ Nxd7 16.Qb8+ Nxb8 17.Rd8# 1-0`, 13.Rxd7 Rxd7 14.Rd1 Qe6 15.Bxd7+ Nxd7 16.Qb8+ Nxb8 17.Rd8# 1-0`,
`[Event "Casual Bullet game"]
[Site "https://lichess.org/9PndkM3J"]
[Date "2022.01.15"]
[White "Anonymous"]
[Black "Anonymous"]
[Result "1-0"]
[UTCDate "2022.01.15"]
[UTCTime "19:04:57"]
[WhiteElo "?"]
[BlackElo "?"]
[Variant "Standard"]
[TimeControl "60+0"]
[ECO "A00"]
[Opening "Polish Opening"]
[Termination "Normal"]
[Annotator "lichess.org"]
1. b4 { A00 Polish Opening } e5 2. Bb2 Nc6 3. b5 Nd4 4. e3 Nxb5 5. Bxb5 c6 6. Be2 Nf6 7. Bxe5 d6 8. Bb2 Be7 9. Nf3 O-O 10. O-O Bg4 11. d3 d5 12. Nbd2 Rc8 13. Qc1 Be6 14. c4 d4 15. Bxd4 Bg4 16. Bb2 Qc7 17. Qc3 Bxf3 18. Bxf3 Rcd8 19. Ne4 a5 20. a3 b5 21. Rad1 b4 22. axb4 Bxb4 23. Nxf6+ gxf6 24. Qxf6 Rd6 25. Qg7# { White wins by checkmate. } 1-0`,
`[Event "Hoogovens Group A"] `[Event "Hoogovens Group A"]
[Site "Wijk aan Zee NED"] [Site "Wijk aan Zee NED"]
[Date "1999.01.20"] [Date "1999.01.20"]