UNPKG

tsshogi

Version:

TypeScript library for Shogi (Japanese chess)

904 lines 71.5 kB
// KIF file format (.kif or .kifu)
// See http://kakinoki.o.oo7.jp/kif_format.html
import { appendLine } from "./helpers/string.mjs";
import { millisecondsToHHMMSS, millisecondsToMSS } from "./helpers/time.mjs";
import { Color } from "./color.mjs";
import { InvalidBoardError, InvalidDestinationError, InvalidHandPieceError, InvalidLineError, InvalidMoveError, InvalidMoveNumberError, } from "./errors.mjs";
import { Move, SpecialMoveType, anySpecialMove, isKnownSpecialMove, specialMove, } from "./move.mjs";
import { Piece } from "./piece.mjs";
import { InitialPositionSFEN, Position } from "./position.mjs";
import { Record, RecordMetadata, RecordMetadataKey, } from "./record.mjs";
import { Square } from "./square.mjs";
import { fileToMultiByteChar, formatMove, numberToKanji, parseMoves, pieceTypeToStringForBoard, pieceTypeToStringForMove, rankToKanji, stringToNumber, stringToPieceType, } from "./text.mjs";
export var KakinokiFormatType;
(function (KakinokiFormatType) {
    KakinokiFormatType["KIF"] = "KIF";
    KakinokiFormatType["KI2"] = "KI2";
})(KakinokiFormatType || (KakinokiFormatType = {}));
const metadataKeyMap = {
    先手: RecordMetadataKey.BLACK_NAME,
    後手: RecordMetadataKey.WHITE_NAME,
    下手: RecordMetadataKey.SHITATE_NAME,
    上手: RecordMetadataKey.UWATE_NAME,
    開始日時: RecordMetadataKey.START_DATETIME,
    終了日時: RecordMetadataKey.END_DATETIME,
    対局日: RecordMetadataKey.DATE,
    棋戦: RecordMetadataKey.TOURNAMENT,
    戦型: RecordMetadataKey.STRATEGY,
    表題: RecordMetadataKey.TITLE,
    持ち時間: RecordMetadataKey.TIME_LIMIT,
    秒読み: RecordMetadataKey.BYOYOMI,
    消費時間: RecordMetadataKey.TIME_SPENT,
    場所: RecordMetadataKey.PLACE,
    掲載: RecordMetadataKey.POSTED_ON,
    備考: RecordMetadataKey.NOTE,
    先手省略名: RecordMetadataKey.BLACK_SHORT_NAME,
    後手省略名: RecordMetadataKey.WHITE_SHORT_NAME,
    記録係: RecordMetadataKey.SCOREKEEPER,
    作品番号: RecordMetadataKey.OPUS_NO,
    作品名: RecordMetadataKey.OPUS_NAME,
    作者: RecordMetadataKey.AUTHOR,
    発表誌: RecordMetadataKey.PUBLISHED_BY,
    発表年月: RecordMetadataKey.PUBLISHED_AT,
    出典: RecordMetadataKey.SOURCE,
    手数: RecordMetadataKey.LENGTH,
    完全性: RecordMetadataKey.INTEGRITY,
    分類: RecordMetadataKey.CATEGORY,
    受賞: RecordMetadataKey.AWARD,
    // CSA 形式で規定されている項目
    先手持ち時間: RecordMetadataKey.BLACK_TIME_LIMIT,
    後手持ち時間: RecordMetadataKey.WHITE_TIME_LIMIT,
    最大手数: RecordMetadataKey.MAX_MOVES,
    持将棋: RecordMetadataKey.JISHOGI,
};
/**
 * 柿木形式のメタデータのキー名を RecordMetadataKey へ変換します。
 * @param key
 */
