////////////////////
// COORDINATES UTILS
- // a3 --> {x:10, y:3}
+ // 3a --> {x:3, y:10}
static SquareToCoords(sq) {
return ArrayFun.toObject(["x", "y"],
[0, 1].map(i => parseInt(sq[i], 36)));
}
- // {x:1, y:12} --> 1c
+ // {x:11, y:12} --> bc
static CoordsToSquare(cd) {
return Object.values(cd).map(c => c.toString(36)).join("");
}
// Turn "wb" into "B" (for FEN)
board2fen(b) {
- return b[0] == "w" ? b[1].toUpperCase() : b[1];
+ return (b[0] == "w" ? b[1].toUpperCase() : b[1]);
}
// Turn "p" into "bp" (for board)
fen2board(f) {
- return f.charCodeAt(0) <= 90 ? "w" + f.toLowerCase() : "b" + f;
+ return (f.charCodeAt(0) <= 90 ? "w" + f.toLowerCase() : "b" + f);
}
// Setup the initial random-or-not (asymmetric-or-not) position
}
else
this.r_pieces = { 'w': {}, 'b': {} };
- let chessboard =
+ let chessboard =
document.getElementById(this.containerId).querySelector(".chessboard");
if (!r)
r = chessboard.getBoundingClientRect();
// Am I allowed to move thing at square x,y ?
canIplay(x, y) {
- return (
- this.playerColor == this.turn &&
- (
- (typeof x == "number" && this.getColor(x, y) == this.turn) ||
- (typeof x == "string" && x == this.turn) //reserve
- )
- );
+ return (this.playerColor == this.turn && this.getColor(x, y) == this.turn);
}
////////////////////////
}
}
if (!this.options["rifle"])
- m.appear.pop(); //nothin appears
+ m.appear.pop(); //nothing appears
}
});
}
const lastRank = (color == "w" ? 0 : this.size.x - 1);
const initPiece = this.getPiece(moves[0].start.x, moves[0].start.y);
moves.forEach(m => {
- let finalPieces = ["p"];
const [x1, y1] = [m.start.x, m.start.y];
const [x2, y2] = [m.end.x, m.end.y];
const promotionOk = (
);
if (!promotionOk)
return; //nothing to do
- if (!this.options["pawnfall"]) {
- if (
- this.options["cannibal"] &&
- this.board[x2][y2] != "" &&
- this.getColor(x2, y2) == oppCol
- ) {
- finalPieces = [this.getPieceType(x2, y2)];
- }
- else
- finalPieces = this.pawnPromotions;
+ if (this.options["pawnfall"]) {
+ m.appear.shift();
+ return;
}
+ let finalPieces = ["p"];
+ if (
+ this.options["cannibal"] &&
+ this.board[x2][y2] != "" &&
+ this.getColor(x2, y2) == oppCol
+ ) {
+ finalPieces = [this.getPieceType(x2, y2)];
+ }
+ else
+ finalPieces = this.pawnPromotions;
m.appear[0].p = finalPieces[0];
if (initPiece == "!") //cannibal king-pawn
m.appear[0].p = C.CannibalKingCode[finalPieces[0]];
for (let i=1; i<finalPieces.length; i++) {
const piece = finalPieces[i];
- let tr = null;
- if (!this.options["pawnfall"]) {
- tr = {
- c: color,
- p: (initPiece != "!" ? piece : C.CannibalKingCode[piece])
- };
- }
+ const tr = {
+ c: color,
+ p: (initPiece != "!" ? piece : C.CannibalKingCode[piece])
+ };
let newMove = this.getBasicMove([x1, y1], [x2, y2], tr);
- if (this.options["pawnfall"]) {
- newMove.appear.shift();
- newMove.pawnfall = true; //required in prePlay()
- }
moreMoves.push(newMove);
}
});
m.appear[0].x == m.start.x &&
m.appear[0].y == m.start.y
) {
- const promotionPiece0 = this.pawnSpecs.promotions[0];
m.appear[0].p = this.pawnPromotions[0];
for (let i=1; i<this.pawnPromotions.length; i++) {
let newMv = JSON.parse(JSON.stringify(m));
p: this.getPiece(ex, ey)
})
);
- if (this.options["rifle"])
- // Rifle captures are tricky in combination with Atomic etc,
- // so it's useful to mark the move :
- mv.capture = true;
if (this.options["cannibal"] && destColor != initColor) {
const lastIdx = mv.vanish.length - 1;
let trPiece = mv.vanish[lastIdx].p;
prePlay(move) {
if (
- typeof move.start.x == "number" &&
- (!this.options["teleport"] || this.subTurnTeleport == 1)
+ this.hasCastle &&
+ // If flags already off, no need to re-check:
+ Object.keys(this.castleFlags).some(c => {
+ return this.castleFlags[c].some(val => val < this.size.y)})
) {
- // OK, not a drop move
- if (
- this.hasCastle &&
- // If flags already off, no need to re-check:
- Object.keys(this.castleFlags).some(c => {
- return this.castleFlags[c].some(val => val < this.size.y)})
- ) {
- this.updateCastleFlags(move);
- }
- const initSquare = C.CoordsToSquare(move.start);
- if (
- this.options["crazyhouse"] &&
- (!this.options["rifle"] || !move.capture)
- ) {
+ 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);
const destSquare = C.CoordsToSquare(move.end);
- if (this.ispawn[initSquare]) {
- delete this.ispawn[initSquare];
- this.ispawn[destSquare] = true;
- }
- else if (
- move.vanish[0].p == "p" &&
- move.appear[0].p != "p"
+ if (
+ this.ispawn[initSquare] ||
+ (move.vanish[0].p == "p" && move.appear[0].p != "p")
) {
this.ispawn[destSquare] = true;
}
}
}
const minSize = Math.min(move.appear.length, move.vanish.length);
- if (this.hasReserve && !move.pawnfall) {
+ if (
+ this.hasReserve &&
+ // Warning; atomic pawn removal isn't a capture
+ (!this.options["atomic"] || !this.rempawn || this.movesCount >= 1)
+ ) {
const color = this.turn;
for (let i=minSize; i<move.appear.length; i++) {
// Something appears = dropped on board (some exceptions, Chakart...)
- const piece = move.appear[i].p;
- this.updateReserve(color, piece, this.reserve[color][piece] - 1);
+ if (move.appear[i].c == color) {
+ const piece = move.appear[i].p;
+ this.updateReserve(color, piece, this.reserve[color][piece] - 1);
+ }
}
for (let i=minSize; i<move.vanish.length; i++) {
// Something vanish: add to reserve except if recycle & opponent
- const piece = move.vanish[i].p;
- if (this.options["crazyhouse"] || move.vanish[i].c == color)
+ if (
+ this.options["crazyhouse"] ||
+ (this.options["recycle"] && move.vanish[i].c == color)
+ ) {
+ const piece = move.vanish[i].p;
this.updateReserve(color, piece, this.reserve[color][piece] + 1);
+ }
}
}
}
return;
}
let movingPiece = this.getDomPiece(move.start.x, move.start.y);
+ if (!movingPiece) { //TODO this shouldn't be required
+ callback();
+ return;
+ }
const initTransform = movingPiece.style.transform;
let chessboard =
document.getElementById(this.containerId).querySelector(".chessboard");