const steps = this.pieces(this.playerColor)["p"].attack[0].steps;
for (let step of steps) {
const x = this.epSquare.x - step[0],
- y = this.computeY(this.epSquare.y - step[1]);
+ y = this.getY(this.epSquare.y - step[1]);
if (
this.onBoard(x, y) &&
this.getColor(x, y) == this.playerColor &&
////////////////////
// MOVES GENERATION
- // For Cylinder: get Y coordinate
- computeY(y) {
+ // Return negative y to say "h to a" or "a to h"
+ getY_withSign(y) {
if (!this.options["cylinder"])
return y;
let res = y % this.size.y;
if (res < 0)
- res += this.size.y;
+ // Off-board, "teleportation" marked with negative sign:
+ return - (res + this.size.y);
return res;
}
+ // For Cylinder: get Y coordinate
+ getY(y) {
+ return Math.abs(this.getY_withSign(y));
+ }
+
// Stop at the first capture found
atLeastOneCapture(color) {
color = color || this.turn;
const attacks = specs.attack || specs.moves;
for (let a of attacks) {
outerLoop: for (let step of a.steps) {
- let [ii, jj] = [i + step[0], this.computeY(j + step[1])];
+ let [ii, jj] = [i + step[0], this.getY(j + step[1])];
let stepCounter = 1;
while (this.onBoard(ii, jj) && this.board[ii][jj] == "") {
if (a.range <= stepCounter++)
continue outerLoop;
ii += step[0];
- jj = this.computeY(jj + step[1]);
+ jj = this.getY(jj + step[1]);
}
if (
this.onBoard(ii, jj) &&
];
for (let step of steps) {
let x = m.end.x + step[0];
- let y = this.computeY(m.end.y + step[1]);
+ let y = this.getY(m.end.y + step[1]);
if (
this.onBoard(x, y) &&
this.board[x][y] != "" &&
if (a.range <= stepCounter++)
continue outerLoop;
i += step[0];
- j = this.computeY(j + step[1]);
+ j = this.getY(j + step[1]);
}
if (
this.onBoard(i, j) &&
const findAddMoves = (type, stepArray) => {
for (let s of stepArray) {
- // TODO: if jump in y (computeY, Cylinder), move.segments
outerLoop: for (let step of s.steps) {
- let [i, j] = [x + step[0], this.computeY(y + step[1])];
- let stepCounter = 1;
- while (this.onBoard(i, j) && this.board[i][j] == "") {
- if (type != "attack" && !explored[i + "." + j]) {
+ let segments = [];
+ let segStart = [x, y],
+ segEnd = [];
+ let [i, j] = [x, y];
+ let stepCounter = 0;
+ while (
+ this.onBoard(i, j) &&
+ (this.board[i][j] == "" || (i == x && j == y))
+ ) {
+ if (
+ type != "attack" &&
+ !explored[i + "." + j] &&
+ (i != x || j != y)
+ ) {
explored[i + "." + j] = true;
- moves.push(this.getBasicMove([x, y], [i, j]));
+ moves.push(
+
+
+
+
+/////////////
+
+
+
+ this.getBasicMove([x, y], [i, j]));
}
if (s.range <= stepCounter++)
continue outerLoop;
+ const oldIJ = [i, j];
i += step[0];
- j = this.computeY(j + step[1]);
+ j = this.getY_withSign(j + step[1]);
+ if (j < 0) {
+ // Boundary between segments (cylinder mode)
+ j = -j;
+ segEnd = oldIJ;
+ segments.push(JSON.parse(JSON.stringify([segStart, segEnd])));
+ segStart = [];
+ }
+ else if (segStart.length == 0)
+ segStart = oldIJ;
}
if (!this.onBoard(i, j))
continue;
if (specialAttack)
findAddMoves("attack", stepSpec.attack);
findAddMoves(specialAttack ? "moveonly" : "all", stepSpec.moves);
- if (this.options["zen"])
- Array.prototype.push.apply(moves, this.findCapturesOn([x, y], true));
+ if (this.options["zen"]) {
+ Array.prototype.push.apply(moves,
+ this.findCapturesOn([x, y], {zen: true}));
+ }
return moves;
}
- findCapturesOn([x, y], zen) {
+ // Search for enemy (or not) pieces attacking [x, y]
+ findCapturesOn([x, y], args) {
let moves = [];
- // Find reverse captures (opponent takes)
- const color = this.getColor(x, y);
- const oppCol = C.GetOppCol(color);
+ if (!args.oppCol)
+ args.oppCol = C.GetOppCol(this.getColor(x, y) || this.turn);
for (let i=0; i<this.size.x; i++) {
for (let j=0; j<this.size.y; j++) {
if (
this.board[i][j] != "" &&
- this.canTake([i, j], [x, y]) &&
+ this.getColor(i, j) == args.oppCol &&
!this.isImmobilized([i, j])
) {
- if (zen && this.isKing(this.getPiece(i, j)))
+ if (args.zen && this.isKing(this.getPiece(i, j)))
continue; //king not captured in this way
- const stepSpec = this.pieces(oppCol, i, j)[this.getPieceType(i, j)];
+ const stepSpec =
+ this.pieces(args.oppCol, i, j)[this.getPieceType(i, j)];
const attacks = stepSpec.attack || stepSpec.moves;
for (let a of attacks) {
for (let s of a.steps) {
if (!C.CompatibleStep([i, j], [x, y], s, a.range))
continue;
// Finally verify that nothing stand in-between
- let [ii, jj] = [i + s[0], this.computeY(j + s[1])];
+ let [ii, jj] = [i + s[0], this.getY(j + s[1])];
let stepCounter = 1;
- while (this.onBoard(ii, jj) && this.board[ii][jj] == "") {
+ while (
+ this.onBoard(ii, jj) &&
+ this.board[ii][jj] == "" &&
+ (ii != x || jj != y) //condition to attack empty squares too
+ ) {
ii += s[0];
- jj = this.computeY(jj + s[1]);
+ jj = this.getY(jj + s[1]);
}
if (ii == x && jj == y) {
- moves.push(this.getBasicMove([x, y], [i, j]));
- if (!zen)
+ if (args.zen)
+ // Reverse capture:
+ moves.push(this.getBasicMove([x, y], [i, j]));
+ else
+ moves.push(this.getBasicMove([i, j], [x, y]));
+ if (args.one)
return moves; //test for underCheck
}
}
if (
!!this.epSquare &&
this.epSquare.x == x + shiftX &&
- Math.abs(this.computeY(this.epSquare.y - y)) == 1 &&
+ Math.abs(this.getY(this.epSquare.y - y)) == 1 &&
this.getColor(x, this.epSquare.y) == oppCol //Doublemove guard...
) {
const [epx, epy] = [this.epSquare.x, this.epSquare.y];
////////////////////
// MOVES VALIDATION
- // Is (king at) given position under check by "color" ?
- underCheck([x, y], color) {
+ // Is (king at) given position under check by "oppCol" ?
+ underCheck([x, y], oppCol) {
if (this.options["taking"] || this.options["dark"])
return false;
- return (this.findCapturesOn([x, y]).length >= 1);
+ return (
+ this.findCapturesOn([x, y], {oppCol: oppCol, one: true}).length >= 1
+ );
}
// Stop at first king found (TODO: multi-kings)
let container =
document.getElementById(this.containerId)
const r = container.querySelector(".chessboard").getBoundingClientRect();
+ if (typeof move.start.x == "string") {
+ // Need to bound width/height (was 100% for reserve pieces)
+ const pieceWidth = this.getPieceWidth(r.width);
+ movingPiece.style.width = pieceWidth + "px";
+ movingPiece.style.height = pieceWidth + "px";
+ }
const maxDist = this.getMaxDistance(r.width);
const pieces = this.pieces();
if (move.drag) {