export function kakinokiToMetadataKey(key) {
    return metadataKeyMap[key];
}
const metadataNameMap = {
    [RecordMetadataKey.BLACK_NAME]: "先手",
    [RecordMetadataKey.WHITE_NAME]: "後手",
    [RecordMetadataKey.SHITATE_NAME]: "下手",
    [RecordMetadataKey.UWATE_NAME]: "上手",
    [RecordMetadataKey.START_DATETIME]: "開始日時",
    [RecordMetadataKey.END_DATETIME]: "終了日時",
    [RecordMetadataKey.DATE]: "対局日",
    [RecordMetadataKey.TOURNAMENT]: "棋戦",
    [RecordMetadataKey.STRATEGY]: "戦型",
    [RecordMetadataKey.TITLE]: "表題",
    [RecordMetadataKey.TIME_LIMIT]: "持ち時間",
    [RecordMetadataKey.BYOYOMI]: "秒読み",
    [RecordMetadataKey.TIME_SPENT]: "消費時間",
    [RecordMetadataKey.PLACE]: "場所",
    [RecordMetadataKey.POSTED_ON]: "掲載",
    [RecordMetadataKey.NOTE]: "備考",
    [RecordMetadataKey.BLACK_SHORT_NAME]: "先手省略名",
    [RecordMetadataKey.WHITE_SHORT_NAME]: "後手省略名",
    [RecordMetadataKey.SCOREKEEPER]: "記録係",
    [RecordMetadataKey.OPUS_NO]: "作品番号",
    [RecordMetadataKey.OPUS_NAME]: "作品名",
    [RecordMetadataKey.AUTHOR]: "作者",
    [RecordMetadataKey.PUBLISHED_BY]: "発表誌",
    [RecordMetadataKey.PUBLISHED_AT]: "発表年月",
    [RecordMetadataKey.SOURCE]: "出典",
    [RecordMetadataKey.LENGTH]: "手数",
    [RecordMetadataKey.INTEGRITY]: "完全性",
    [RecordMetadataKey.CATEGORY]: "分類",
    [RecordMetadataKey.AWARD]: "受賞",
    // CSA 形式で規定されている項目
    [RecordMetadataKey.BLACK_TIME_LIMIT]: "先手持ち時間",
    [RecordMetadataKey.WHITE_TIME_LIMIT]: "後手持ち時間",
    [RecordMetadataKey.MAX_MOVES]: "最大手数",
    [RecordMetadataKey.JISHOGI]: "持将棋",
};
/**
 * RecordMetadataKey を柿木形式のメタデータのキー名へ変換します。
 * @param key
 */
