return Object.values(cd).map(c => c.toString(36)).join("");
}
+ // c10 --> 02 (assuming 10 rows)
+ static SquareFromUsual(sq) {
+ return (
+ (this.size.x - parseInt(sq.substring(1), 10)).toString(36) +
+ (sq.charCodeAt(0) - 97).toString(36)
+ );
+ }
+
+ // 02 --> c10
+ static UsualFromSquare(sq) {
+ return (
+ String.fromCharCode(parseInt(sq.charAt(1), 36) + 97) +
+ (this.size.x - parseInt(sq.charAt(0), 36)).toString(10)
+ );
+ }
+
coordsToId(cd) {
if (typeof cd.x == "number") {
return (
randomness: this.options["randomness"],
between: [{p1: 'k', p2: 'r'}],
diffCol: ['b'],
- flags: ['r', 'k']
+ flags: ['r']
}
);
return {
getReserveFen(o) {
if (o.init)
- return "000000000000";
+ return Array(2 * V.ReserveArray.length).fill('0').join("");
return (
['w', 'b'].map(c => Object.values(this.reserve[c]).join("")).join("")
);
}
// Some additional variables from FEN (variant dependant)
- setOtherVariables(fenParsed, pieceArray) {
+ setOtherVariables(fenParsed) {
// Set flags and enpassant:
if (this.hasFlags)
this.setFlags(fenParsed.flags);
if (this.hasEnpassant)
this.epSquare = this.getEpSquare(fenParsed.enpassant);
if (this.hasReserve && !this.isDiagram)
- this.initReserves(fenParsed.reserve, pieceArray);
+ this.initReserves(fenParsed.reserve);
if (this.options["crazyhouse"])
this.initIspawn(fenParsed.ispawn);
if (this.options["teleport"]) {
}
// ordering as in pieces() p,r,n,b,q,k
- initReserves(reserveStr, pieceArray) {
- if (!pieceArray)
- pieceArray = ['p', 'r', 'n', 'b', 'q', 'k'];
+ static get ReserveArray() {
+ return ['p', 'r', 'n', 'b', 'q', 'k'];
+ }
+
+ initReserves(reserveStr) {
const counts = reserveStr.split("").map(c => parseInt(c, 36));
- const L = pieceArray.length;
+ const L = V.ReserveArray.length;
this.reserve = {
- w: ArrayFun.toObject(pieceArray, counts.slice(0, L)),
- b: ArrayFun.toObject(pieceArray, counts.slice(L, 2 * L))
+ w: ArrayFun.toObject(V.ReserveArray, counts.slice(0, L)),
+ b: ArrayFun.toObject(V.ReserveArray, counts.slice(L, 2 * L))
};
}
// VISUAL UTILS
getPieceWidth(rwidth) {
- return (rwidth / this.size.y);
+ return (rwidth / Math.max(this.size.x, this.size.y));
}
getReserveSquareSize(rwidth, nbR) {
// Get SVG board (background, no pieces)
getSvgChessboard() {
- const flipped = this.flippedBoard;
let board = `
<svg
viewBox="0 0 ${10*this.size.y} ${10*this.size.x}"
class="chessboard_SVG">`;
+ board += this.getBaseSvgChessboard();
+ board += "</svg>";
+ return board;
+ }
+
+ getBaseSvgChessboard() {
+ let board = "";
+ const flipped = this.flippedBoard;
for (let i=0; i < this.size.x; i++) {
for (let j=0; j < this.size.y; j++) {
if (!this.onBoard(i, j))
/>`;
}
}
- board += "</svg>";
return board;
}
else
this[arrName] = ArrayFun.init(this.size.x, this.size.y, null);
if (arrName == "d_pieces")
- this.marks.forEach(([i, j]) => addPiece(i, j, arrName, "mark"));
+ this.marks.forEach((m) => {
+ const formattedSquare = C.SquareFromUsual(m);
+ const mCoords = C.SquareToCoords(formattedSquare);
+ addPiece(mCoords.x, mCoords.y, arrName, "mark");
+ });
};
if (this.marks)
conditionalReset("d_pieces");
y = (this.playerColor == i ? y = r.height + 5 : - 5 - rsqSize);
}
else {
- const sqSize = r.width / this.size.y;
+ const sqSize = r.width / Math.max(this.size.x, this.size.y);
const flipped = this.flippedBoard;
- x = (flipped ? this.size.y - 1 - j : j) * sqSize;
+ x = (flipped ? this.size.y - 1 - j : j) * sqSize +
+ Math.abs(this.size.x - this.size.y) * sqSize / 2;
y = (flipped ? this.size.x - 1 - i : i) * sqSize;
}
return [r.x + x, r.y + y];
continue outerLoop;
const oldIJ = [i, j];
[i, j] = this.increment([i, j], step);
- if (Math.abs(j - oldIJ[1]) > 1 || Math.abs(i - oldIJ[0]) > 1) {
+ if (
+ Math.abs(i - oldIJ[0]) != Math.abs(step[0]) ||
+ Math.abs(j - oldIJ[1]) != Math.abs(step[1])
+ ) {
// Boundary between segments (cylinder or circular mode)
segments.push([[segStart[0], segStart[1]], oldIJ]);
segStart = [i, j];
}
// Update castling flags if start or arrive from/at rook/king locations
move.appear.concat(move.vanish).forEach(psq => {
- if ((!!king && psq.p == king) || this.isKing(0, 0, psq.p))
+ if ((king && psq.p == king) || (!king && this.isKing(0, 0, psq.p)))
castleFlags[psq.c] = [this.size.y, this.size.y];
// NOTE: not "else if" because king can capture enemy rook...
let c = "";
if (this.hasCastle)
this.updateCastleFlags(move);
if (this.options["crazyhouse"]) {
- move.vanish.forEach(v => {
- const square = C.CoordsToSquare({x: v.x, y: v.y});
- if (this.ispawn[square])
- delete this.ispawn[square];
- });
if (move.appear.length > 0 && move.vanish.length > 0) {
// Assumption: something is moving
const initSquare = C.CoordsToSquare(move.start);
delete this.ispawn[destSquare];
}
}
+ move.vanish.forEach(v => {
+ const square = C.CoordsToSquare({x: v.x, y: v.y});
+ if (this.ispawn[square])
+ delete this.ispawn[square];
+ });
}
const minSize = Math.min(move.appear.length, move.vanish.length);
if (
if (this.options["teleport"]) {
if (
this.subTurnTeleport == 1 &&
- move.vanish.length > move.appear.length &&
+ move.vanish.length == 2 &&
+ move.appear.length == 1 &&
move.vanish[1].c == this.turn
) {
- const v = move.vanish[move.vanish.length - 1];
+ const v = move.vanish[1];
this.captured = {x: v.x, y: v.y, c: v.c, p: v.p};
this.subTurnTeleport = 2;
return;