UNPKG

tsshogi

Version:

TypeScript library for Shogi (Japanese chess)

463 lines 35.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.stringToNumber = stringToNumber; exports.stringToPieceType = stringToPieceType; exports.numberToKanji = numberToKanji; exports.fileToMultiByteChar = fileToMultiByteChar; exports.rankToKanji = rankToKanji; exports.pieceTypeToStringForMove = pieceTypeToStringForMove; exports.pieceTypeToStringForBoard = pieceTypeToStringForBoard; exports.formatSpecialMove = formatSpecialMove; exports.getDirectionModifier = getDirectionModifier; exports.formatMove = formatMove; exports.formatPV = formatPV; exports.parsePV = parsePV; exports.parseMoves = parseMoves; const color_1 = require("./color.cjs"); const direction_1 = require("./direction.cjs"); const errors_1 = require("./errors.cjs"); const move_1 = require("./move.cjs"); const piece_1 = require("./piece.cjs"); const position_1 = require("./position.cjs"); const square_1 = require("./square.cjs"); const stringToNumberMap = { "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, 一: 1, 二: 2, 三: 3, 四: 4, 五: 5, 六: 6, 七: 7, 八: 8, 九: 9, 十: 10, 十一: 11, 十二: 12, 十三: 13, 十四: 14, 十五: 15, 十六: 16, 十七: 17, 十八: 18, }; const stringToPieceTypeMap = { 王: piece_1.PieceType.KING, 玉: piece_1.PieceType.KING, 飛: piece_1.PieceType.ROOK, 龍: piece_1.PieceType.DRAGON, 竜: piece_1.PieceType.DRAGON, 角: piece_1.PieceType.BISHOP, 馬: piece_1.PieceType.HORSE, 金: piece_1.PieceType.GOLD, 銀: piece_1.PieceType.SILVER, 成銀: piece_1.PieceType.PROM_SILVER, 全: piece_1.PieceType.PROM_SILVER, 桂: piece_1.PieceType.KNIGHT, 成桂: piece_1.PieceType.PROM_KNIGHT, 圭: piece_1.PieceType.PROM_KNIGHT, 香: piece_1.PieceType.LANCE, 成香: piece_1.PieceType.PROM_LANCE, 杏: piece_1.PieceType.PROM_LANCE, 歩: piece_1.PieceType.PAWN, と: piece_1.PieceType.PROM_PAWN, }; function stringToNumber(s) { return stringToNumberMap[s]; } function stringToPieceType(piece) { return stringToPieceTypeMap[piece]; } const kanjiNumberStrings = [ "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", ]; const fileStrings = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]; function numberToKanji(n) { return kanjiNumberStrings[n - 1]; } function fileToMultiByteChar(file) { return fileStrings[file - 1]; } function rankToKanji(rank) { return kanjiNumberStrings[rank - 1]; } const pieceTypeToStringForMoveMap = { king: "玉", rook: "飛", dragon: "龍", bishop: "角", horse: "馬", gold: "金", silver: "銀", promSilver: "成銀", knight: "桂", promKnight: "成桂", lance: "香", promLance: "成香", pawn: "歩", promPawn: "と", }; function pieceTypeToStringForMove(pieceType) { return pieceTypeToStringForMoveMap[pieceType]; } const pieceTypeToStringForBoardMap = { king: "玉", rook: "飛", dragon: "龍", bishop: "角", horse: "馬", gold: "金", silver: "銀", promSilver: "全", knight: "桂", promKnight: "圭", lance: "香", promLance: "杏", pawn: "歩", promPawn: "と", }; function pieceTypeToStringForBoard(pieceType) { return pieceTypeToStringForBoardMap[pieceType]; } const specialMoveToDisplayStringMap = { [move_1.SpecialMoveType.START]: "開始局面", [move_1.SpecialMoveType.RESIGN]: "投了", [move_1.SpecialMoveType.INTERRUPT]: "中断", [move_1.SpecialMoveType.MAX_MOVES]: "最大手数", [move_1.SpecialMoveType.IMPASS]: "持将棋", [move_1.SpecialMoveType.DRAW]: "引き分け", [move_1.SpecialMoveType.REPETITION_DRAW]: "千日手", [move_1.SpecialMoveType.MATE]: "詰み", [move_1.SpecialMoveType.NO_MATE]: "不詰", [move_1.SpecialMoveType.TIMEOUT]: "切れ負け", [move_1.SpecialMoveType.FOUL_WIN]: "反則勝ち", [move_1.SpecialMoveType.FOUL_LOSE]: "反則負け", [move_1.SpecialMoveType.ENTERING_OF_KING]: "入玉", [move_1.SpecialMoveType.WIN_BY_DEFAULT]: "不戦勝", [move_1.SpecialMoveType.LOSE_BY_DEFAULT]: "不戦敗", [move_1.SpecialMoveType.TRY]: "トライ", }; /** * 特殊な指し手の表示用の文字列を返します。 * @param move */ function formatSpecialMove(move) { if (typeof move === "string") { return specialMoveToDisplayStringMap[move]; } if ((0, move_1.isKnownSpecialMove)(move)) { return specialMoveToDisplayStringMap[move.type]; } return move.name; } /** * 「上」や「引」など指し手の移動方向を修飾する文字列を返します。 * @param move * @param position */ function getDirectionModifier(move, position) { const piece = new piece_1.Piece(move.color, move.pieceType); // 同じマス目へ移動可能な同種の駒を列挙 const others = position.listAttackersByPiece(move.to, piece).filter((square) => { return !(move.from instanceof square_1.Square) || !square.equals(move.from); }); // 移動可能な同じ駒がある場合に移動元を区別する文字を付ける。 if (move.from instanceof square_1.Square) { let ret = ""; // この指し手の移動方向 let myDir = move.from.directionTo(move.to); myDir = move.color === color_1.Color.BLACK ? myDir : (0, direction_1.reverseDirection)(myDir); const myVDir = (0, direction_1.directionToVDirection)(myDir); const myHDir = (0, direction_1.directionToHDirection)(myDir); // 他の駒の移動方向 const otherDirs = others.map((square) => { const dir = square.directionTo(move.to); return move.color === color_1.Color.BLACK ? dir : (0, direction_1.reverseDirection)(dir); }); // 水平方向がこの指し手と同じものを列挙して、その垂直方向を保持する。 const vDirections = otherDirs .filter((dir) => (0, direction_1.directionToHDirection)(dir) == myHDir) .map((dir) => (0, direction_1.directionToVDirection)(dir)); // 垂直方向がこの指し手と同じものを列挙して、その水平方向を保持する。 const hDirections = otherDirs .filter((dir) => (0, direction_1.directionToVDirection)(dir) == myVDir) .map((dir) => (0, direction_1.directionToHDirection)(dir)); // 水平方向で区別すべき駒がある場合 let noVertical = false; if (hDirections.length) { if (move.pieceType === piece_1.PieceType.HORSE || move.pieceType === piece_1.PieceType.DRAGON) { // 竜や馬の場合は2枚しかないので「直」は使わない。 if (myHDir === direction_1.HDirection.LEFT || (myHDir === direction_1.HDirection.NONE && hDirections[0] === direction_1.HDirection.RIGHT)) { ret += "右"; } else if (myHDir === direction_1.HDirection.RIGHT || (myHDir === direction_1.HDirection.NONE && hDirections[0] === direction_1.HDirection.LEFT)) { ret += "左"; } } else { switch (myHDir) { case direction_1.HDirection.LEFT: ret += "右"; break; case direction_1.HDirection.NONE: ret += "直"; // 後ろへ3方向移動できてなおかつ3枚以上ある駒は存在しないため「直」と垂直方向の区別は同時に使用しない。 noVertical = true; break; case direction_1.HDirection.RIGHT: ret += "左"; break; } } } // 垂直方向で区別すべき駒がある場合 if (!noVertical && (vDirections.length || (!hDirections.length && others.length))) { switch (myVDir) { case direction_1.VDirection.DOWN: ret += "引"; break; case direction_1.VDirection.NONE: ret += "寄"; break; case direction_1.VDirection.UP: ret += "上"; break; } } return ret; } else if (others.length) { // 盤上に移動可能な同じ駒がある場合は、駒台から打つことを明示する。 return "打"; } return ""; } /** * 指し手を表す文字列を返します。 * @param position 指し手の直前の局面 * @param move 対象の指し手 */ function formatMove(position, move, opt) { let ret = ""; // 手番を表す記号を付与する。 switch (move.color) { case color_1.Color.BLACK: ret += opt?.compatible ? "▲" : "☗"; break; case color_1.Color.WHITE: ret += opt?.compatible ? "△" : "☖"; break; } // 移動先の筋・段を付与する。 if (opt?.lastMove && opt.lastMove.to.equals(move.to)) { ret += "同 "; } else { ret += fileToMultiByteChar(move.to.file); ret += rankToKanji(move.to.rank); } ret += pieceTypeToStringForMove(move.pieceType); ret += getDirectionModifier(move, position); if (move.from instanceof square_1.Square) { // 「成」または「不成」を付ける。 if (move.promote) { ret += "成"; } else if (move.from instanceof square_1.Square && (0, piece_1.isPromotable)(move.pieceType) && ((0, position_1.isPromotableRank)(move.color, move.from.rank) || (0, position_1.isPromotableRank)(move.color, move.to.rank))) { ret += "不成"; } } return ret; } function formatPV(position, pv) { let ret = ""; let lastMove; const p = position.clone(); for (const move of pv) { ret += `${formatMove(p, move, { lastMove, compatible: true, })}`; p.doMove(move, { ignoreValidation: true }); lastMove = move; } return ret; } const moveRegExp = /^[▲△▼▽☗☖]?([123456789一二三四五六七八九1-9]{2}|同)(王|玉|飛|龍|竜|角|馬|金|銀|成銀|全|桂|成桂|圭|香|成香|杏|歩|と)(左|直|右|)(引|寄|上|)(成|不成|打|)(\([1-9][1-9]\)|)/; function parsePV(position, text) { return parseMoves(position, text)[0]; } /** * テキストから指し手を読み込みます。 KI2 と互換性があります。 * @param position 指し手の直前の局面 * @param text 対象の文字列 * @param lastMove 直前の指し手(1 手目が "同" を使った表記の場合に使用する。) */ function parseMoves(position, text, lastMove) { const clean = text.replaceAll(/[\s\u3000]/g, ""); // 1手ずつ分割する。 const sections = []; let lastIndex = 0; for (let i = 1; i <= clean.length; i++) { const char = clean[i]; if (!char || char === "▲" || char === "△" || char === "▼" || char === "▽" || char === "☗" || char === "☖") { sections.push(clean.substring(lastIndex, i)); lastIndex = i; } } // 指し手を読み込む。 const p = position.clone(); const pv = []; for (const section of sections) { const result = moveRegExp.exec(section); if (!result) { return [pv, new errors_1.InvalidMoveError(section)]; } const toStr = result[1]; const pieceType = stringToPieceType(result[2]); const horStr = result[3]; const verStr = result[4]; const promOrDropStr = result[5]; const fromStr = result[6]; // 古い表記の場合のみ let to; if (toStr.startsWith("同")) { if (pv.length > 0) { to = pv[pv.length - 1].to; } else if (lastMove) { to = lastMove.to; } else { return [pv, new errors_1.InvalidMoveError(section)]; } } else { const file = stringToNumber(toStr[0]); const rank = stringToNumber(toStr[1]); to = new square_1.Square(file, rank); } let from; if (promOrDropStr === "打") { from = pieceType; } else if (fromStr) { const file = stringToNumber(fromStr[1]); const rank = stringToNumber(fromStr[2]); from = new square_1.Square(file, rank); } else { let squares = p.listAttackersByPiece(to, new piece_1.Piece(p.color, pieceType)).filter((square) => { let dir = square.directionTo(to); dir = p.color === color_1.Color.BLACK ? dir : (0, direction_1.reverseDirection)(dir); const vDir = (0, direction_1.directionToVDirection)(dir); const hDir = (0, direction_1.directionToHDirection)(dir); if (verStr.indexOf("引") >= 0 && vDir !== direction_1.VDirection.DOWN) { return false; } if (verStr.indexOf("寄") >= 0 && vDir !== direction_1.VDirection.NONE) { return false; } if ((verStr.indexOf("上") >= 0 || verStr.indexOf("行") >= 0) && vDir !== direction_1.VDirection.UP) { return false; } if (horStr.indexOf("直") >= 0 && (hDir !== direction_1.HDirection.NONE || vDir !== direction_1.VDirection.UP)) { return false; } if (pieceType === piece_1.PieceType.HORSE || pieceType === piece_1.PieceType.DRAGON) { // 馬や龍の場合は "左" や "右" でも真っ直ぐ進む場合があるので明らかに違うものだけを除外する。 if (horStr.indexOf("左") >= 0 && hDir === direction_1.HDirection.LEFT) { return false; } if (horStr.indexOf("右") >= 0 && hDir === direction_1.HDirection.RIGHT) { return false; } } else { if (horStr.indexOf("左") >= 0 && hDir !== direction_1.HDirection.RIGHT) { return false; } if (horStr.indexOf("右") >= 0 && hDir !== direction_1.HDirection.LEFT) { return false; } } return true; }); if (squares.length === 2 && (pieceType === piece_1.PieceType.HORSE || pieceType === piece_1.PieceType.DRAGON)) { // 馬や龍で "左" や "右" が使われ、 1 つに絞れなかった場合は真っ直ぐ進むものを除外する。 squares = squares.filter((square) => { let dir = square.directionTo(to); dir = p.color === color_1.Color.BLACK ? dir : (0, direction_1.reverseDirection)(dir); const hDir = (0, direction_1.directionToHDirection)(dir); return hDir !== direction_1.HDirection.NONE; }); } if (squares.length === 1) { from = squares[0]; } else if (squares.length === 0 && p.hand(p.color).count(pieceType) !== 0) { from = pieceType; } else { return [pv, new errors_1.InvalidMoveError(section)]; } } let move = p.createMove(from, to); if (!move) { return [pv, new errors_1.InvalidMoveError(section)]; } if (promOrDropStr === "成") { move = move.withPromote(); } if (!p.doMove(move, { ignoreValidation: true })) { return [pv, new errors_1.InvalidMoveError(section)]; } pv.push(move); } return [pv, undefined]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkVBLHdDQUVDO0FBRUQsOENBRUM7QUF3QkQsc0NBRUM7QUFFRCxrREFFQztBQUVELGtDQUVDO0FBcUJELDREQUVDO0FBcUJELDhEQUVDO0FBMkJELDhDQVFDO0FBT0Qsb0RBaUZDO0FBT0QsZ0NBMkNDO0FBRUQsNEJBYUM7QUFLRCwwQkFFQztBQVFELGdDQW1JQztBQS9lRCxtQ0FBZ0M7QUFDaEMsMkNBTXFCO0FBQ3JCLHFDQUE0QztBQUM1QyxpQ0FBZ0Y7QUFDaEYsbUNBQXlEO0FBQ3pELHlDQUFpRTtBQUNqRSxxQ0FBa0M7QUFFbEMsTUFBTSxpQkFBaUIsR0FBNEI7SUFDakQsR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMsRUFBRSxDQUFDO0lBQ0osQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMsRUFBRSxDQUFDO0lBQ0osQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMs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