export function metadataKeyToKakinoki(key) {
    return metadataNameMap[key];
}
var LineType;
(function (LineType) {
    LineType[LineType["PROGRAM_COMMENT"] = 0] = "PROGRAM_COMMENT";
    LineType[LineType["METADATA"] = 1] = "METADATA";
    LineType[LineType["HANDICAP"] = 2] = "HANDICAP";
    LineType[LineType["BLACK_HAND"] = 3] = "BLACK_HAND";
    LineType[LineType["WHITE_HAND"] = 4] = "WHITE_HAND";
    LineType[LineType["BOARD"] = 5] = "BOARD";
    LineType[LineType["BLACK_TURN"] = 6] = "BLACK_TURN";
    LineType[LineType["WHITE_TURN"] = 7] = "WHITE_TURN";
    LineType[LineType["MOVE"] = 8] = "MOVE";
    LineType[LineType["MOVE2"] = 9] = "MOVE2";
    LineType[LineType["BRANCH"] = 10] = "BRANCH";
    LineType[LineType["COMMENT"] = 11] = "COMMENT";
    LineType[LineType["BOOKMARK"] = 12] = "BOOKMARK";
    LineType[LineType["END_OF_GAME"] = 13] = "END_OF_GAME";
    LineType[LineType["UNKNOWN"] = 14] = "UNKNOWN";
})(LineType || (LineType = {}));
const linePatterns = [
    {
        prefix: /^#/,
        type: LineType.PROGRAM_COMMENT,
        removePrefix: false,
        isPosition: false,
    },
    {
        prefix: /^手合割[::]/,
        type: LineType.HANDICAP,
        removePrefix: true,
        isPosition: true,
    },
    {
        prefix: /^(先|下)手の持駒[::]/,
        type: LineType.BLACK_HAND,
        removePrefix: true,
        isPosition: true,
    },
    {
        prefix: /^(後|上)手の持駒[::]/,
        type: LineType.WHITE_HAND,
        removePrefix: true,
        isPosition: true,
    },
    {
        prefix: /^\|/,
        type: LineType.BOARD,
        removePrefix: false,
        isPosition: true,
    },
    {
        prefix: /^(先|下)手番/,
        type: LineType.BLACK_TURN,
        removePrefix: false,
        isPosition: true,
    },
    {
        prefix: /^(後|上)手番/,
        type: LineType.WHITE_TURN,
        removePrefix: false,
        isPosition: true,
    },
    {
        prefix: /^ *[0-9]+ +/,
        type: LineType.MOVE,
        removePrefix: false,
        isPosition: false,
    },
    {
        prefix: /^[ \u3000]*[▲△▼▽☗☖]/,
        type: LineType.MOVE2,
        removePrefix: false,
        isPosition: false,
    },
    {
        prefix: /^[ \u3000]*変化[::][ \u3000]*/,
        type: LineType.BRANCH,
        removePrefix: true,
        isPosition: false,
    },
    {
        prefix: /^\*/,
        type: LineType.COMMENT,
        removePrefix: true,
        isPosition: false,
    },
    {
        prefix: /^&/,
        type: LineType.BOOKMARK,
        removePrefix: true,
        isPosition: false,
    },
    {
        prefix: /^まで、?([0-9]+手で)?/,
        type: LineType.END_OF_GAME,
        removePrefix: true,
        isPosition: false,
    },
];
function parseLine(line) {
    for (let i = 0; i < linePatterns.length; i++) {
        const pattern = linePatterns[i];
        const matched = line.match(pattern.prefix);
        if (matched) {
            const begin = pattern.removePrefix ? matched[0].length : 0;
            return {
                type: pattern.type,
                data: line.substring(begin),
                isPosition: pattern.isPosition,
                metadataKey: "",
            };
        }
    }
    const metadataPrefix = line.match(/^[^ ::]+[::]/);
    if (metadataPrefix) {
        const prefix = metadataPrefix[0];
        return {
            type: LineType.METADATA,
            data: line.substring(prefix.length),
            isPosition: false,
            metadataKey: prefix.substring(0, prefix.length - 1),
        };
    }
    return {
        type: LineType.UNKNOWN,
        data: line,
        isPosition: false,
        metadataKey: "",
    };
}
function readHandicap(position, data) {
    switch (data.trim()) {
        case "平手":
            position.resetBySFEN(InitialPositionSFEN.STANDARD);
            return;
        case "香落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_LANCE);
            return;
        case "右香落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_RIGHT_LANCE);
            return;
        case "角落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_BISHOP);
            return;
        case "飛車落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_ROOK);
            return;
        case "飛香落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_ROOK_LANCE);
            return;
        case "二枚落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_2PIECES);
            return;
        case "四枚落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_4PIECES);
            return;
        case "六枚落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_6PIECES);
            return;
        case "八枚落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_8PIECES);
            return;
        case "十枚落ち":
            position.resetBySFEN(InitialPositionSFEN.HANDICAP_10PIECES);
            return;
        case "その他":
            position.resetBySFEN(InitialPositionSFEN.EMPTY);
            return;
    }
    // マイナビ系のソフトウェアは「手合割:詰将棋」を使用する場合がある。
    // それを含め柿木将棋で規定していない値が使われるケースがしばしばあり、
    // それらに対して適切な処理を判断しようがなく、
    // エラーを返すわけにも行かないためここでは何もしない。
}
const stringToSpecialMoveType = {
    中断: SpecialMoveType.INTERRUPT,
    投了: SpecialMoveType.RESIGN,
    持将棋: SpecialMoveType.IMPASS,
    千日手: SpecialMoveType.REPETITION_DRAW,
    詰み: SpecialMoveType.MATE,
    詰: SpecialMoveType.MATE,
    不詰: SpecialMoveType.NO_MATE,
    切れ負け: SpecialMoveType.TIMEOUT,
    反則勝ち: SpecialMoveType.FOUL_WIN,
    反則負け: SpecialMoveType.FOUL_LOSE,
    入玉勝ち: SpecialMoveType.ENTERING_OF_KING,
    不戦勝: SpecialMoveType.WIN_BY_DEFAULT,
    不戦敗: SpecialMoveType.LOSE_BY_DEFAULT,
};
const moveRegExp = /^ *([0-9]+) +[▲△▼▽]?([123456789][一二三四五六七八九]|同\u3000*)(王|玉|飛|龍|竜|角|馬|金|銀|成銀|全|桂|成桂|圭|香|成香|杏|歩|と)\u3000*(成?)(打|\([1-9][1-9]\)) *([^ ].*|$)/;
const timeRegExp = /\( *([0-9]+):([0-9]+)\/[0-9: ]*\)/;
const specialMoveRegExp = /^ *([0-9]+) +([^ \u3000]+) *([^ ].*|$)/;
const branchRegExp = /^ *([0-9]+)/;
function readBoard(board, data) {
    if (data.length < 21) {
        return new InvalidBoardError(data);
    }
    const rankStr = data[20];
    const rank = stringToNumber(rankStr);
    if (!rank) {
        return new InvalidBoardError(data);
    }
    for (let x = 0; x < 9; x += 1) {
        const file = 9 - x;
        const square = new Square(file, rank);
        const index = x * 2 + 1;
        const pieceStr = data[index + 1];
        const pieceType = stringToPieceType(pieceStr);
        if (!pieceType) {
            board.remove(square);
            continue;
        }
        const color = data[index] !== "v" ? Color.BLACK : Color.WHITE;
        board.set(square, new Piece(color, pieceType));
    }
}
function readHand(hand, data) {
    // NOTE:
    //   スペースで区切られていないものでも Kifu for Windows や ShogiGUI は読み込める。
    //   See: https://github.com/sunfish-shogi/shogihome/issues/572
    const sections = data.split(/[  ]/);
    for (const section of sections) {
        if (!section || section === "なし") {
            continue;
        }
        const pieceStr = section[0];
        const numberStr = section.substring(1);
        const pieceType = stringToPieceType(pieceStr);
        const n = stringToNumber(numberStr) || 1;
        if (!pieceType) {
            return new InvalidHandPieceError(section);
        }
        hand.add(pieceType, n);
    }
    return;
}
function readMoveTime(record, data) {
    const timeResult = timeRegExp.exec(data);
    if (timeResult) {
        const minutes = timeResult[1];
        const seconds = timeResult[2];
        const s = Number.parseInt(minutes) * 60 + Number.parseInt(seconds);
        record.current.setElapsedMs(s * 1e3);
    }
}
function readMove(record, data) {
    const result = readRegularMove(record, data);
    if (result instanceof Error) {
        return result;
    }
    else if (result) {
        return;
    }
    if (readSpecialMove(record, data)) {
        return;
    }
    return new InvalidMoveError(data);
}
function readRegularMove(record, data) {
    const result = moveRegExp.exec(data);
    if (!result) {
        return false;
    }
    const num = Number(result[1]);
    const toStr = result[2];
    const pieceTypeStr = result[3];
    const promStr = result[4];
    const fromStr = result[5];
    const time = result[6];
    if (num === 0) {
        return new InvalidMoveNumberError(data);
    }
    record.goto(num - 1);
    let to;
    let from;
    if (toStr.startsWith("同")) {
        if (!(record.current.move instanceof Move)) {
            return new InvalidDestinationError(data);
        }
        to = record.current.move.to;
    }
    else {
        const file = stringToNumber(toStr[0]);
        const rank = stringToNumber(toStr[1]);
        to = new Square(file, rank);
    }
    if (fromStr === "打") {
        from = stringToPieceType(pieceTypeStr);
    }
    else {
        const file = stringToNumber(fromStr[1]);
        const rank = stringToNumber(fromStr[2]);
        from = new Square(file, rank);
    }
    let move = record.position.createMove(from, to);
    if (!move) {
        return new InvalidMoveError(data);
    }
    if (promStr === "成") {
        move = move.withPromote();
    }
    record.append(move, {
        ignoreValidation: true,
    });
    readMoveTime(record, time);
    return true;
}
function readSpecialMove(record, data) {
    const result = specialMoveRegExp.exec(data);
    if (!result) {
        return false;
    }
    const num = Number(result[1]);
    const type = stringToSpecialMoveType[result[2]];
    const time = result[3];
    record.goto(num - 1);
    let move;
    if (type) {
        move = specialMove(type);
    }
    else {
        move = anySpecialMove(result[2]);
    }
    record.append(move, {
        ignoreValidation: true,
    });
    readMoveTime(record, time);
    return true;
}
function readMove2(record, data) {
    const lastMove = record.current.move instanceof Move ? record.current.move : undefined;
    const [moves, e] = parseMoves(record.position, data, lastMove);
    if (e) {
        return e;
    }
    for (const move of moves) {
        record.append(move, { ignoreValidation: true });
    }
}
function readBranch(record, data) {
    const result = branchRegExp.exec(data);
    if (!result) {
        return new InvalidMoveNumberError(data);
    }
    const num = Number(result[1]);
    if (num === 0 || num > record.current.ply + 1) {
        return new InvalidMoveNumberError(data);
    }
    record.goto(num - 1);
}
function readEndOfGame(record, data) {
    const clean = data.replaceAll(/[\s\u3000]/g, "");
    // NOTE: 末尾 "勝ち" は "時間切れにより...の勝ち" "反則勝ち" ともマッチするので最後に判定する必要がある。
    if (clean.startsWith("時間切れ")) {
        record.append(specialMove(SpecialMoveType.TIMEOUT));
    }
    else if (clean.endsWith("反則勝ち")) {
        record.append(specialMove(SpecialMoveType.FOUL_WIN));
    }
    else if (clean.endsWith("反則負け")) {
        record.append(specialMove(SpecialMoveType.FOUL_LOSE));
    }
    else if (clean.endsWith("入玉勝ち")) {
        record.append(specialMove(SpecialMoveType.ENTERING_OF_KING));
    }
    else if (clean.endsWith("勝ち")) {
        record.append(specialMove(SpecialMoveType.RESIGN));
    }
    else {
        const type = stringToSpecialMoveType[clean];
        if (type) {
            record.append(specialMove(type));
        }
        else {
            record.append(anySpecialMove(clean));
        }
    }
}
/**
 * KIF 形式の文字列を読み込みます。
 * @param data
 */
