tsshogi
Version:
TypeScript library for Shogi (Japanese chess)
469 lines • 36.3 kB
JavaScript
;
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, color) {
if (typeof move !== "string" && !(0, move_1.isKnownSpecialMove)(move)) {
return move.name;
}
const moveType = typeof move === "string" ? move : move.type;
if (color !== undefined) {
if (moveType === move_1.SpecialMoveType.FOUL_LOSE) {
return color === color_1.Color.BLACK ? "先手の反則負け" : "後手の反則負け";
}
else if (moveType === move_1.SpecialMoveType.FOUL_WIN) {
return color === color_1.Color.BLACK ? "後手の反則負け" : "先手の反則負け";
}
}
return specialMoveToDisplayStringMap[moveType];
}
/**
* 「上」や「引」など指し手の移動方向を修飾する文字列を返します。
* @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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkVBLHdDQUVDO0FBRUQsOENBRUM7QUF3QkQsc0NBRUM7QUFFRCxrREFFQztBQUVELGtDQUVDO0FBcUJELDREQUVDO0FBcUJELDhEQUVDO0FBMkJELDhDQWFDO0FBT0Qsb0RBaUZDO0FBT0QsZ0NBMkNDO0FBRUQsNEJBYUM7QUFLRCwwQkFFQztBQVFELGdDQW1JQztBQXBmRCxtQ0FBZ0M7QUFDaEMsMkNBTXFCO0FBQ3JCLHFDQUE0QztBQUM1QyxpQ0FBZ0Y7QUFDaEYsbUNBQXlEO0FBQ3pELHlDQUFpRTtBQUNqRSxxQ0FBa0M7QUFFbEMsTUFBTSxpQkFBaUIsR0FBNEI7SUFDakQsR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sR0FBRyxFQUFFLENBQUM7SUFDTixHQUFHLEVBQUUsQ0FBQztJQUNOLEdBQUcsRUFBRSxDQUFDO0lBQ04sQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMsRUFBRSxDQUFDO0lBQ0osQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMsRUFBRSxDQUFDO0lBQ0osQ0FBQyxFQUFFLENBQUM7SUFDSixDQUFDLEVBQUUsQ0FBQztJQUNKLENBQUMs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