import { pos2key, invRanks } from "./util.js"; import * as cg from "./types.js"; export const initial: cg.FEN = "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w"; const roles: { [letter: string]: cg.Role } = { p: "pawn", r: "rook", n: "knight", b: "bishop", a: "advisor", c: "cannon", k: "king", }; const letters = { pawn: "p", rook: "r", knight: "n", bishop: "b", advisor: "a", cannon: "c", king: "k", }; export function read(fen: cg.FEN): cg.Pieces { if (fen === "start") fen = initial; if (fen.indexOf("[") !== -1) fen = fen.slice(0, fen.indexOf("[")); const pieces: cg.Pieces = new Map(); let row: number = fen.split("/").length; let col: number = 0; for (const c of fen) { switch (c) { case " ": return pieces; case "/": --row; if (row === 0) return pieces; col = 0; break; case "~": // const piece = pieces.get(pos2key([col, row])); break; default: const nb = c.charCodeAt(0); if (nb < 58) { col += c === "0" ? 9 : nb - 48; } else { ++col; const role = c.toLowerCase(); let piece = { role: roles[role], color: (c === role ? "black" : "white") as cg.Color, } as cg.Piece; pieces.set(pos2key([col, row]), piece); } } } return pieces; } export function write(pieces: cg.Pieces): cg.FEN { return invRanks .map((y) => cg.files .map((x) => { const piece = pieces.get((x + y) as cg.Key); if (piece) { const letter = letters[piece.role]; return piece.color === "white" ? letter.toUpperCase() : letter; } else return "1"; }) .join("") ) .join("/") .replace(/1{2,}/g, (s) => s.length.toString()); }