export function importKIF(data) {
    return importKakinoki(data, KakinokiFormatType.KIF);
}
/**
 * KI2 形式の文字列を読み込みます。
 * @param data
 */
export function importKI2(data) {
    return importKakinoki(data, KakinokiFormatType.KI2);
}
function importKakinoki(data, formatType) {
    const metadata = new RecordMetadata();
    const record = new Record();
    const lines = data.split(/\r?\n/);
    const position = new Position();
    let preMoveComment = "";
    let preMoveBookmark = "";
    let isMoveSection = false;
    const startMoveSectionIfNot = () => {
        if (isMoveSection) {
            return;
        }
        record.clear(position);
        record.first.comment = preMoveComment;
        record.first.bookmark = preMoveBookmark;
        isMoveSection = true;
    };
    for (const line of lines) {
        if (line === "") {
            continue;
        }
        const parsed = parseLine(line);
        if (isMoveSection && parsed.isPosition) {
            return new InvalidLineError(line);
        }
        let e;
        switch (parsed.type) {
            case LineType.METADATA: {
                const standardKey = metadataKeyMap[parsed.metadataKey];
                if (standardKey) {
                    metadata.setStandardMetadata(standardKey, parsed.data);
                }
                else {
                    metadata.setCustomMetadata(parsed.metadataKey, parsed.data);
                }
                break;
            }
            case LineType.HANDICAP:
                readHandicap(position, parsed.data);
                break;
            case LineType.BLACK_HAND:
                e = readHand(position.blackHand, parsed.data);
                break;
            case LineType.WHITE_HAND:
                e = readHand(position.whiteHand, parsed.data);
                break;
            case LineType.BOARD:
                e = readBoard(position.board, parsed.data);
                break;
            case LineType.BLACK_TURN:
                position.setColor(Color.BLACK);
                break;
            case LineType.WHITE_TURN:
                position.setColor(Color.WHITE);
                break;
            case LineType.MOVE:
                if (formatType !== KakinokiFormatType.KIF) {
                    return new InvalidLineError(line);
                }
                startMoveSectionIfNot();
                e = readMove(record, parsed.data);
                break;
            case LineType.MOVE2:
                if (formatType !== KakinokiFormatType.KI2) {
                    return new InvalidLineError(line);
                }
                startMoveSectionIfNot();
                e = readMove2(record, parsed.data);
                break;
            case LineType.BRANCH:
                // NOTE:
                //   KIF では指し手の先頭に手数が付与されるので必要ない。
                //   https://github.com/sunfish-shogi/shogihome/issues/570
                //   の不具合により、ヘッダー部に "変化:" で始まる行が存在する場合がある。
                //   指し手が始まるより前に "変化:" が出現しても無視しなければならない。
                if (isMoveSection && formatType === KakinokiFormatType.KI2) {
                    e = readBranch(record, parsed.data);
                }
                break;
            case LineType.COMMENT:
                if (isMoveSection) {
                    record.current.comment = appendLine(record.current.comment, parsed.data);
                }
                else {
                    preMoveComment = appendLine(preMoveComment, parsed.data);
                }
                break;
            case LineType.BOOKMARK:
                if (isMoveSection) {
                    record.current.bookmark = parsed.data;
                }
                else {
                    preMoveBookmark = parsed.data;
                }
                break;
            case LineType.END_OF_GAME:
                // NOTE:
                //   KI2 では "までn手で" で始まる行から終局理由を読み取らなければいけない。
                //   KIF では指し手の一つとしても記載されるので必要ない。
                if (formatType === KakinokiFormatType.KI2) {
                    startMoveSectionIfNot();
                    readEndOfGame(record, parsed.data);
                }
                break;
            case LineType.PROGRAM_COMMENT:
                break;
            case LineType.UNKNOWN:
                break;
        }
        if (e) {
            return e;
        }
    }
    startMoveSectionIfNot();
    record.goto(0);
    record.resetAllBranchSelection();
    record.metadata = metadata;
    return record;
}
const specialMoveToString = {
    [SpecialMoveType.START]: "",
    [SpecialMoveType.RESIGN]: "投了",
    [SpecialMoveType.INTERRUPT]: "中断",
    [SpecialMoveType.MAX_MOVES]: "持将棋",
    [SpecialMoveType.IMPASS]: "持将棋",
    [SpecialMoveType.DRAW]: "持将棋",
    [SpecialMoveType.REPETITION_DRAW]: "千日手",
    [SpecialMoveType.MATE]: "詰み",
    [SpecialMoveType.NO_MATE]: "不詰",
    [SpecialMoveType.TIMEOUT]: "切れ負け",
    [SpecialMoveType.FOUL_WIN]: "反則勝ち",
    [SpecialMoveType.FOUL_LOSE]: "反則負け",
    [SpecialMoveType.ENTERING_OF_KING]: "入玉勝ち",
    [SpecialMoveType.WIN_BY_DEFAULT]: "不戦勝",
    [SpecialMoveType.LOSE_BY_DEFAULT]: "不戦敗",
    [SpecialMoveType.TRY]: "トライ",
};
function formatMetadata(metadata, options) {
    let ret = "";
    const returnCode = options?.returnCode || "\n";
    for (const key of metadata.standardMetadataKeys) {
        ret += metadataNameMap[key] + ":" + metadata.getStandardMetadata(key) + returnCode;
    }
    for (const key of metadata.customMetadataKeys) {
        ret += key + ":" + metadata.getCustomMetadata(key) + returnCode;
    }
    return ret;
}
function formatPosition(position, options) {
    const returnCode = options?.returnCode || "\n";
    switch (position.sfen) {
        case InitialPositionSFEN.STANDARD:
            return "手合割:平手" + returnCode;
        case InitialPositionSFEN.HANDICAP_LANCE:
            return "手合割:香落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_RIGHT_LANCE:
            return "手合割:右香落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_BISHOP:
            return "手合割:角落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_ROOK:
            return "手合割:飛車落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_ROOK_LANCE:
            return "手合割:飛香落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_2PIECES:
            return "手合割:二枚落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_4PIECES:
            return "手合割:四枚落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_6PIECES:
            return "手合割:六枚落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_8PIECES:
            return "手合割:八枚落ち" + returnCode;
        case InitialPositionSFEN.HANDICAP_10PIECES:
            return "手合割:十枚落ち" + returnCode;
    }
    return formatBOD(position, options);
}
function formatBOD(position, options) {
    const returnCode = options?.returnCode || "\n";
    let ret = "";
    ret += "後手の持駒:" + formatHand(position.whiteHand) + returnCode;
    ret += "  9 8 7 6 5 4 3 2 1" + returnCode;
    ret += "+---------------------------+" + returnCode;
    for (let y = 0; y < 9; y++) {
        ret += "|";
        for (let x = 0; x < 9; x++) {
            const square = Square.newByXY(x, y);
            const piece = position.board.at(square);
            if (!piece) {
                ret += " ・";
            }
            else if (piece.color === Color.BLACK) {
                ret += " " + pieceTypeToStringForBoard(piece.type);
            }
            else {
                ret += "v" + pieceTypeToStringForBoard(piece.type);
            }
        }
        ret += "|" + rankToKanji(y + 1) + returnCode;
    }
    ret += "+---------------------------+" + returnCode;
    ret += "先手の持駒:" + formatHand(position.blackHand) + returnCode;
    if (position.color === Color.BLACK) {
        ret += "先手番" + returnCode;
    }
    else {
        ret += "後手番" + returnCode;
    }
    return ret;
}
/**
 * KIF 形式の指し手を出力します。
 * @param move 対象の指し手
 * @param prev 直前の指し手 ("同"の判定に使用)
 */
