tsshogi
Version:
TypeScript library for Shogi (Japanese chess)
454 lines • 34.8 kB
JavaScript
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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