tryChangeTurn(move) {
if (this.isLastMove(move)) {
- this.turn = (this.turn == 'w' ? 'b' : 'w');
+ this.turn = C.GetOppTurn(this.turn);
this.movesCount++;
this.subTurn = 1;
}
playVisual(move, r) {
move.vanish.forEach(v => {
- this.g_pieces[v.x][v.y].remove();
+ if (this.g_pieces[v.x][v.y]) //can be null (e.g. Apocalypse)
+ this.g_pieces[v.x][v.y].remove();
this.g_pieces[v.x][v.y] = null;
});
let chessboard =
animateMoving(start, end, drag, segments, cb) {
let initPiece = this.getDomPiece(start.x, start.y);
+ if (!initPiece) { //TODO: shouldn't occur!
+ cb();
+ return;
+ }
// NOTE: cloning often not required, but light enough, and simpler
let movingPiece = initPiece.cloneNode();
initPiece.style.opacity = "0";
{name: 'Avalam', desc: 'Build towers'},
{name: 'Avalanche', desc: 'Pawnfalls'},
{name: 'Balaklava', desc: 'Meet the Mammoth'},
+ {name: "Balanced", desc: "Balanced chess"},
{name: 'Bario', desc: 'A quantum story'},
- {name: "Balanced", desc: "balanced chess"},
{name: 'Baroque', desc: 'Exotic captures'},
{name: "Benedict", desc: "Change colors"},
{name: 'Berolina', desc: 'Pawns move diagonally'},
piece.black.rook {
- background-image: url('/variants/Alapo/pieces/black_SQUARE.svg');
+ background-image: url('/pieces/Alapo/black_SQUARE.svg');
}
piece.black.bishop {
- background-image: url('/variants/Alapo/pieces/black_TRIANGLE.svg');
+ background-image: url('/pieces/Alapo/black_TRIANGLE.svg');
}
piece.black.bishop_inv {
- background-image: url('/variants/Alapo/pieces/black_TRIANGLE_inv.svg');
+ background-image: url('/pieces/Alapo/black_TRIANGLE_inv.svg');
}
piece.black.queen {
- background-image: url('/variants/Alapo/pieces/black_CIRCLE.svg');
+ background-image: url('/pieces/Alapo/black_CIRCLE.svg');
}
piece.black.babyrook {
- background-image: url('/variants/Alapo/pieces/black_square.svg');
+ background-image: url('/pieces/Alapo/black_square.svg');
}
piece.black.babybishop {
- background-image: url('/variants/Alapo/pieces/black_triangle.svg');
+ background-image: url('/pieces/Alapo/black_triangle.svg');
}
piece.black.babybishop_inv {
- background-image: url('/variants/Alapo/pieces/black_triangle_inv.svg');
+ background-image: url('/pieces/Alapo/black_triangle_inv.svg');
}
piece.black.babyqueen {
- background-image: url('/variants/Alapo/pieces/black_circle.svg');
+ background-image: url('/pieces/Alapo/black_circle.svg');
}
piece.white.rook {
- background-image: url('/variants/Alapo/pieces/white_SQUARE.svg');
+ background-image: url('/pieces/Alapo/white_SQUARE.svg');
}
piece.white.bishop {
- background-image: url('/variants/Alapo/pieces/white_TRIANGLE.svg');
+ background-image: url('/pieces/Alapo/white_TRIANGLE.svg');
}
piece.white.bishop_inv {
- background-image: url('/variants/Alapo/pieces/white_TRIANGLE_inv.svg');
+ background-image: url('/pieces/Alapo/white_TRIANGLE_inv.svg');
}
piece.white.queen {
- background-image: url('/variants/Alapo/pieces/white_CIRCLE.svg');
+ background-image: url('/pieces/Alapo/white_CIRCLE.svg');
}
piece.white.babyrook {
- background-image: url('/variants/Alapo/pieces/white_square.svg');
+ background-image: url('/pieces/Alapo/white_square.svg');
}
piece.white.babybishop {
- background-image: url('/variants/Alapo/pieces/white_triangle.svg');
+ background-image: url('/pieces/Alapo/white_triangle.svg');
}
piece.white.babybishop_inv {
- background-image: url('/variants/Alapo/pieces/white_triangle_inv.svg');
+ background-image: url('/pieces/Alapo/white_triangle_inv.svg');
}
piece.white.babyqueen {
- background-image: url('/variants/Alapo/pieces/white_circle.svg');
+ background-image: url('/pieces/Alapo/white_circle.svg');
}
-import GoRules from "/variants/Weiqi/class.js";
+import WeiqiRules from "/variants/Weiqi/class.js";
import Move from "/utils/Move.js";
import PiPo from "/utils/PiPo.js";
import {ArrayFun} from "/utils/array.js";
if (height == 5)
return [];
let moves = [];
- for (let s of this.pieces()['b'].moves[0].steps) {
+ for (let s of this.pieces(this.turn, x, y)['b'].both[0].steps) {
const [i, j] = [x + s[0], y + s[1]];
if (
this.onBoard(i, j) &&
piece.white.stack {
- background-image: url('/variants/Avalam/pieces/white_stack.svg');
+ background-image: url('/pieces/Avalam/white_stack.svg');
}
piece.white.stack2 {
- background-image: url('/variants/Avalam/pieces/white_stack2.svg');
+ background-image: url('/pieces/Avalam/white_stack2.svg');
}
piece.white.stack3 {
- background-image: url('/variants/Avalam/pieces/white_stack3.svg');
+ background-image: url('/pieces/Avalam/white_stack3.svg');
}
piece.white.stack4 {
- background-image: url('/variants/Avalam/pieces/white_stack4.svg');
+ background-image: url('/pieces/Avalam/white_stack4.svg');
}
piece.white.stack5 {
- background-image: url('/variants/Avalam/pieces/white_stack5.svg');
+ background-image: url('/pieces/Avalam/white_stack5.svg');
}
piece.black.stack {
- background-image: url('/variants/Avalam/pieces/black_stack.svg');
+ background-image: url('/pieces/Avalam/black_stack.svg');
}
piece.black.stack2 {
- background-image: url('/variants/Avalam/pieces/black_stack2.svg');
+ background-image: url('/pieces/Avalam/black_stack2.svg');
}
piece.black.stack3 {
- background-image: url('/variants/Avalam/pieces/black_stack3.svg');
+ background-image: url('/pieces/Avalam/black_stack3.svg');
}
piece.black.stack4 {
- background-image: url('/variants/Avalam/pieces/black_stack4.svg');
+ background-image: url('/pieces/Avalam/black_stack4.svg');
}
piece.black.stack5 {
- background-image: url('/variants/Avalam/pieces/black_stack5.svg');
+ background-image: url('/pieces/Avalam/black_stack5.svg');
}
.board-sq {
static get Options() {
return {
select: C.Options.select,
+ input: [
+ {
+ label: "Balanced",
+ variable: "balanced",
+ type: "checkbox",
+ defaut: false
+ }
+ ],
styles: [
"atomic",
"cannibal",
return false;
}
- postPlay(move) {
+ tryChangeTurn(move) {
const color = this.turn;
const oppCol = C.GetOppTurn(color);
- this.promotion = (
- this.subTurn == 2 &&
- move.end.x == (oppCol == 'w' ? 0 : this.size.x - 1) &&
- move.vanish[0].p == 'p'
- );
- if (this.subTurn == 0) {
- this.subTurn++;
- if (!this.atLeastOneMove(color)) {
- move.result = "1/2"; //avoid re-computation
- this.turn = oppCol;
+ const incrementTurn = () => {
+ if (this.options["balanced"] && this.movesCount == 0) {
+ // No pawn push on move 1:
+ return true;
}
- }
- else if (this.subTurn == 2) {
- this.turn = oppCol;
- this.subTurn = this.promotion ? 0 : 1;
- }
- else { //subTurn == 1, usual case
+ this.promotion = (
+ this.subTurn == 2 &&
+ move.end.x == (oppCol == 'w' ? 0 : this.size.x - 1) &&
+ move.vanish[0].p == 'p'
+ );
+ if (this.subTurn == 0) {
+ this.subTurn++;
+ if (!this.atLeastOneMove(color)) {
+ move.result = "1/2"; //avoid re-computation
+ return true;
+ }
+ return false;
+ }
+ if (this.subTurn == 2) {
+ this.subTurn = (this.promotion ? 0 : 1);
+ return true;
+ }
+ // subTurn == 1, usual case
const kingCapture = this.searchKingPos(oppCol).length == 0;
if (kingCapture)
move.result = (color == 'w' ? "1-0" : "0-1");
- if (!kingCapture && this.atLeastOnePawnPush(oppCol))
- this.subTurn++;
- else {
- this.turn = oppCol;
- this.subTurn = this.promotion ? 0 : 1;
+ if (kingCapture || !this.atLeastOnePawnPush(oppCol)) {
+ this.subTurn = (this.promotion ? 0 : 1);
+ return true;
}
+ // A pawn push is possible: usual case
+ this.subTurn++;
+ return false;
+ };
+ if (incrementTurn()) {
+ this.turn = oppCol;
+ this.movesCount++;
}
}
<p>
After each normal move, push an opponent pawn one square forward.
If the pawn promotes, its owner will select into which piece on next turn.
+ In balanced Avalanche, white has no pawn push at the first move.
</p>
<p>The goal is either to checkmate or to capture the enemy king.</p>
pieces(color, x, y) {
let res = super.pieces(color, x, y);
- const knightSpec = res['n'];
+ const knightSpecMoves = res['n'].both;
delete res['n'];
res['m'] = {
"class": "mammoth",
}
]
};
- ['p', 'r', 'b', 'm', 'q'].forEach(p => res[p].moves = knightSpec.moves);
+ ['p', 'r', 'b', 'm', 'q'].forEach(p => {
+ if (!res[p].moves)
+ res[p].moves = [];
+ Array.prototype.push.apply(res[p].moves, knightSpecMoves);
+ });
return res;
}
return {
fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" +
s.w.join("").toUpperCase(),
- o: {}
+ o: {flags: s.flags}
};
}
@import url("/base_pieces.css");
piece.white.mammoth {
- background-image: url('/variants/Balaklava/pieces/white_mammoth.svg');
+ background-image: url('/pieces/Balaklava/white_mammoth.svg');
}
piece.black.mammoth {
- background-image: url('/variants/Balaklava/pieces/black_mammoth.svg');
+ background-image: url('/pieces/Balaklava/black_mammoth.svg');
}
-import AbstractSpecialCaptureRules from "/variants/_SpecialCaptures.js";
+import AbstractSpecialCaptureRules from "/variants/_SpecialCaptures/class.js";
import {FenUtil} from "/utils/setupPieces.js";
import {Random} from "/utils/alea.js";
const piece = this.getPiece(x, y);
const color = this.getColor(x, y);
const oppCol = C.GetOppTurn(color);
- const adjacentSteps = this.pieces()['k'].moves[0].steps;
+ const adjacentSteps = this.pieces()['k'].both[0].steps;
for (let step of adjacentSteps) {
const [i, j] = [x + step[0], this.getY(y + step[1])];
if (
@import url("/variants/_SpecialCaptures/style.css");
piece.white.immobilizer {
- background-image: url('/variants/Baroque/pieces/white_immobilizer.svg');
+ background-image: url('/pieces/Baroque/white_immobilizer.svg');
}
piece.black.immobilizer {
- background-image: url('/variants/Baroque/pieces/black_immobilizer.svg');
+ background-image: url('/pieces/Baroque/black_immobilizer.svg');
}
@import url("/base_pieces.css");
piece.black.cleopatra {
- background-image: url('/variants/Benedict/pieces/black_cleopatra.svg');
+ background-image: url('/pieces/Benedict/black_cleopatra.svg');
}
piece.white.cleopatra {
- background-image: url('/variants/Benedict/pieces/white_cleopatra.svg');
+ background-image: url('/pieces/Benedict/white_cleopatra.svg');
}
@import url("/base_pieces.css");
piece.egg {
- background-image: url('/variants/Chakart/pieces/egg.svg');
+ background-image: url('/pieces/Chakart/egg.svg');
}
piece.mushroom {
- background-image: url('/variants/Chakart/pieces/mushroom.svg');
+ background-image: url('/pieces/Chakart/mushroom.svg');
}
piece.banana {
- background-image: url('/variants/Chakart/pieces/banana.svg');
+ background-image: url('/pieces/Chakart/banana.svg');
}
piece.bomb {
- background-image: url('/variants/Chakart/pieces/bomb.svg');
+ background-image: url('/pieces/Chakart/bomb.svg');
}
piece.white.invisible {
}
piece.remote-capture {
- background-image: url('/variants/Chakart/pieces/shell.svg');
+ background-image: url('/pieces/Chakart/shell.svg');
}
piece.white.mystery {
@import url("/base_pieces.css");
piece.checkered.pawn {
- background-image: url('/variants/Checkered/pieces/cp.svg');
+ background-image: url('/pieces/Checkered/cp.svg');
}
piece.checkered.rook {
- background-image: url('/variants/Checkered/pieces/cr.svg');
+ background-image: url('/pieces/Checkered/cr.svg');
}
piece.checkered.knight {
- background-image: url('/variants/Checkered/pieces/cn.svg');
+ background-image: url('/pieces/Checkered/cn.svg');
}
piece.checkered.bishop {
- background-image: url('/variants/Checkered/pieces/cb.svg');
+ background-image: url('/pieces/Checkered/cb.svg');
}
piece.checkered.queen {
- background-image: url('/variants/Checkered/pieces/cq.svg');
+ background-image: url('/pieces/Checkered/cq.svg');
}
div.info-text {
}
piece.white.stone {
- background-image: url('/variants/Weiqi/pieces/black_stone.svg');
+ background-image: url('/pieces/Weiqi/black_stone.svg');
}
piece.black.stone, piece.white.stone.one-color {
- background-image: url('/variants/Weiqi/pieces/white_stone.svg');
+ background-image: url('/pieces/Weiqi/white_stone.svg');
}
button.pass-btn {
@import url("/base_pieces.css");
piece.black.antiking {
- background-image: url('/variants/_Antiking/pieces/black_antiking.svg');
+ background-image: url('/pieces/_Antiking/black_antiking.svg');
}
piece.white.antiking {
- background-image: url('/variants/_Antiking/pieces/white_antiking.svg');
+ background-image: url('/pieces/_Antiking/white_antiking.svg');
}
piece.black.pawn {
- background-image: url('/variants/_Berolina/pieces/black_pawn.svg');
+ background-image: url('/pieces/_Berolina/black_pawn.svg');
}
piece.white.pawn {
- background-image: url('/variants/_Berolina/pieces/white_pawn.svg');
+ background-image: url('/pieces/_Berolina/white_pawn.svg');
}
[i, j] = [i + step[0], this.getY(j + step[1])];
while (this.onBoard(i, j) && this.board[i][j] == "") {
let mv = this.getBasicMove([x, y], [i, j]);
- Array.prorotype.push.apply(mv.vanish, vanished);
+ Array.prototype.push.apply(mv.vanish, vanished);
moves.push(mv);
[i, j] = [i + step[0], this.getY(j + step[1])];
}
getChameleonCaptures(moves, pushPullType, onlyOneJump) {
const [x, y] = [moves[0].start.x, moves[0].start.y];
moves = moves.concat(
- this.getKnightCaptures([x, y], "asChameleon", onlyOneJump));
+ this.getLeaperCaptures([x, y], "asChameleon", onlyOneJump));
// No "king capture" because king cannot remain under check
this.addPincerCaptures(moves, "asChameleon");
this.addCoordinatorCaptures(moves, "asChameleon");
moves.forEach(m => {
const [ex, ey] = [m.end.x, m.end.y];
const step = [
- ex != x ? (ex - x) / Math.abs(ex - x) : 0,
- ey != y ? (ey - y) / Math.abs(ey - y) : 0
+ ex != sx ? (ex - sx) / Math.abs(ex - sx) : 0,
+ ey != sy ? (ey - sy) / Math.abs(ey - sy) : 0
];
let vanishPull, vanishPush;
if (type != "pull") {
}
}
if (capturingPullDir[step[0] + "." + step[1]]) {
- const [bi, bj] = [x - step[0], this.getY(y - step[1])];
+ const [bi, bj] = [sx - step[0], this.getY(sy - step[1])];
vanishPull =
new PiPo({x: bi, y: bj, p: this.getPiece(bi, bj), c: oppCol});
}
.piece.white.push-action {
- background-image: url('/variants/_SpecialCaptures/pieces/capture_push.svg');
+ background-image: url('/pieces/_SpecialCaptures/capture_push.svg');
}
.piece.white.pull-action {
- background-image: url('/variants/_SpecialCaptures/pieces/capture_pull.svg');
+ background-image: url('/pieces/_SpecialCaptures/capture_pull.svg');
}