UNPKG

tsshogi

Version:

TypeScript library for Shogi (Japanese chess)

634 lines 51.8 kB
// CSA file format (.csa) // See http://www2.computer-shogi.org/protocol/record_v22.html import { appendLine } from "./helpers/string.mjs"; import { InvalidLineError, InvalidMoveError, InvalidPieceNameError, InvalidTurnError, PieceNotExistsError, } from "./errors.mjs"; import { Color, reverseColor } from "./color.mjs"; import { anySpecialMove, Move, specialMove, SpecialMoveType } from "./move.mjs"; import { Piece, PieceType, promotedPieceType } from "./piece.mjs"; import { Position, countNotExistingPieces, InitialPositionSFEN, } from "./position.mjs"; import { Record, RecordMetadata, RecordMetadataKey, getBlackPlayerName, getWhitePlayerName, } from "./record.mjs"; import { Square } from "./square.mjs"; var LineType; (function (LineType) { LineType[LineType["VERSION"] = 0] = "VERSION"; LineType[LineType["EXTENDED_COMMENT"] = 1] = "EXTENDED_COMMENT"; LineType[LineType["COMMENT"] = 2] = "COMMENT"; LineType[LineType["BLACK_NAME"] = 3] = "BLACK_NAME"; LineType[LineType["WHITE_NAME"] = 4] = "WHITE_NAME"; LineType[LineType["METADATA"] = 5] = "METADATA"; LineType[LineType["POSITION"] = 6] = "POSITION"; LineType[LineType["RANK"] = 7] = "RANK"; LineType[LineType["PIECES"] = 8] = "PIECES"; LineType[LineType["FIRST_TURN"] = 9] = "FIRST_TURN"; LineType[LineType["MOVE"] = 10] = "MOVE"; LineType[LineType["SPECIAL_MOVE"] = 11] = "SPECIAL_MOVE"; LineType[LineType["ELAPSED"] = 12] = "ELAPSED"; })(LineType || (LineType = {})); var SectionType; (function (SectionType) { SectionType[SectionType["HEADER"] = 0] = "HEADER"; SectionType[SectionType["MOVE"] = 1] = "MOVE"; SectionType[SectionType["NEUTRAL"] = 2] = "NEUTRAL"; })(SectionType || (SectionType = {})); const linePatterns = [ { pattern: /^V/, type: LineType.VERSION, sectionType: SectionType.HEADER, }, { pattern: /^'\*(.+)$/, type: LineType.EXTENDED_COMMENT, sectionType: SectionType.NEUTRAL, }, { pattern: /^'(.+)$/, type: LineType.COMMENT, sectionType: SectionType.NEUTRAL, }, { pattern: /^N\+(.+)$/, type: LineType.BLACK_NAME, sectionType: SectionType.HEADER, }, { pattern: /^N-(.+)$/, type: LineType.WHITE_NAME, sectionType: SectionType.HEADER, }, { pattern: /^\$([^:]+):(.+)$/, type: LineType.METADATA, sectionType: SectionType.HEADER, }, { pattern: /^PI([1-9]{2}[A-Z]{2})*$/, type: LineType.POSITION, sectionType: SectionType.HEADER, }, { pattern: /^P[1-9]( \* ?|[-+][A-Z][A-Z]){9}$/, type: LineType.RANK, sectionType: SectionType.HEADER, }, { pattern: /^P[-+]([0-9]{2}[A-Z]{2})*/, type: LineType.PIECES, sectionType: SectionType.HEADER, }, { pattern: /^[-+]$/, type: LineType.FIRST_TURN, sectionType: SectionType.HEADER, }, { pattern: /^[-+][0-9]{4}[A-Z]{2}/, type: LineType.MOVE, sectionType: SectionType.MOVE, }, { pattern: /^%[-+A-Z_]+/, type: LineType.SPECIAL_MOVE, sectionType: SectionType.MOVE, }, { pattern: /^T([0-9]+(?:\.[0-9]*)?)/, type: LineType.ELAPSED, sectionType: SectionType.MOVE, }, ]; function parseLine(line) { const results = []; const lines = /^['N$]/.test(line) ? [line] : line.split(","); for (const line of lines) { for (let i = 0; i < linePatterns.length; i++) { const matched = linePatterns[i].pattern.exec(line); if (matched) { results.push({ type: linePatterns[i].type, line: line, args: matched.slice(1), sectionType: linePatterns[i].sectionType, }); break; } } } return results; } const csaNameToRecordMetadataKey = { EVENT: RecordMetadataKey.TITLE, SITE: RecordMetadataKey.PLACE, START_TIME: RecordMetadataKey.START_DATETIME, END_TIME: RecordMetadataKey.END_DATETIME, TIME_LIMIT: RecordMetadataKey.TIME_LIMIT, TIME: RecordMetadataKey.TIME_LIMIT, "TIME+": RecordMetadataKey.BLACK_TIME_LIMIT, "TIME-": RecordMetadataKey.WHITE_TIME_LIMIT, OPENING: RecordMetadataKey.STRATEGY, MAX_MOVES: RecordMetadataKey.MAX_MOVES, JISHOGI: RecordMetadataKey.JISHOGI, NOTE: RecordMetadataKey.NOTE, }; const csaNameToPieceType = { FU: PieceType.PAWN, KY: PieceType.LANCE, KE: PieceType.KNIGHT, GI: PieceType.SILVER, KI: PieceType.GOLD, KA: PieceType.BISHOP, HI: PieceType.ROOK, OU: PieceType.KING, TO: PieceType.PROM_PAWN, NY: PieceType.PROM_LANCE, NK: PieceType.PROM_KNIGHT, NG: PieceType.PROM_SILVER, UM: PieceType.HORSE, RY: PieceType.DRAGON, }; function parsePosition(line, position) { position.resetBySFEN(InitialPositionSFEN.STANDARD); for (let i = 2; i + 4 <= line.length; i += 4) { const file = Number(line[i]); const rank = Number(line[i + 1]); position.board.remove(new Square(file, rank)); } } function parseRank(line, position) { const rank = Number(line[1]); let begin = 2; for (let x = 0; x < 9; x += 1) { const file = 9 - x; const section = line.slice(begin, begin + 3); // 次のマス目は通常3文字先になる。 // ただし " * * " のように空きマスが続いた時にメールやHTML上で連続する空白がまとめられて " * * " となることがある。 // これはCSAの仕様といては正しいデータではないが、現実に存在するので配慮する。 // 3文字先へ進めるが、次の文字が "*" であれば1文字戻る。 begin += 3; if (line[begin] === "*") { begin -= 1; } if (section[0] === " ") { continue; } const color = section[0] === "+" ? Color.BLACK : Color.WHITE; const pieceType = csaNameToPieceType[section.slice(1)]; if (!pieceType) { return new InvalidPieceNameError(section); } position.board.set(new Square(file, rank), new Piece(color, pieceType)); } } function parsePieces(line, position) { const color = line[1] === "+" ? Color.BLACK : Color.WHITE; for (let begin = 2; begin + 4 <= line.length; begin += 4) { const section = line.slice(begin, begin + 4); if (section === "00AL") { const counts = countNotExistingPieces(position); if (color === Color.BLACK) { position.blackHand.forEach((pieceType) => { position.blackHand.add(pieceType, counts[pieceType]); }); } else { position.whiteHand.forEach((pieceType) => { position.whiteHand.add(pieceType, counts[pieceType]); }); } return; } const file = Number(section[0]); const rank = Number(section[1]); const pieceType = csaNameToPieceType[section.slice(2)]; if (!pieceType) { return new InvalidPieceNameError(section); } if (file !== 0 && rank !== 0) { position.board.set(new Square(file, rank), new Piece(color, pieceType)); } else if (color === Color.BLACK) { position.blackHand.add(pieceType, 1); } else { position.whiteHand.add(pieceType, 1); } } } function parseMove(line, position) { const color = line[0] === "+" ? Color.BLACK : Color.WHITE; if (color != position.color) { return new InvalidTurnError(line); } const fromFile = Number(line[1]); const fromRank = Number(line[2]); const toFile = Number(line[3]); const toRank = Number(line[4]); const pieceType = csaNameToPieceType[line.slice(5, 7)]; if (!pieceType) { return new InvalidPieceNameError(line); } const from = fromFile === 0 && fromRank === 0 ? pieceType : new Square(fromFile, fromRank); const to = new Square(toFile, toRank); let move = position.createMove(from, to); if (!move) { return new InvalidMoveError(line); } if (from instanceof Square) { const basePiece = position.board.at(from); if (!basePiece) { return new PieceNotExistsError(line); } if (basePiece.type !== pieceType) { if (basePiece.promoted().type === pieceType) { move = move.withPromote(); } else { return new PieceNotExistsError(line); } } } return move; } /** * CSA形式の特殊な指し手の名前をSpecialMoveTypeに変換します。 * @param name 先頭の % 記号を含めない名前をしていします。 * @param color 手番を指定します。 +ILLEGAL_ACTION や -ILLEGAL_ACTION の読み取りに使用します。 */ export function getSpecialMoveByName(name, color) { switch (name) { case "CHUDAN": return specialMove(SpecialMoveType.INTERRUPT); case "TORYO": return specialMove(SpecialMoveType.RESIGN); case "MAX_MOVES": return specialMove(SpecialMoveType.MAX_MOVES); case "JISHOGI": return specialMove(SpecialMoveType.IMPASS); case "HIKIWAKE": return specialMove(SpecialMoveType.DRAW); case "SENNICHITE": return specialMove(SpecialMoveType.REPETITION_DRAW); case "TSUMI": return specialMove(SpecialMoveType.MATE); case "FUZUMI": return specialMove(SpecialMoveType.NO_MATE); case "TIME_UP": return specialMove(SpecialMoveType.TIMEOUT); case "ILLEGAL_MOVE": return specialMove(SpecialMoveType.FOUL_LOSE); case "+ILLEGAL_ACTION": return specialMove(color == Color.BLACK ? SpecialMoveType.FOUL_WIN : SpecialMoveType.FOUL_LOSE); case "-ILLEGAL_ACTION": return specialMove(color == Color.WHITE ? SpecialMoveType.FOUL_WIN : SpecialMoveType.FOUL_LOSE); case "KACHI": return specialMove(SpecialMoveType.ENTERING_OF_KING); } return anySpecialMove(name); } /** * CSA形式の指し手を読み取ります。 * @param position * @param line */ export function parseCSAMove(position, line) { return parseMove(line, position); } /** * CSA形式の棋譜を読み取ります。 * @param data */ export function importCSA(data) { const metadata = new RecordMetadata(); const record = new Record(); const position = new Position(); position.resetBySFEN(InitialPositionSFEN.EMPTY); let preMoveComment = ""; let inMoveSection = false; const lines = data.replace(/\r?\n\/(\r?\n[\s\S]*)?$/, "").split(/\r?\n/); for (const line of lines) { for (const parsed of parseLine(line)) { if (parsed.sectionType === SectionType.MOVE && !inMoveSection) { return new InvalidLineError(parsed.line); } // NOTE: // WCSC の棋譜中継ではファイルの末尾に $END_TIME が書かれる。 // V2.2 の仕様上は認められないはずだが、エラーにすると実用上困るので無視する。 if (parsed.sectionType === SectionType.HEADER && inMoveSection) { continue; } switch (parsed.type) { case LineType.VERSION: break; case LineType.EXTENDED_COMMENT: if (inMoveSection) { record.current.comment = appendLine(record.current.comment, parsed.args[0]); } else { preMoveComment = appendLine(preMoveComment, parsed.args[0]); } break; case LineType.COMMENT: break; case LineType.BLACK_NAME: metadata.setStandardMetadata(RecordMetadataKey.BLACK_NAME, parsed.args[0]); break; case LineType.WHITE_NAME: metadata.setStandardMetadata(RecordMetadataKey.WHITE_NAME, parsed.args[0]); break; case LineType.METADATA: { const key = csaNameToRecordMetadataKey[parsed.args[0]]; if (key) { metadata.setStandardMetadata(key, parsed.args[1]); } else { metadata.setCustomMetadata(parsed.args[0], parsed.args[1]); } break; } case LineType.POSITION: parsePosition(parsed.line, position); break; case LineType.RANK: { const error = parseRank(parsed.line, position); if (error) { return error; } break; } case LineType.PIECES: { const error = parsePieces(parsed.line, position); if (error) { return error; } break; } case LineType.FIRST_TURN: if (parsed.line[0] === "+") { position.setColor(Color.BLACK); } else { position.setColor(Color.WHITE); } record.clear(position); record.first.comment = preMoveComment; inMoveSection = true; break; case LineType.MOVE: { const moveOrError = parseMove(parsed.line, record.position); if (moveOrError instanceof Error) { return moveOrError; } record.append(moveOrError, { ignoreValidation: true }); break; } case LineType.SPECIAL_MOVE: { const specialMove = getSpecialMoveByName(parsed.line.slice(1), record.position.color); record.append(specialMove, { ignoreValidation: true }); break; } case LineType.ELAPSED: record.current.setElapsedMs(Number(parsed.args[0]) * 1e3); break; } } } if (!inMoveSection) { record.clear(position); record.first.comment = preMoveComment; } record.goto(0); record.resetAllBranchSelection(); record.metadata = metadata; return record; } const timeRegExpV2 = /^[0-9]+:[0-9]{2}\+[0-9]+$/; const timeRegExpV3 = /^[0-9.]+\+[0-9.]+\+[0-9.]+$/; function formatMetadata(metadata, options) { let ret = ""; const returnCode = options?.returnCode || "\n"; const blackName = getBlackPlayerName(metadata); if (blackName) { ret += "N+" + blackName + returnCode; } const whiteName = getWhitePlayerName(metadata); if (whiteName) { ret += "N-" + whiteName + returnCode; } const event = metadata.getStandardMetadata(RecordMetadataKey.TOURNAMENT) || metadata.getStandardMetadata(RecordMetadataKey.TITLE) || metadata.getStandardMetadata(RecordMetadataKey.OPUS_NAME) || metadata.getStandardMetadata(RecordMetadataKey.PUBLISHED_BY); if (event) { ret += "$EVENT:" + event + returnCode; } const site = metadata.getStandardMetadata(RecordMetadataKey.PLACE); if (site) { ret += "$SITE:" + site + returnCode; } const startTime = metadata.getStandardMetadata(RecordMetadataKey.START_DATETIME) || metadata.getStandardMetadata(RecordMetadataKey.DATE); if (startTime) { // 年月日 YYYY/MM/DD (10文字) については KIF 形式と共通 ret += "$START_TIME:" + startTime.slice(10) + returnCode; } const endTime = metadata.getStandardMetadata(RecordMetadataKey.DATE); if (endTime) { ret += "$END_TIME:" + endTime.slice(10) + returnCode; } const opening = metadata.getStandardMetadata(RecordMetadataKey.STRATEGY); if (opening) { ret += "$OPENING:" + opening + returnCode; } const timeLimit = metadata.getStandardMetadata(RecordMetadataKey.TIME_LIMIT); if (timeLimit && timeRegExpV2.test(timeLimit)) { ret += "$TIME_LIMIT:" + timeLimit + returnCode; } else if (timeLimit && timeRegExpV3.test(timeLimit)) { ret += "$TIME:" + timeLimit + returnCode; } const blackTimeLimit = metadata.getStandardMetadata(RecordMetadataKey.BLACK_TIME_LIMIT); if (blackTimeLimit && timeRegExpV3.test(blackTimeLimit)) { ret += "$TIME+:" + blackTimeLimit + returnCode; } const whiteTimeLimit = metadata.getStandardMetadata(RecordMetadataKey.WHITE_TIME_LIMIT); if (whiteTimeLimit && timeRegExpV3.test(whiteTimeLimit)) { ret += "$TIME-:" + whiteTimeLimit + returnCode; } const maxMoves = metadata.getStandardMetadata(RecordMetadataKey.MAX_MOVES); if (maxMoves) { ret += "$MAX_MOVES:" + maxMoves + returnCode; } const jishogi = metadata.getStandardMetadata(RecordMetadataKey.JISHOGI); if (jishogi) { ret += "$JISHOGI:" + jishogi + returnCode; } const note = metadata.getStandardMetadata(RecordMetadataKey.NOTE); if (note) { ret += "$NOTE:" + note + returnCode; } return ret; } const pieceTypeToString = { king: "OU", rook: "HI", dragon: "RY", bishop: "KA", horse: "UM", gold: "KI", silver: "GI", promSilver: "NG", knight: "KE", promKnight: "NK", lance: "KY", promLance: "NY", pawn: "FU", promPawn: "TO", }; function formatHand(hand) { let ret = ""; hand.forEach((pieceType, n) => { for (let i = 0; i < n; i++) { ret += "00" + pieceTypeToString[pieceType]; } }); return ret; } const sfenToPCommand = { [InitialPositionSFEN.STANDARD]: ["PI", "+"], [InitialPositionSFEN.HANDICAP_LANCE]: ["PI11KY", "-"], [InitialPositionSFEN.HANDICAP_RIGHT_LANCE]: ["PI91KY", "-"], [InitialPositionSFEN.HANDICAP_BISHOP]: ["PI22KA", "-"], [InitialPositionSFEN.HANDICAP_ROOK]: ["PI82HI", "-"], [InitialPositionSFEN.HANDICAP_ROOK_LANCE]: ["PI82HI11KY", "-"], [InitialPositionSFEN.HANDICAP_2PIECES]: ["PI82HI22KA", "-"], [InitialPositionSFEN.HANDICAP_4PIECES]: ["PI82HI22KA11KY91KY", "-"], [InitialPositionSFEN.HANDICAP_6PIECES]: ["PI82HI22KA21KE81KE11KY91KY", "-"], [InitialPositionSFEN.HANDICAP_8PIECES]: ["PI82HI22KA31GI71GI21KE81KE11KY91KY", "-"], [InitialPositionSFEN.HANDICAP_10PIECES]: ["PI82HI22KA41KI61KI31GI71GI21KE81KE11KY91KY", "-"], }; function formatPosition(position, options) { const returnCode = options?.returnCode || "\n"; const p = sfenToPCommand[position.sfen]; if (p) { return p[0] + returnCode + p[1] + returnCode; } let ret = ""; for (let rank = 1; rank <= 9; rank += 1) { ret += "P" + rank; for (let file = 9; file >= 1; file -= 1) { const piece = position.board.at(new Square(file, rank)); if (!piece) { ret += " * "; } else if (piece.color === Color.BLACK) { ret += "+" + pieceTypeToString[piece.type]; } else { ret += "-" + pieceTypeToString[piece.type]; } } ret += returnCode; } ret += "P+" + formatHand(position.blackHand) + returnCode; ret += "P-" + formatHand(position.whiteHand) + returnCode; ret += (position.color === Color.BLACK ? "+" : "-") + returnCode; return ret; } function formatSquare(square) { return square instanceof Square ? `${square.file}${square.rank}` : "00"; } /** * 特殊な指し手のCSA形式文字列を取得します。 * 先頭の % は含みません。 * @param move * @param color 手番を指定します。 +ILLEGAL_ACTION や -ILLEGAL_ACTION の出力に使用します。 */ export function getCSASpecialMoveName(move, color) { switch (move.type) { case SpecialMoveType.INTERRUPT: return "CHUDAN"; case SpecialMoveType.RESIGN: return "TORYO"; case SpecialMoveType.MAX_MOVES: return "MAX_MOVES"; case SpecialMoveType.IMPASS: return "JISHOGI"; case SpecialMoveType.DRAW: return "HIKIWAKE"; case SpecialMoveType.REPETITION_DRAW: return "SENNICHITE"; case SpecialMoveType.MATE: return "TSUMI"; case SpecialMoveType.NO_MATE: return "FUZUMI"; case SpecialMoveType.TIMEOUT: return "TIME_UP"; case SpecialMoveType.FOUL_LOSE: return "ILLEGAL_MOVE"; case SpecialMoveType.FOUL_WIN: return color == Color.BLACK ? "+ILLEGAL_ACTION" : "-ILLEGAL_ACTION"; case SpecialMoveType.ENTERING_OF_KING: return "KACHI"; } } /** * CSA形式の指し手を出力します。 * @param move */ export function formatCSAMove(move) { return ((move.color === Color.BLACK ? "+" : "-") + formatSquare(move.from) + formatSquare(move.to) + pieceTypeToString[move.promote ? promotedPieceType(move.pieceType) : move.pieceType]); } /** * CSA形式の棋譜を出力します。 * @param record * @param options */ export function exportCSA(record, options) { const returnCode = options?.returnCode || "\n"; let ret = ""; if (options?.v3) { ret += "'CSA encoding=" + (options.v3.encoding || "UTF-8") + returnCode; } if (options?.comment) { for (const line of options.comment.split("\n")) { ret += "'" + line + returnCode; } } ret += (options?.v3 ? "V3.0" : "V2.2") + returnCode; ret += formatMetadata(record.metadata, options); ret += formatPosition(record.initialPosition, options); record.moves.forEach((node) => { if (node.ply !== 0) { let move; if (node.move instanceof Move) { move = formatCSAMove(node.move); } else { const name = getCSASpecialMoveName(node.move, reverseColor(node.nextColor)); if (name) { move = "%" + name; } } if (move) { ret += move + returnCode; if (options?.v3?.milliseconds && node.elapsedMs % 1e3 !== 0) { ret += "T" + node.elapsedMs / 1e3 + returnCode; } else { ret += "T" + Math.floor(node.elapsedMs / 1e3) + returnCode; } } } if (node.comment) { const comment = node.comment.endsWith("\n") ? node.comment.slice(0, -1) : node.comment; comment.split("\n").forEach((line) => { ret += "'*" + line + returnCode; }); } }); return ret; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3NhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NzYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5QkFBeUI7QUFDekIsOERBQThEO0FBRTlELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixxQkFBcUIsRUFDckIsZ0JBQWdCLEVBQ2hCLG1CQUFtQixHQUNwQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUU5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQWUsZUFBZSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlELE9BQU8sRUFDTCxRQUFRLEVBQ1Isc0JBQXNCLEVBRXRCLG1CQUFtQixHQUNwQixNQUFNLFlBQVksQ0FBQztBQUNwQixPQUFPLEVBR0wsTUFBTSxFQUNOLGNBQWMsRUFDZCxpQkFBaUIsRUFDakIsa0JBQWtCLEVBQ2xCLGtCQUFrQixHQUNuQixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRWxDLElBQUssUUFjSjtBQWRELFdBQUssUUFBUTtJQUNYLDZDQUFPLENBQUE7SUFDUCwrREFBZ0IsQ0FBQTtJQUNoQiw2Q0FBTyxDQUFBO0lBQ1AsbURBQVUsQ0FBQTtJQUNWLG1EQUFVLENBQUE7SUFDViwrQ0FBUSxDQUFBO0lBQ1IsK0NBQVEsQ0FBQTtJQUNSLHVDQUFJLENBQUE7SUFDSiwyQ0FBTSxDQUFBO0lBQ04sbURBQVUsQ0FBQTtJQUNWLHdDQUFJLENBQUE7SUFDSix3REFBWSxDQUFBO0lBQ1osOENBQU8sQ0FBQTtBQUNULENBQUMsRUFk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