export function formatKIFMove(move, options) {
    let ret = "";
    if (options?.prev && move.to.equals(options.prev.to)) {
        ret += "同\u3000";
    }
    else {
        ret += fileToMultiByteChar(move.to.file);
        ret += rankToKanji(move.to.rank);
    }
    ret += pieceTypeToStringForMove(move.pieceType);
    if (move.promote) {
        ret += "成";
    }
    if (move.from instanceof Square) {
        ret += "(" + move.from.file + move.from.rank + ")";
        ret += ret.length === 7 && options?.padding ? "  " : "";
    }
    else {
        ret += "打";
        ret += options?.padding ? "    " : "";
    }
    return ret;
}
function formatHand(hand) {
    let ret = "";
    hand.forEach((pieceType, n) => {
        if (n >= 1) {
            ret += pieceTypeToStringForBoard(pieceType);
            if (n >= 2) {
                ret += numberToKanji(n);
            }
            ret += " ";
        }
    });
    if (ret === "") {
        ret = "なし";
    }
    return ret;
}
/**
 * KIF形式の文字列を出力します。
 * @param record
 * @param options
 */
export function exportKIF(record, options) {
    let ret = "";
    const returnCode = options?.returnCode || "\n";
    if (options?.comment) {
        for (const line of options.comment.split("\n")) {
            ret += "#" + line + returnCode;
        }
    }
    ret += formatMetadata(record.metadata, options);
    ret += formatPosition(record.initialPosition, options);
    ret += "手数----指手---------消費時間--" + returnCode;
    record.forEach((node) => {
        if (node.ply !== 0) {
            if (!node.isFirstBranch) {
                ret += returnCode;
                ret += "変化:" + node.ply + "手" + returnCode;
            }
            ret += String(node.ply).padStart(4, " ") + " ";
            if (node.move instanceof Move) {
                const prev = node.prev?.move instanceof Move ? node.prev.move : undefined;
                ret += formatKIFMove(node.move, { prev, padding: true });
            }
            else if (isKnownSpecialMove(node.move)) {
                const s = specialMoveToString[node.move.type];
                ret += s + " ".repeat(Math.max(12 - s.length * 2, 0));
            }
            else {
                ret += node.move.name + " ".repeat(Math.max(12 - node.move.name.length * 2, 0));
            }
            const elapsed = millisecondsToMSS(node.elapsedMs);
            const totalElapsed = millisecondsToHHMMSS(node.totalElapsedMs);
            ret += ` (${elapsed}/${totalElapsed})`;
            if (node.branch) {
                // Kifu for Windows にならい、後続の分岐が存在する場合は行末に "+" を付ける。
                ret += "+";
            }
            ret += returnCode;
        }
        if (node.comment.length !== 0) {
            const comment = node.comment.endsWith("\n") ? node.comment.slice(0, -1) : node.comment;
            ret += "*" + comment.replaceAll("\n", returnCode + "*") + returnCode;
        }
        if (node.bookmark.length !== 0) {
            ret += "&" + node.bookmark + returnCode;
        }
    });
    return ret;
}
/**
 * KI2形式の文字列を出力します。
 * @param record
 * @param options
 */
