@wxzqs/chess
Version:
公共象棋工具类
1,018 lines (1,012 loc) • 29.8 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) return _arrayLikeToArray(r);
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
t && (r = t);
var n = 0,
F = function () {};
return {
s: F,
n: function () {
return n >= r.length ? {
done: true
} : {
done: false,
value: r[n++]
};
},
e: function (r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = true,
u = false;
return {
s: function () {
t = t.call(r);
},
n: function () {
var r = t.next();
return a = r.done, r;
},
e: function (r) {
u = true, o = r;
},
f: function () {
try {
a || null == t.return || t.return();
} finally {
if (u) throw o;
}
}
};
}
function _defineProperty(e, r, t) {
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: true,
configurable: true,
writable: true
}) : e[r] = t, e;
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = true,
o = false;
try {
if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = true, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _toArray(r) {
return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest();
}
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r);
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
var PieceKind = {
EMPTY: 0,
ROOK: "r",
KNIGHT: "n",
BISHOP: "b",
ADVISOR: "a",
KING: "k",
CANNON: "c",
PAWN: "p"
};
var PieceType = {
// 红方棋子
WP: "P",
WC: "C",
WR: "R",
WN: "N",
WB: "B",
WA: "A",
WK: "K",
// 黑方棋子
BP: "p",
BC: "c",
BR: "r",
BN: "n",
BB: "b",
BA: "a",
BK: "k"
};
var Color = {
WHITE: "w",
BLACK: "b"
};
var ICCS_REGEXP = /([a-i][0-9])[-]?([a-i][0-9])/i;
var EMPTY_BOARD = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]];
var ChessUtil = {
/**
* 校验fen是否有效
* <p>
* rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
* </p>
* <p>1part 棋盘信息</p>
* <p>2part 红/黑 方</p>
* <p>3part 忽略</p>
* <p>4part 忽略</p>
* <p>5part</p>
* <p>6part</p>
* */
validateFen: function validateFen(fen) {
if (!fen) {
return {
ok: false,
error: "Invalid FEN: fen\u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32"
};
}
var tokens = fen.split(/\s+/);
if (tokens.length < 2) {
return {
ok: false,
error: "Invalid FEN: \u5FC5\u987B\u5305\u542B\u4E8C\u8981\u7D20\u4FE1\u606F"
};
}
var moveNumber = parseInt(tokens[5], 10) || 0;
if (isNaN(moveNumber) || moveNumber < 0) {
return {
ok: false,
error: "Invalid FEN: \u79FB\u52A8\u6B65\u6570\u5FC5\u987B\u4E3A\u4E00\u4E2A\u6B63\u6574\u6570"
};
}
var halfMoves = parseInt(tokens[4], 10) || 1;
if (isNaN(halfMoves) || halfMoves < 0) {
return {
ok: false,
error: "Invalid FEN: \u534A\u79FB\u52A8\u8BA1\u6570\u6B65\u6570\u5FC5\u987B\u4E3A\u975E\u8D1F\u6570"
};
}
if (!/^[wb]$/.test(tokens[1])) {
return {
ok: false,
error: "Invalid FEN: \u8F6E\u5230\u8C01\u884C\u52A8\u503C\u65E0\u6548, \u5FC5\u987B\u4E3Aw \u6216 b"
};
}
var rows = tokens[0].split("/");
if (rows.length !== 10) {
return {
ok: false,
error: "Invalid FEN: \u68CB\u5B50\u6570\u636E\u5206\u5272\u68CB\u5B50\u65E0\u6548 (\u683C\u5B50\u6570\u636E\u672A\u6EE110)"
};
}
var _iterator = _createForOfIteratorHelper(rows),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var row = _step.value;
var sumFields = 0;
var previousWasNumber = false;
var _iterator2 = _createForOfIteratorHelper(row),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var element = _step2.value;
if (this.isDigit(element)) {
if (previousWasNumber) {
return {
ok: false,
error: "Invalid FEN: \u68CB\u5B50\u6570\u636E\u65E0\u6548 (\u7A7A\u683C\u6570\u5B57\u65E0\u6548)"
};
}
sumFields += parseInt(element, 10);
previousWasNumber = true;
} else {
if (!/^[rnbakcpRNBAKCP]$/.test(element)) {
return {
ok: false,
error: "Invalid FEN: \u68CB\u5B50\u6570\u636E\u65E0\u6548 (\u65E0\u6548\u68CB\u5B50".concat(element, ")")
};
}
sumFields += 1;
previousWasNumber = false;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
if (sumFields < 9) {
return {
ok: false,
error: "Invalid FEN: \u68CB\u5B50\u6570\u636E\u65E0\u6548 (\u683C\u5B50\u6570\u636E\u5C0F\u4E8E9\u5217)"
};
} else if (sumFields > 9) {
return {
ok: false,
error: "Invalid FEN: \u68CB\u5B50\u6570\u636E\u65E0\u6548 (\u683C\u5B50\u6570\u636E\u5927\u4E8E9\u5217)"
};
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
var kings = [{
color: "\u7EA2\u65B9",
regex: /K/g
}, {
color: "\u9ED1\u65B9",
regex: /k/g
}];
for (var _i = 0, _kings = kings; _i < _kings.length; _i++) {
var _kings$_i = _kings[_i],
color = _kings$_i.color,
regex = _kings$_i.regex;
if (!regex.test(tokens[0])) {
return {
ok: false,
error: "Invalid FEN: \u672A\u627E\u5230".concat(color, "\u5C06\u519B")
};
}
if ((tokens[0].match(regex) || []).length > 1) {
return {
ok: false,
error: "Invalid FEN: \u627E\u5230\u591A\u4E2A".concat(color, "\u5C06\u519B")
};
}
}
var pieces = [{
type: "r",
max: 2
}, {
type: "n",
max: 2
}, {
type: "b",
max: 2
}, {
type: "a",
max: 2
}, {
type: "k",
max: 1
}, {
type: "c",
max: 2
}, {
type: "p",
max: 5
}];
var boardPart = tokens[0];
var pieceCount = {};
for (var _i2 = 0, _pieces = pieces; _i2 < _pieces.length; _i2++) {
var type = _pieces[_i2].type;
pieceCount[type] = 0;
pieceCount[type.toUpperCase()] = 0;
}
for (var i = 0; i < boardPart.length; i++) {
var _char = boardPart[i];
if (/^[rnbakcpRNBAKCP]$/.test(_char)) {
pieceCount[_char]++;
}
}
for (var _i3 = 0, _pieces2 = pieces; _i3 < _pieces2.length; _i3++) {
var _pieces2$_i = _pieces2[_i3],
_type = _pieces2$_i.type,
max = _pieces2$_i.max;
var lowerCaseCount = pieceCount[_type];
var upperCaseCount = pieceCount[_type.toUpperCase()];
if (lowerCaseCount > max || upperCaseCount > max) {
return {
ok: false,
error: "\u68CB\u5C40\u65E0\u6548".concat(_type, "\u68CB\u5B50\u8D85\u51FA\u6700\u5927\u4E2A\u6570")
};
}
}
return {
ok: true
};
},
/**
* 是否为数字
* */
isDigit: function isDigit(c) {
return "0123456789".indexOf(c) !== -1;
},
/**
* 去除fen最后两个的配置信息
* */
trimFen: function trimFen(fen) {
return fen.split(/\s+/).slice(0, 4).join(" ");
},
/**
* 交换棋子颜色
* @param {string} color - 当前棋子的颜色
* @returns {string} - 交换后的棋子颜色
*/
swapColor: function swapColor(color) {
return color === Color.WHITE ? Color.BLACK : Color.WHITE;
},
/**
* 获取棋子颜色
* */
getColor: function getColor(piece) {
return piece < "a" ? Color.WHITE : Color.BLACK;
},
/**
* 检查棋子位置是否在棋盘内
* @param {number} left - 棋子的左侧坐标
* @param {number} top - 棋子的顶部坐标
* @param {string} checkType - 可选参数,检查的类型,默认为棋盘检查
* @returns {boolean} - 如果棋子位置在棋盘内则返回 true,否则返回 false
*/
inBoard: function inBoard(left, top) {
var checkType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ChessConstants.CHECK_TYPE_BOARD;
if (checkType == ChessConstants.CHECK_TYPE_BOARD) {
return left >= 0 && left < ChessConstants.MAX_LEFT && top >= 0 && top < ChessConstants.MAX_TOP;
} else if (checkType == ChessConstants.CHECK_TYPE_JIU_GONG) {
var jiuGong = {
left: 3,
redBottom: 7,
blackBottom: 0,
right: 5,
redTop: 9,
blackTop: 2
};
if (left < jiuGong.left || left > jiuGong.right) {
return false;
}
return top >= jiuGong.blackBottom && top <= jiuGong.blackTop || top >= jiuGong.redBottom && top <= jiuGong.redTop;
}
},
/**
* 翻转方向
* @param directions 方向
* @param revert 是否翻转(Y轴)
* @param revertKeys 翻转字段
* */
transformDirections: function transformDirections(directions, revert) {
for (var _len = arguments.length, revertKeys = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
revertKeys[_key - 2] = arguments[_key];
}
if (!revert) {
return directions;
}
return directions.map(function (v) {
Object.keys(v).forEach(function (key) {
if (revertKeys.includes(key)) {
v[key] = -v[key];
}
});
return v;
});
},
/**
* 是否过河
* */
isCrossRiver: function isCrossRiver(top, color) {
return color === Color.BLACK ? top >= 5 : top <= 4;
},
isBing: function isBing(type) {
return /^[pP]$/.test(type);
},
isPao: function isPao(type) {
return /^[cC]$/.test(type);
},
isChe: function isChe(type) {
return /^[rR]$/.test(type);
},
isMa: function isMa(type) {
return /^[nN]$/.test(type);
},
isXiang: function isXiang(type) {
return /^[bB]$/.test(type);
},
isShi: function isShi(type) {
return /^[aA]$/.test(type);
},
isJiang: function isJiang(type) {
return /^[kK]$/.test(type);
},
/**
* 对称棋盘
* */
reverseBoard: function reverseBoard(boardMap) {
var reversedExpandedBoard = [];
if (!boardMap) {
return reversedExpandedBoard;
}
var _iterator3 = _createForOfIteratorHelper(boardMap),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var row = _step3.value;
var reversedRow = [];
for (var i = row.length - 1; i >= 0; i--) {
reversedRow.push(row[i]);
}
reversedExpandedBoard.push(reversedRow);
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
return reversedExpandedBoard;
},
/**
* 翻转局面代码
* */
reverseFen: function reverseFen(fen) {
if (!fen) {
return fen;
}
var _this$validateFen = this.validateFen(fen),
ok = _this$validateFen.ok,
error = _this$validateFen.error;
if (!ok) {
throw new Error(error);
}
var parts = fen.split(/\s+/);
var fenCode = parts[0];
var config = parts.slice(1);
var expandedBoard = this.toBoard(fenCode);
var reversedExpandedBoard = this.reverseBoard(expandedBoard);
var reversedFen = this.toFen(reversedExpandedBoard);
return [reversedFen].concat(_toConsumableArray(config)).join(" ");
},
/**
* 标准棋盘
* */
standardBoard: function standardBoard() {
var cols = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
var rows = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
return rows.map(function (row) {
return cols.map(function (col) {
return "".concat(col).concat(row);
}).join("|");
}).reverse().join("\n");
},
/**
* 修复局面代码
* */
fixFen: function fixFen(fen) {
if (!fen) {
throw new Error("\u5C40\u9762\u4EE3\u7801\u4E0D\u80FD\u4E3A\u7A7A");
}
var tokens = fen.split(/\s+/);
if (tokens.length >= 1 && tokens.length < 6) {
var adjustments = [Color.WHITE, "-", "-", "0", "1"];
fen = tokens.concat(adjustments.slice(-(6 - tokens.length))).join(" ");
}
return fen;
},
/**
* 将二维数组转换为局面代码
* */
toFen: function toFen(boardMap) {
if (boardMap.length !== 9) {
console.warn("\u8BF7\u8865\u5168\u68CB\u76D8\u5185\u5BB9\uFF0C\u5FC5\u987B\u67099\u884C\u6570\u636E", boardMap);
throw new Error("\u8BF7\u8865\u5168\u68CB\u76D8\u5185\u5BB9\uFF0C\u5FC5\u987B\u67099\u884C\u6570\u636E");
}
if (boardMap.some(function (col) {
return col.length !== 10;
})) {
console.warn("\u8BF7\u8865\u5168\u68CB\u76D8\u5185\u5BB9\uFF0C\u5FC5\u987B\u6BCF\u884C\u4E3A10\u5217", boardMap);
throw new Error("\u8BF7\u8865\u5168\u68CB\u76D8\u5185\u5BB9\uFF0C\u5FC5\u987B\u6BCF\u884C\u4E3A10\u5217");
}
var fenList = [];
if (!boardMap) {
return fenList;
}
for (var rowIndex = 0; rowIndex < 10; rowIndex++) {
var fenRow = "";
var emptyCount = 0;
for (var colIndex = 0; colIndex < 9; colIndex++) {
var cell = boardMap[colIndex][9 - rowIndex];
if (cell === PieceKind.EMPTY) {
emptyCount++;
} else {
if (emptyCount > 0) {
fenRow += emptyCount;
emptyCount = 0;
}
fenRow += cell;
}
}
if (emptyCount > 0) {
fenRow += emptyCount;
}
fenList.push(fenRow);
}
return fenList.join("/");
},
/**
* 将局面代码转换为二维数组
* */
toBoard: function toBoard(fen) {
fen = fen.split(/\s+/)[0];
var boardList = this.emptyBoard();
if (!fen) {
return boardList;
}
var boardLayout = fen.split("/");
boardLayout.forEach(function (rowStr, rowIndex) {
var colIndex = 0;
var _iterator4 = _createForOfIteratorHelper(rowStr),
_step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
var _char2 = _step4.value;
if (/\d/.test(_char2)) {
colIndex += parseInt(_char2, 10);
} else {
boardList[colIndex][9 - rowIndex] = _char2;
colIndex++;
}
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
});
return boardList;
},
// 默认局面代码
defaultFen: function defaultFen() {
return "rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1";
},
// 空局面代码
emptyFen: function emptyFen() {
return "9/9/9/9/9/9/9/9/9/9 w - - 0 1";
},
// 默认局面
defaultBoard: function defaultBoard() {
return this.toBoard(this.defaultFen());
},
// 空棋盘
emptyBoard: function emptyBoard() {
return EMPTY_BOARD.map(function (row) {
return _toConsumableArray(row);
});
},
/**
* 移动
* @param fen 局面代码
* @param tricks 招数列表
*/
move: function move(fen) {
if (!fen) {
throw new Error("\u5C40\u9762\u4EE3\u7801\u4E0D\u80FD\u4E3A\u7A7A");
}
for (var _len2 = arguments.length, tricks = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
tricks[_key2 - 1] = arguments[_key2];
}
if (!(tricks !== null && tricks !== void 0 && tricks.length)) return fen;
var parts = fen.split(/\s+/);
var _parts = _toArray(parts),
boardPart = _parts[0],
currentPlayer = _parts[1],
rest = _parts.slice(2);
var board = this.toBoard(boardPart);
for (var _i4 = 0, _tricks = tricks; _i4 < _tricks.length; _i4++) {
var trick = _tricks[_i4];
var _this$toPos = this.toPos(trick),
_this$toPos2 = _slicedToArray(_this$toPos, 4),
fromLeft = _this$toPos2[0],
fromTop = _this$toPos2[1],
toLeft = _this$toPos2[2],
toTop = _this$toPos2[3];
var piece = board[fromLeft][fromTop];
board[fromLeft][fromTop] = PieceKind.EMPTY;
board[toLeft][toTop] = piece;
}
var newBoard = this.toFen(board);
var newPlayer = ChessUtil.swapColor(currentPlayer);
return [newBoard, newPlayer].concat(_toConsumableArray(rest)).join(" ");
},
/**
* 判断是否为前进
* @param {number} fromTop - 起始行(绝对坐标)
* @param {number} topTop - 目标行(绝对坐标)
* @param {string} color - 棋子颜色
* @returns {boolean} 是否前进
*/
isForward: function isForward(fromTop, topTop, color) {
var forwardDirection = {
WHITE: 1,
BLACK: -1
};
var dir = color === "w" ? forwardDirection.WHITE : forwardDirection.BLACK;
return (topTop - fromTop) * dir > 0;
},
/**
* 批量翻译着法
* @param fen 局面代码
* @param tricks 着法数组 iccs
* @param format 翻译格式 cn:中文纵线格式 wxf:WXF纵线格式
*/
translateBatch: function translateBatch(fen, tricks) {
var _this = this;
var format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "cn";
return tricks.map(function (trick, index, array) {
var newFen = _this.move.apply(_this, [fen].concat(_toConsumableArray(array.slice(0, index))));
return _this.translate(newFen, trick, format);
});
},
/**
* 翻译着法
* @param fen 局面代码
* @param coord 着法 iccs
* @param format 翻译格式 cn:中文纵线格式 wxf:WXF纵线格式
*/
translate: function translate(fen, coord) {
var format = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "cn";
var pieceMap = {
"R": "\u8F66",
"N": "\u9A6C",
"B": "\u76F8",
"A": "\u4ED5",
"K": "\u5E05",
"C": "\u70AE",
"P": "\u5175",
"r": "\u8F66",
"n": "\u9A6C",
"b": "\u8C61",
"a": "\u58EB",
"k": "\u5C06",
"c": "\u70AE",
"p": "\u5352"
};
var colorWithNumberMap = {
"w": {
0: "\u4E5D",
1: "\u516B",
2: "\u4E03",
3: "\u516D",
4: "\u4E94",
5: "\u56DB",
6: "\u4E09",
7: "\u4E8C",
8: "\u4E00"
},
"b": {
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
5: 6,
6: 7,
7: 8,
8: 9
}
};
var chineseNumbers = ["", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"];
var board = this.toBoard(fen);
var _this$toPos3 = this.toPos(coord),
_this$toPos4 = _slicedToArray(_this$toPos3, 4),
fromLeft = _this$toPos4[0],
fromTop = _this$toPos4[1],
toLeft = _this$toPos4[2],
toTop = _this$toPos4[3];
var piece = board[fromLeft][fromTop];
var color = piece === piece.toUpperCase() ? "w" : "b";
var isRed = color === "w";
var numberMap = colorWithNumberMap[color];
var duplicate = board[fromLeft].filter(function (pieceType) {
return pieceType === piece;
}).length > 1;
var roadText;
if (duplicate) {
var candidates = board[fromLeft].map(function (pieceType, top) {
return {
pieceType: pieceType,
top: top
};
}).filter(function (_ref) {
var pieceType = _ref.pieceType;
return pieceType === piece;
});
candidates.sort(function (a, b) {
return isRed ? b.top - a.top : a.top - b.top;
});
var candidatePieceMap = candidates.map(function (candidate, index) {
return {
piece: candidate,
index: index
};
});
var candidatePiece = candidatePieceMap.find(function (candidatePieceItem) {
return candidatePieceItem.piece.top === fromTop;
});
if (candidates.length <= 3) {
var orderMap = _defineProperty(_defineProperty({
0: "\u524D"
}, Math.floor(candidatePieceMap.length / 2), "\u4E2D"), candidatePieceMap.length - 1, "\u540E");
roadText = orderMap[candidatePiece.index];
} else {
var _orderMap2 = {
0: "\u4E00",
1: "\u4E8C",
2: "\u4E09",
3: "\u56DB",
4: "\u4E94"
};
roadText = _orderMap2[candidatePiece.index];
}
}
var startRoad = numberMap[fromLeft];
var endRoad = numberMap[toLeft];
var action, value;
if (["R", "C", "K", "P"].includes(piece.toUpperCase())) {
if (fromLeft !== toLeft) {
action = "\u5E73";
value = endRoad;
} else {
var steps = Math.abs(toTop - fromTop);
action = this.isForward(fromTop, toTop, color) ? "\u8FDB" : "\u9000";
value = isRed ? chineseNumbers[steps] : steps;
}
} else {
action = this.isForward(fromTop, toTop, color) ? "\u8FDB" : "\u9000";
value = endRoad;
}
switch (format) {
case "cn":
{
var type = pieceMap[piece];
if (duplicate) {
return "".concat(roadText).concat(type).concat(action).concat(value);
} else {
return "".concat(type).concat(startRoad).concat(action).concat(value);
}
}
case "wxf":
{
switch (action) {
case "\u8FDB":
{
action = "+";
break;
}
case "\u9000":
{
action = "-";
break;
}
case "\u5E73":
{
action = ".";
break;
}
}
var chineseNumbers2 = ["", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
var road = isRed ? chineseNumbers2[startRoad] : startRoad;
var _type2 = piece.toUpperCase();
return "".concat(_type2).concat(road).concat(action).concat(value);
}
default:
throw new Error("\u672A\u77E5\u7740\u6CD5\u683C\u5F0F");
}
},
// ICCS 坐标转棋盘索引
iccsToPos: function iccsToPos(iccs) {
var col = iccs[0].toLowerCase().charCodeAt(0) - "a".charCodeAt(0);
var row = parseInt(iccs[1]);
return {
x: col,
y: row
};
},
/**
* 解析棋盘坐标转为iccs坐标
* */
posToIccs: function posToIccs(x, y) {
var col = String.fromCharCode("a".charCodeAt(0) + x);
return col + y;
},
/**
* 解析iccs坐标转为棋盘坐标
*/
toPos: function toPos(iccs) {
if (!ICCS_REGEXP.test(iccs)) {
throw new Error("\u975E\u6CD5iccs\u5750\u6807\u683C\u5F0F");
}
var _this$iccsToPos = this.iccsToPos(iccs[0] + iccs[1]),
startCol = _this$iccsToPos.x,
startRow = _this$iccsToPos.y;
var _this$iccsToPos2 = this.iccsToPos(iccs[2] + iccs[3]),
endCol = _this$iccsToPos2.x,
endRow = _this$iccsToPos2.y;
return [startCol, startRow, endCol, endRow];
},
/**
* 起始和目标索引转 ICCS 格式坐标
*/
toIccs: function toIccs(x1, y1, x2, y2) {
var startIccs = this.posToIccs(x1, y1);
var endIccs = this.posToIccs(x2, y2);
return startIccs + endIccs;
},
/**
* 比较两个fen的差异,只比较两个局面代码
*
* @return 差异点列表
*/
difference: function difference(fen, lastFen) {
var board = ChessUtil.toBoard(fen);
var lastBoard = ChessUtil.toBoard(lastFen);
var diffs = [];
for (var left = 0; left < 9; left++) {
for (var top = 0; top < 10; top++) {
var piece = board[left][top];
var lastPiece = lastBoard[left][top];
if (piece !== lastPiece) {
diffs.push({
piece: piece,
lastPiece: lastPiece,
left: left,
top: top,
color: this.getColor(piece || lastPiece)
});
}
}
}
return diffs;
},
countPiecesDetail: function countPiecesDetail(fen) {
var pieceCount = {
red: {
R: 0,
N: 0,
B: 0,
A: 0,
K: 0,
C: 0,
P: 0
},
black: {
r: 0,
n: 0,
b: 0,
a: 0,
k: 0,
c: 0,
p: 0
}
};
var board = fen.split(/\s+/)[0].replace(/\//g, "").replace(/\d/g, function (m) {
return "-".repeat(parseInt(m));
});
var _iterator5 = _createForOfIteratorHelper(board),
_step5;
try {
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
var _char3 = _step5.value;
if (_char3 === "-") continue;
if (/[RNBAKCP]/.test(_char3)) {
pieceCount.red[_char3] = (pieceCount.red[_char3] || 0) + 1;
} else if (/[rnbakcp]/.test(_char3)) {
pieceCount.black[_char3.toLowerCase()] = (pieceCount.black[_char3.toLowerCase()] || 0) + 1;
}
}
} catch (err) {
_iterator5.e(err);
} finally {
_iterator5.f();
}
return {
red: {
chariot: pieceCount.red.R,
horse: pieceCount.red.N,
elephant: pieceCount.red.B,
advisor: pieceCount.red.A,
king: pieceCount.red.K,
cannon: pieceCount.red.C,
pawn: pieceCount.red.P
},
black: {
chariot: pieceCount.black.r,
horse: pieceCount.black.n,
elephant: pieceCount.black.b,
advisor: pieceCount.black.a,
king: pieceCount.black.k,
cannon: pieceCount.black.c,
pawn: pieceCount.black.p
}
};
},
/**
* 返回棋子数
* @return 红方棋子数、黑方棋子数、全部棋子数
* */
countPieces: function countPieces(fen) {
var result = this.countPiecesDetail(fen);
var red = Object.values(result.red).reduce(function (sum, num) {
return sum + num;
}, 0);
var black = Object.values(result.black).reduce(function (sum, num) {
return sum + num;
}, 0);
return {
red: red,
black: black,
all: red + black
};
},
/**
* 是否为默认局面
* */
isStartPos: function isStartPos(fen) {
return this.fixFen(this.defaultFen()) === this.fixFen(fen);
},
/**
* 判断是否为iccs坐标 s1s2-t1t2
* */
isIccs: function isIccs(iccs) {
return iccs.length < 5 && /[a-iA-I][0-9][-.]?[a-iA-I][0-9]/.test(iccs);
},
/**
* 获取fen的走棋方
* */
getFenColor: function getFenColor(fen) {
if (!fen) {
throw new Error("\u5C40\u9762\u4EE3\u7801\u4E0D\u80FD\u4E3A\u7A7A");
}
var _this$validateFen2 = this.validateFen(fen),
ok = _this$validateFen2.ok,
error = _this$validateFen2.error;
if (!ok) {
throw new Error(error);
}
return fen.includes(Color.WHITE) ? Color.WHITE : Color.BLACK;
}
};
exports.ChessUtil = ChessUtil;
exports.Color = Color;
exports.PieceKind = PieceKind;
exports.PieceType = PieceType;
exports.default = ChessUtil;