tsshogi
Version:
TypeScript library for Shogi (Japanese chess)
366 lines • 20.6 kB
JavaScript
import { Color, reverseColor } from "./color.mjs";
export var PieceType;
(function (PieceType) {
PieceType["PAWN"] = "pawn";
PieceType["LANCE"] = "lance";
PieceType["KNIGHT"] = "knight";
PieceType["SILVER"] = "silver";
PieceType["GOLD"] = "gold";
PieceType["BISHOP"] = "bishop";
PieceType["ROOK"] = "rook";
PieceType["KING"] = "king";
PieceType["PROM_PAWN"] = "promPawn";
PieceType["PROM_LANCE"] = "promLance";
PieceType["PROM_KNIGHT"] = "promKnight";
PieceType["PROM_SILVER"] = "promSilver";
PieceType["HORSE"] = "horse";
PieceType["DRAGON"] = "dragon";
})(PieceType || (PieceType = {}));
const standardPieceNameMap = {
pawn: "歩",
lance: "香",
knight: "桂",
silver: "銀",
gold: "金",
bishop: "角",
rook: "飛",
king: "玉",
promPawn: "と",
promLance: "成香",
promKnight: "成桂",
promSilver: "成銀",
horse: "馬",
dragon: "竜",
};
/**
* 標準的な駒の名前を返します。
* @param type
*/
export function standardPieceName(type) {
const val = standardPieceNameMap[type];
return val || "";
}
export const pieceTypes = [
PieceType.PAWN,
PieceType.LANCE,
PieceType.KNIGHT,
PieceType.SILVER,
PieceType.GOLD,
PieceType.BISHOP,
PieceType.ROOK,
PieceType.KING,
PieceType.PROM_PAWN,
PieceType.PROM_LANCE,
PieceType.PROM_KNIGHT,
PieceType.PROM_SILVER,
PieceType.HORSE,
PieceType.DRAGON,
];
export const handPieceTypes = [
PieceType.PAWN,
PieceType.LANCE,
PieceType.KNIGHT,
PieceType.SILVER,
PieceType.GOLD,
PieceType.BISHOP,
PieceType.ROOK,
];
const promotable = {
pawn: true,
lance: true,
knight: true,
silver: true,
gold: false,
bishop: true,
rook: true,
king: false,
promPawn: false,
promLance: false,
promKnight: false,
promSilver: false,
horse: false,
dragon: false,
};
/**
* 成ることができる駒かどうかを返します。
* @param pieceType
*/
export function isPromotable(pieceType) {
return !!promotable[pieceType];
}
const promoteMap = {
pawn: PieceType.PROM_PAWN,
lance: PieceType.PROM_LANCE,
knight: PieceType.PROM_KNIGHT,
silver: PieceType.PROM_SILVER,
bishop: PieceType.HORSE,
rook: PieceType.DRAGON,
};
/**
* 成った時の駒の種類を返します。
* @param pieceType
*/
export function promotedPieceType(pieceType) {
return promoteMap[pieceType] || pieceType;
}
const unpromoteMap = {
promPawn: PieceType.PAWN,
promLance: PieceType.LANCE,
promKnight: PieceType.KNIGHT,
promSilver: PieceType.SILVER,
horse: PieceType.BISHOP,
dragon: PieceType.ROOK,
};
/**
* 成る前の駒の種類を返します。
* @param pieceType
*/
export function unpromotedPieceType(pieceType) {
return unpromoteMap[pieceType] || pieceType;
}
const toSFENCharBlack = {
pawn: "P",
lance: "L",
knight: "N",
silver: "S",
gold: "G",
bishop: "B",
rook: "R",
king: "K",
promPawn: "+P",
promLance: "+L",
promKnight: "+N",
promSilver: "+S",
horse: "+B",
dragon: "+R",
};
/**
* SFEN形式の駒種を表す文字列を返します。
* @param type
*/
export function pieceTypeToSFEN(type) {
return toSFENCharBlack[type];
}
const toSFENCharWhite = {
pawn: "p",
lance: "l",
knight: "n",
silver: "s",
gold: "g",
bishop: "b",
rook: "r",
king: "k",
promPawn: "+p",
promLance: "+l",
promKnight: "+n",
promSilver: "+s",
horse: "+b",
dragon: "+r",
};
const sfenCharToTypeMap = {
P: PieceType.PAWN,
L: PieceType.LANCE,
N: PieceType.KNIGHT,
S: PieceType.SILVER,
G: PieceType.GOLD,
B: PieceType.BISHOP,
R: PieceType.ROOK,
K: PieceType.KING,
"+P": PieceType.PROM_PAWN,
"+L": PieceType.PROM_LANCE,
"+N": PieceType.PROM_KNIGHT,
"+S": PieceType.PROM_SILVER,
"+B": PieceType.HORSE,
"+R": PieceType.DRAGON,
p: PieceType.PAWN,
l: PieceType.LANCE,
n: PieceType.KNIGHT,
s: PieceType.SILVER,
g: PieceType.GOLD,
b: PieceType.BISHOP,
r: PieceType.ROOK,
k: PieceType.KING,
"+p": PieceType.PROM_PAWN,
"+l": PieceType.PROM_LANCE,
"+n": PieceType.PROM_KNIGHT,
"+s": PieceType.PROM_SILVER,
"+b": PieceType.HORSE,
"+r": PieceType.DRAGON,
};
const sfenCharToColorMap = {
P: Color.BLACK,
L: Color.BLACK,
N: Color.BLACK,
S: Color.BLACK,
G: Color.BLACK,
B: Color.BLACK,
R: Color.BLACK,
K: Color.BLACK,
"+P": Color.BLACK,
"+L": Color.BLACK,
"+N": Color.BLACK,
"+S": Color.BLACK,
"+B": Color.BLACK,
"+R": Color.BLACK,
p: Color.WHITE,
l: Color.WHITE,
n: Color.WHITE,
s: Color.WHITE,
g: Color.WHITE,
b: Color.WHITE,
r: Color.WHITE,
k: Color.WHITE,
"+p": Color.WHITE,
"+l": Color.WHITE,
"+n": Color.WHITE,
"+s": Color.WHITE,
"+b": Color.WHITE,
"+r": Color.WHITE,
};
const rotateMap = new Map();
rotateMap.set(PieceType.PAWN, {
type: PieceType.PROM_PAWN,
reverseColor: false,
});
rotateMap.set(PieceType.LANCE, {
type: PieceType.PROM_LANCE,
reverseColor: false,
});
rotateMap.set(PieceType.KNIGHT, {
type: PieceType.PROM_KNIGHT,
reverseColor: false,
});
rotateMap.set(PieceType.SILVER, {
type: PieceType.PROM_SILVER,
reverseColor: false,
});
rotateMap.set(PieceType.GOLD, { type: PieceType.GOLD, reverseColor: true });
rotateMap.set(PieceType.BISHOP, { type: PieceType.HORSE, reverseColor: false });
rotateMap.set(PieceType.ROOK, { type: PieceType.DRAGON, reverseColor: false });
rotateMap.set(PieceType.KING, { type: PieceType.KING, reverseColor: true });
rotateMap.set(PieceType.PROM_PAWN, {
type: PieceType.PAWN,
reverseColor: true,
});
rotateMap.set(PieceType.PROM_LANCE, {
type: PieceType.LANCE,
reverseColor: true,
});
rotateMap.set(PieceType.PROM_KNIGHT, {
type: PieceType.KNIGHT,
reverseColor: true,
});
rotateMap.set(PieceType.PROM_SILVER, {
type: PieceType.SILVER,
reverseColor: true,
});
rotateMap.set(PieceType.HORSE, { type: PieceType.BISHOP, reverseColor: true });
rotateMap.set(PieceType.DRAGON, { type: PieceType.ROOK, reverseColor: true });
/**
* 駒(手番を含む)
*/
export class Piece {
color;
type;
constructor(color, type) {
this.color = color;
this.type = type;
}
/**
* 先手番の駒に変換します。
*/
black() {
return this.withColor(Color.BLACK);
}
/**
* 後手番の駒に変換します。
*/
white() {
return this.withColor(Color.WHITE);
}
/**
* 手番を変更した駒を返します。
*/
withColor(color) {
return new Piece(color, this.type);
}
/**
* 等しい駒かどうかを判定します。
*/
equals(piece) {
return this.type === piece.type && this.color === piece.color;
}
/**
* 成った駒を返します。
*/
promoted() {
const type = promoteMap[this.type];
return new Piece(this.color, type || this.type);
}
/**
* 成る前の駒を返します。
*/
unpromoted() {
const type = unpromoteMap[this.type];
return new Piece(this.color, type || this.type);
}
/**
* 成ることが可能な駒かどうかを返します。
*/
isPromotable() {
return isPromotable(this.type);
}
/**
* 駒の向きと種類をローテートします。
* ex) 先手・歩 -> 先手・と -> 後手・歩 -> 後手・と -> 先手・歩
*/
rotate() {
const r = rotateMap.get(this.type);
const piece = new Piece(this.color, r ? r.type : this.type);
if (r && r.reverseColor) {
piece.color = reverseColor(this.color);
}
return piece;
}
/**
* 手番と種類を一意に識別する ID を返します。
*/
get id() {
return this.color + "_" + this.type;
}
/**
* SFEN形式の文字列を取得します。
*/
get sfen() {
switch (this.color) {
default:
case Color.BLACK:
return toSFENCharBlack[this.type];
case Color.WHITE:
return toSFENCharWhite[this.type];
}
}
/**
* 指定した文字列が正しいSFEN形式の駒かどうかを判定します。
* @param sfen
*/
static isValidSFEN(sfen) {
return !!sfenCharToTypeMap[sfen];
}
/**
* SFEN形式の文字列から駒を生成します。
* @param sfen
*/
static newBySFEN(sfen) {
const type = sfenCharToTypeMap[sfen];
if (!type) {
return null;
}
const color = sfenCharToColorMap[sfen];
if (!color) {
return null;
}
return new Piece(color, type);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGllY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGllY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFOUMsTUFBTSxDQUFOLElBQVksU0FlWDtBQWZELFdBQVksU0FBUztJQUNuQiwwQkFBYSxDQUFBO0lBQ2IsNEJBQWUsQ0FBQTtJQUNmLDhCQUFpQixDQUFBO0lBQ2pCLDhCQUFpQixDQUFBO0lBQ2pCLDBCQUFhLENBQUE7SUFDYiw4QkFBaUIsQ0FBQTtJQUNqQiwwQkFBYSxDQUFBO0lBQ2IsMEJBQWEsQ0FBQTtJQUNiLG1DQUFzQixDQUFBO0lBQ3RCLHFDQUF3QixDQUFBO0lBQ3hCLHVDQUEwQixDQUFBO0lBQzFCLHVDQUEwQixDQUFBO0lBQzFCLDRCQUFlLENBQUE7SUFDZiw4QkFBaUIsQ0FBQTtBQUNuQixDQUFDLEVBZlcsU0FBUyxLQUFULFNBQVMsUUFlcEI7QUFFRCxNQUFNLG9CQUFvQixHQUF5QztJQUNqRSxJQUFJLEVBQUUsR0FBRztJQUNULEtBQUssRUFBRSxHQUFHO0lBQ1YsTUFBTSxFQUFFLEdBQUc7SUFDWCxNQUFNLEVBQUUsR0FBRztJQUNYLElBQUksRUFBRSxHQUFHO0lBQ1QsTUFBTSxFQUFFLEdBQUc7SUFDWCxJQUFJLEVBQUUsR0FBRztJQUNULElBQUksRUFBRSxHQUFHO0lBQ1QsUUFBUSxFQUFFLEdBQUc7SUFDYixTQUFTLEVBQUUsSUFBSTtJQUNmLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLEtBQUssRUFBRSxHQUFHO0lBQ1YsTUFBTSxFQUFFLEdBQUc7Q0FDWixDQUFDO0FBRUY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQWU7SUFDL0MsTUFBTSxHQUFHLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkMsT0FBTyxHQUFHLElBQUks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