static get Options() {
return {
select: C.Options.select,
- check: [],
+ input: [
+ {
+ label: "Cleopatra",
+ variable: "cleopatra",
+ type: "checkbox",
+ defaut: false
+ }
+ ],
styles: [
"balance",
"cylinder",
return false;
}
- // Find potential captures from a square
- // follow steps from x,y until something is met.
- findAttacks([x, y]) {
- const [color, piece] = [this.getColor(x, y), this.getPiece(x, y)];
- const oppCol = C.GetOppCol(color);
- let squares = {};
- const specs = this.pieces(color, x, y)[piece];
- const attacks = specs.attack || specs.moves;
- for (let a of attacks) {
- outerLoop: for (let step of a.steps) {
- let [i, j] = [x + step[0], this.computeY(y + step[1])];
- let nbSteps = 1;
- while (this.onBoard(i, j) && this.board[i][j] == "") {
- if (a.range <= nbSteps++) continue outerLoop;
- i += step[0];
- j = this.computeY(j + step[1]);
- }
- if (this.onBoard(i, j) && this.getColor(i, j) == oppCol)
- squares[C.CoordsToSquare({x: i, y: j})] = true;
- }
- }
- return Object.keys(squares);
+ pieces(color, x, y) {
+ if (!this.options["cleopatra"])
+ return super.pieces(color, x, y);
+ const allSpecs = super.pieces(color, x, y);
+ return Object.assign({},
+ allSpecs,
+ {'q': Object.assign({}, allSpecs['q'], {"class": "cleopatra"})}
+ );
}
postProcessPotentialMoves(moves) {
- if (moves.length == 0) return moves;
- const [x, y] = [moves[0].end.x, moves[0].end.y];
- const color = this.getColor(moves[0].start.x, moves[0].start.y);
- const oppCol = C.GetOppCol(color);
- moves = super.postProcessPotentialMoves(moves);
moves.forEach(m => {
- this.playOnBoard(m);
- let attacks;
- if (this.options["zen"]) {
- let endSquares = {};
- super.getZenCaptures(x, y).forEach(c => {
- endSquares[C.CoordsToSquare(c.end)] = true;
- });
- attacks = Object.keys(endSquares);
+ m.flips = [];
+ if (!this.options["cleopatra"] || m.vanish[0].p == 'q') {
+ super.playOnBoard(m);
+ let attacks = super.findDestSquares(
+ [m.end.x, m.end.y],
+ {attackOnly: true, segments: false},
+ ([x, y] => this.canTake([m.end.x, m.end.y], [x, y]))
+ );
+ if (this.options["zen"]) {
+ const zenAttacks = super.findCapturesOn(
+ [m.end.x, m.end.y],
+ {segments: false},
+ ([x, y] => this.canTake([m.end.x, m.end.y], [x, y]))
+ );
+ Array.prototype.push.apply(attacks, zenAttacks);
+ }
+ super.undoOnBoard(m);
+ attacks.forEach(a => m.flips.push({x: a.sq[0], y: a.sq[1]}));
}
- else attacks = this.findAttacks([m.end.x, m.end.y])
- this.undoOnBoard(m);
- attacks.map(C.SquareToCoords).forEach(a => {
- const p = this.getPiece(a.x, a.y);
- m.appear.push(new PiPo({x: a.x, y: a.y, c: color, p: p}));
- m.vanish.push(new PiPo({x: a.x, y: a.y, c: oppCol, p: p}));
- });
});
return moves;
}
- // Moves cannot flip our king's color, so (almost) all are valid
+ playOnBoard(move) {
+ super.playOnBoard(move);
+ this.flipColorOf(move.flips);
+ }
+ undoOnBoard(move) {
+ super.undoOnBoard(move);
+ this.flipColorOf(move.flips);
+ }
+
+ flipColorOf(flips) {
+ for (let xy of flips) {
+ const newColor = C.GetOppCol(this.getColor(xy.x, xy.y));
+ this.board[xy.x][xy.y] = newColor + this.board[xy.x][xy.y][1];
+ }
+ }
+
+ // Moves cannot flip our king's color, so all are valid
filterValid(moves) {
- if (this.options["balance"] && [1, 3].includes(this.movesCount))
- return moves.filter(m => m.vanish.every(v => v.p != C.KING));
return moves;
}
- // Since it's used just for the king, and there are no captures:
- underCheck(square, color) {
+ // A king under (regular) check flips color, and the game is over.
+ underCheck() {
return false;
}
+ playVisual(move, r) {
+ super.playVisual(move, r);
+ move.flips.forEach(f => {
+ this.g_pieces[f.x][f.y].classList.toggle("white");
+ this.g_pieces[f.x][f.y].classList.toggle("black");
+ });
+ }
+
};