UNPKG

tsshogi

Version:

TypeScript library for Shogi (Japanese chess)

454 lines 34.8 kB
import { Color } from "./color.mjs"; import { HDirection, VDirection, directionToHDirection, directionToVDirection, reverseDirection, } from "./direction.mjs"; import { InvalidMoveError } from "./errors.mjs"; import { SpecialMoveType, isKnownSpecialMove } from "./move.mjs"; import { PieceType, Piece, isPromotable } from "./piece.mjs"; import { isPromotableRank } from "./position.mjs"; import { Square } from "./square.mjs"; 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 = { 王: PieceType.KING, 玉: PieceType.KING, 飛: PieceType.ROOK, 龍: PieceType.DRAGON, 竜: PieceType.DRAGON, 角: PieceType.BISHOP, 馬: PieceType.HORSE, 金: PieceType.GOLD, 銀: PieceType.SILVER, 成銀: PieceType.PROM_SILVER, 全: PieceType.PROM_SILVER, 桂: PieceType.KNIGHT, 成桂: PieceType.PROM_KNIGHT, 圭: PieceType.PROM_KNIGHT, 香: PieceType.LANCE, 成香: PieceType.PROM_LANCE, 杏: PieceType.PROM_LANCE, 歩: PieceType.PAWN, と: PieceType.PROM_PAWN, }; export function stringToNumber(s) { return stringToNumberMap[s]; } export function stringToPieceType(piece) { return stringToPieceTypeMap[piece]; } const kanjiNumberStrings = [ "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", ]; const fileStrings = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]; export function numberToKanji(n) { return kanjiNumberStrings[n - 1]; } export function fileToMultiByteChar(file) { return fileStrings[file - 1]; } export function rankToKanji(rank) { return kanjiNumberStrings[rank - 1]; } const pieceTypeToStringForMoveMap = { king: "玉", rook: "飛", dragon: "龍", bishop: "角", horse: "馬", gold: "金", silver: "銀", promSilver: "成銀", knight: "桂", promKnight: "成桂", lance: "香", promLance: "成香", pawn: "歩", promPawn: "と", }; export function pieceTypeToStringForMove(pieceType) { return pieceTypeToStringForMoveMap[pieceType]; } const pieceTypeToStringForBoardMap = { king: "玉", rook: "飛", dragon: "龍", bishop: "角", horse: "馬", gold: "金", silver: "銀", promSilver: "全", knight: "桂", promKnight: "圭", lance: "香", promLance: "杏", pawn: "歩", promPawn: "と", }; export function pieceTypeToStringForBoard(pieceType) { return pieceTypeToStringForBoardMap[pieceType]; } const specialMoveToDisplayStringMap = { [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]: "トライ", }; /** * 特殊な指し手の表示用の文字列を返します。 * @param move */ export function formatSpecialMove(move, color) { if (typeof move !== "string" && !isKnownSpecialMove(move)) { return move.name; } const moveType = typeof move === "string" ? move : move.type; if (color !== undefined) { if (moveType === SpecialMoveType.FOUL_LOSE) { return color === Color.BLACK ? "先手の反則負け" : "後手の反則負け"; } else if (moveType === SpecialMoveType.FOUL_WIN) { return color === Color.BLACK ? "後手の反則負け" : "先手の反則負け"; } } return specialMoveToDisplayStringMap[moveType]; } /** * 「上」や「引」など指し手の移動方向を修飾する文字列を返します。 * @param move * @param position */ export function getDirectionModifier(move, position) { const piece = new Piece(move.color, move.pieceType); // 同じマス目へ移動可能な同種の駒を列挙 const others = position.listAttackersByPiece(move.to, piece).filter((square) => { return !(move.from instanceof Square) || !square.equals(move.from); }); // 移動可能な同じ駒がある場合に移動元を区別する文字を付ける。 if (move.from instanceof Square) { let ret = ""; // この指し手の移動方向 let myDir = move.from.directionTo(move.to); myDir = move.color === Color.BLACK ? myDir : reverseDirection(myDir); const myVDir = directionToVDirection(myDir); const myHDir = directionToHDirection(myDir); // 他の駒の移動方向 const otherDirs = others.map((square) => { const dir = square.directionTo(move.to); return move.color === Color.BLACK ? dir : reverseDirection(dir); }); // 水平方向がこの指し手と同じものを列挙して、その垂直方向を保持する。 const vDirections = otherDirs .filter((dir) => directionToHDirection(dir) == myHDir) .map((dir) => directionToVDirection(dir)); // 垂直方向がこの指し手と同じものを列挙して、その水平方向を保持する。 const hDirections = otherDirs .filter((dir) => directionToVDirection(dir) == myVDir) .map((dir) => directionToHDirection(dir)); // 水平方向で区別すべき駒がある場合 let noVertical = false; if (hDirections.length) { if (move.pieceType === PieceType.HORSE || move.pieceType === PieceType.DRAGON) { // 竜や馬の場合は2枚しかないので「直」は使わない。 if (myHDir === HDirection.LEFT || (myHDir === HDirection.NONE && hDirections[0] === HDirection.RIGHT)) { ret += "右"; } else if (myHDir === HDirection.RIGHT || (myHDir === HDirection.NONE && hDirections[0] === HDirection.LEFT)) { ret += "左"; } } else { switch (myHDir) { case HDirection.LEFT: ret += "右"; break; case HDirection.NONE: ret += "直"; // 後ろへ3方向移動できてなおかつ3枚以上ある駒は存在しないため「直」と垂直方向の区別は同時に使用しない。 noVertical = true; break; case HDirection.RIGHT: ret += "左"; break; } } } // 垂直方向で区別すべき駒がある場合 if (!noVertical && (vDirections.length || (!hDirections.length && others.length))) { switch (myVDir) { case VDirection.DOWN: ret += "引"; break; case VDirection.NONE: ret += "寄"; break; case VDirection.UP: ret += "上"; break; } } return ret; } else if (others.length) { // 盤上に移動可能な同じ駒がある場合は、駒台から打つことを明示する。 return "打"; } return ""; } /** * 指し手を表す文字列を返します。 * @param position 指し手の直前の局面 * @param move 対象の指し手 */ export function formatMove(position, move, opt) { let ret = ""; // 手番を表す記号を付与する。 switch (move.color) { case Color.BLACK: ret += opt?.compatible ? "▲" : "☗"; break; case 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) { // 「成」または「不成」を付ける。 if (move.promote) { ret += "成"; } else if (move.from instanceof Square && isPromotable(move.pieceType) && (isPromotableRank(move.color, move.from.rank) || isPromotableRank(move.color, move.to.rank))) { ret += "不成"; } } return ret; } export 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]\)|)/; export function parsePV(position, text) { return parseMoves(position, text)[0]; } /** * テキストから指し手を読み込みます。 KI2 と互換性があります。 * @param position 指し手の直前の局面 * @param text 対象の文字列 * @param lastMove 直前の指し手(1 手目が "同" を使った表記の場合に使用する。) */ export 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 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 InvalidMoveError(section)]; } } else { const file = stringToNumber(toStr[0]); const rank = stringToNumber(toStr[1]); to = new 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(file, rank); } else { let squares = p.listAttackersByPiece(to, new Piece(p.color, pieceType)).filter((square) => { let dir = square.directionTo(to); dir = p.color === Color.BLACK ? dir : reverseDirection(dir); const vDir = directionToVDirection(dir); const hDir = directionToHDirection(dir); if (verStr.indexOf("引") >= 0 && vDir !== VDirection.DOWN) { return false; } if (verStr.indexOf("寄") >= 0 && vDir !== VDirection.NONE) { return false; } if ((verStr.indexOf("上") >= 0 || verStr.indexOf("行") >= 0) && vDir !== VDirection.UP) { return false; } if (horStr.indexOf("直") >= 0 && (hDir !== HDirection.NONE || vDir !== VDirection.UP)) { return false; } if (pieceType === PieceType.HORSE || pieceType === PieceType.DRAGON) { // 馬や龍の場合は "左" や "右" でも真っ直ぐ進む場合があるので明らかに違うものだけを除外する。 if (horStr.indexOf("左") >= 0 && hDir === HDirection.LEFT) { return false; } if (horStr.indexOf("右") >= 0 && hDir === HDirection.RIGHT) { return false; } } else { if (horStr.indexOf("左") >= 0 && hDir !== HDirection.RIGHT) { return false; } if (horStr.indexOf("右") >= 0 && hDir !== HDirection.LEFT) { return false; } } return true; }); if (squares.length === 2 && (pieceType === PieceType.HORSE || pieceType === PieceType.DRAGON)) { // 馬や龍で "左" や "右" が使われ、 1 つに絞れなかった場合は真っ直ぐ進むものを除外する。 squares = squares.filter((square) => { let dir = square.directionTo(to); dir = p.color === Color.BLACK ? dir : reverseDirection(dir); const hDir = directionToHDirection(dir); return hDir !== 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 InvalidMoveError(section)]; } } let move = p.createMove(from, to); if (!move) { return [pv, new InvalidMoveError(section)]; } if (promOrDropStr === "成") { move = move.withPromote(); } if (!p.doMove(move, { ignoreValidation: true })) { return [pv, new InvalidMoveError(section)]; } pv.push(move); } return [pv, undefined]; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDaEMsT0FBTyxFQUNMLFVBQVUsRUFDVixVQUFVLEVBQ1YscUJBQXFCLEVBQ3JCLHFCQUFxQixFQUNyQixnQkFBZ0IsR0FDakIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzVDLE9BQU8sRUFBcUIsZUFBZSxFQUFFLGtCQUFrQixFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6RCxPQUFPLEVBQXFCLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFbEMsTUFBTSxpQkFBaUIsR0FBNEI7SUFDakQsR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJ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