export function exportKI2(record, options) {
    let ret = "";
    let moveCountInLine = 0;
    let lastMoveLength = 0;
    const returnCode = options?.returnCode ? options.returnCode : "\n";
    ret += formatMetadata(record.metadata, options);
    ret += formatPosition(record.initialPosition, options);
    record.forEach((node) => {
        if (node.prev) {
            if (!node.isFirstBranch) {
                if (!ret.endsWith(returnCode)) {
                    ret += returnCode;
                }
                ret += returnCode;
                ret += "変化:" + node.ply + "手" + returnCode;
            }
            if (node.move instanceof Move) {
                const pos = Position.newBySFEN(node.prev.sfen);
                if (!pos) {
                    throw new Error("Invalid SFEN");
                }
                const str = formatMove(pos, node.move, {
                    lastMove: node.prev?.move instanceof Move ? node.prev.move : undefined,
                    compatible: true,
                });
                if (ret.endsWith(returnCode)) {
                    moveCountInLine = 0;
                }
                else {
                    ret += " ".repeat(Math.max(12 - lastMoveLength * 2, 0));
                }
                ret += str;
                lastMoveLength = str.length;
                moveCountInLine++;
                if (moveCountInLine >= 6) {
                    ret += returnCode;
                }
            }
            else {
                if (!ret.endsWith(returnCode)) {
                    ret += returnCode;
                }
                ret += `まで${node.ply - 1}手で`;
                if (isKnownSpecialMove(node.move)) {
                    const [next, last] = node.nextColor === Color.BLACK ? ["先手", "後手"] : ["後手", "先手"];
                    switch (node.move.type) {
                        case SpecialMoveType.RESIGN:
                            ret += `${last}の勝ち`;
                            break;
                        case SpecialMoveType.TIMEOUT:
                            ret += `時間切れにより${last}の勝ち`;
                            break;
                        case SpecialMoveType.ENTERING_OF_KING:
                            ret += `${next}の入玉勝ち`;
                            break;
                        case SpecialMoveType.FOUL_WIN:
                            ret += `${next}の反則勝ち`;
                            break;
                        case SpecialMoveType.FOUL_LOSE:
                            ret += `${next}の反則負け`;
                            break;
                        default:
                            ret += specialMoveToString[node.move.type];
                            break;
                    }
                }
                else {
                    ret += node.move.name;
                }
                ret += returnCode;
            }
        }
        if (node.comment.length !== 0) {
            if (!ret.endsWith(returnCode)) {
                ret += returnCode;
            }
            const comment = node.comment.endsWith("\n") ? node.comment.slice(0, -1) : node.comment;
            ret += "*" + comment.replaceAll("\n", returnCode + "*") + returnCode;
        }
        if (node.bookmark.length !== 0) {
            if (!ret.endsWith(returnCode)) {
                ret += returnCode;
            }
            ret += "&" + node.bookmark + returnCode;
        }
    });
    return ret;
}
export function exportBOD(record, options) {
    let ret = "";
    const returnCode = options?.returnCode || "\n";
    ret += formatBOD(record.position, options);
    const ply = record.current.ply;
    const lastMove = record.current.move instanceof Move ? record.current.move : undefined;
    const lastMoveStr = lastMove ? formatKIFMove(lastMove) : "";
    ret += `手数=${ply}  ${lastMoveStr}  まで` + returnCode;
    return ret;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2FraW5va2kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMva2FraW5va2kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0NBQWtDO0FBQ2xDLCtDQUErQztBQUUvQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFekUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNoQyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLHVCQUF1QixFQUN2QixxQkFBcUIsRUFDckIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixzQkFBc0IsR0FDdkIsTUFBTSxVQUFVLENBQUM7QUFFbEIsT0FBTyxFQUNMLElBQUksRUFFSixlQUFlLEVBQ2YsY0FBYyxFQUNkLGtCQUFrQixFQUNsQixXQUFXLEdBQ1osTUFBTSxRQUFRLENBQUM7QUFDaEIsT0FBTyxFQUFFLEtBQUssRUFBYSxNQUFNLFNBQVMsQ0FBQztBQUMzQyxPQUFPLEVBQXFCLG1CQUFtQixFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM5RSxPQUFPLEVBR0wsTUFBTSxFQUNOLGNBQWMsRUFDZCxpQkFBaUIsR0FDbEIsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLFVBQVUsRUFDVixhQUFhLEVBQ2IsVUFBVSxFQUNWLHlCQUF5QixFQUN6Qix3QkFBd0IsRUFDeEIsV0FBVyxFQUNYLGNBQWMsRUFDZCxpQkFBaUIsR0FDbEIsTUFBTSxRQUFRLENBQUM7QUFFaEIsTUFBTSxDQUFOLElBQVksa0JBR1g7QUFIRCxXQUFZLGtCQUFrQjtJQUM1QixpQ0FBVyxDQUFBO0lBQ1gsaUNBQVcsQ0FBQTtBQUNiLENBQUMsRUFIVyxrQkFBa0Is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