buildMoveStack(move, r) {
this.moveStack.push(move);
this.computeNextMove(move);
- this.play(move);
- const newTurn = this.turn;
- if (this.moveStack.length == 1 && !this.hideMoves)
- this.playVisual(move, r);
- if (move.next) {
- this.gameState = {
- fen: this.getFen(),
- board: JSON.parse(JSON.stringify(this.board)) //easier
- };
- this.buildMoveStack(move.next, r);
- }
- else {
- if (this.moveStack.length == 1) {
- // Usual case (one normal move)
- this.afterPlay(this.moveStack, newTurn, {send: true, res: true});
- this.moveStack = []
+ const then = () => {
+ const newTurn = this.turn;
+ if (this.moveStack.length == 1 && !this.hideMoves)
+ this.playVisual(move, r);
+ if (move.next) {
+ this.gameState = {
+ fen: this.getFen(),
+ board: JSON.parse(JSON.stringify(this.board)) //easier
+ };
+ this.buildMoveStack(move.next, r);
}
else {
- this.afterPlay(this.moveStack, newTurn, {send: true, res: false});
- this.re_initFromFen(this.gameState.fen, this.gameState.board);
- this.playReceivedMove(this.moveStack.slice(1), () => {
- this.afterPlay(this.moveStack, newTurn, {send: false, res: true});
- this.moveStack = []
- });
+ if (this.moveStack.length == 1) {
+ // Usual case (one normal move)
+ this.afterPlay(this.moveStack, newTurn, {send: true, res: true});
+ this.moveStack = [];
+ }
+ else {
+ this.afterPlay(this.moveStack, newTurn, {send: true, res: false});
+ this.re_initFromFen(this.gameState.fen, this.gameState.board);
+ this.playReceivedMove(this.moveStack.slice(1), () => {
+ this.afterPlay(this.moveStack, newTurn, {send: false, res: true});
+ this.moveStack = [];
+ });
+ }
}
- }
+ };
+ // If hiding moves, then they are revealed in play() with callback
+ this.play(move, this.hideMoves ? then : null);
+ if (!this.hideMoves)
+ then();
}
// Implemented in variants using (automatic) moveStack
launchAnimation(moves, container, callback) {
if (this.hideMoves) {
- moves.forEach(m => this.play(m));
- callback();
+ for (let i=0; i<moves.length; i++)
+ // If hiding moves, they are revealed into play():
+ this.play(moves[i], i == moves.length - 1 ? callback : () => {});
return;
}
const r = container.querySelector(".chessboard").getBoundingClientRect();
genRandInitBaseFen() {
let baseFen = super.genRandInitBaseFen();
- return { fen: baseFen.fen.replace("rnbqkbnr/pppppppp", "4k3/8"), o: {} };
- }
-
- getPartFen(o) {
- let parts = super.getPartFen(o);
- parts["flags"] = parts["flags"].substr(0, 2) + "88";
- return parts;
+ return {
+ fen: baseFen.fen.replace("rnbqkbnr/pppppppp", "4k3/8"),
+ o: {flags: baseFen.o.flags.substr(0, 2) + "88"}
+ };
}
initReserves() {
for (let c of ['w', 'b']) {
const myMove = res[c + 'm'], oppMove = res[C.GetOppCol(c) + 'm'];
if (
- myMove.end.x == oppMove.start.x &&
- myMove.end.y == oppMove.start.y
+ // More general test than checking moves ends,
+ // because of potential pawn relocation
+ myMove.vanish.length == 2 &&
+ myMove.vanish[1].x == oppMove.start.x &&
+ myMove.vanish[1].y == oppMove.start.y
) {
// Whatever was supposed to vanish, finally doesn't vanish
myMove.vanish.pop();
// Collision (necessarily on empty square)
if (!res.wm.illegal && !res.bm.illegal) {
if (res.wm.vanish[0].p != res.bm.vanish[0].p) {
- const c = (res.wm.vanish[0].p == 'n' ? 'w' : 'b');
- res[c + 'm'].vanish.push(res[C.GetOppCol(c) + 'm'].appear.shift());
+ const vanishColor = (res.wm.vanish[0].p == 'n' ? 'b' : 'w');
+ res[vanishColor + 'm'].appear.shift();
}
else {
// Collision of two pieces of same nature: both disappear
return res;
}
- play(move) {
+ play(move, callback) {
const color = this.turn;
if (color == 'w')
this.whiteMove.push(move);
this.playOnBoard(move);
this.playVisual(move);
}
+ callback();
return;
}
if (color == this.playerColor && this.firstMove) {
if (color == 'b') {
// A full turn just ended
const res = this.resolveSynchroneMove(move);
- const callback = () => {
+ const afterAnimate = () => {
// start + end don't matter for playOnBoard() and playVisual().
// Merging is necessary because moves may overlap.
let toPlay = {appear: [], vanish: []};
}
this.playOnBoard(toPlay);
this.playVisual(toPlay);
+ callback();
};
if (res.wm)
- this.animate(res.wm, () => {if (!res.bm) callback();});
+ this.animate(res.wm, () => {if (!res.bm) afterAnimate();});
if (res.bm)
- this.animate(res.bm, callback);
+ this.animate(res.bm, afterAnimate);
if (!res.wm && !res.bm) {
this.displayIllegalInfo("both illegal");
['w', 'b'].forEach(c => this.penalties[c]++);
}
this.whiteMove = [];
}
+ else
+ callback();
}
displayIllegalInfo(msg) {
return "*";
}
// Count footmen: if a side has none, it loses
- let fmCount = { 'w': 0, 'b': 0 };
- for (let i=0; i<5; i++) {
- for (let j=0; j<5; j++) {
+ let fmCount = {w: 0, b: 0};
+ for (let i=0; i<this.size.x; i++) {
+ for (let j=0; j<this.size.y; j++) {
if (this.board[i][j] != "" && this.getPiece(i, j) == 'p')
fmCount[this.getColor(i, j)]++;
}
div.illegal-text {
position: relative;
- margin-top: 5%;
+ margin-top: 15px;
width: 100%;
text-align: center;
background-color: transparent;
moves.push(this.getBasicMove([x, y], [x + shiftX, nextY]));
}
}
- this.pawnPostProcess(moves, color, oppCol);
+ moves = super.pawnPostProcess(moves, color, oppCol);
// Add mushroom on before-last square (+ potential segments)
moves.forEach(m => {
let [mx, my] = [x, y];
)
) {
// "Forgotten" promotion, which occurred after some effect
- let moves = [move];
- super.pawnPostProcess(moves, color, C.GetOppCol(color));
+ let moves = super.pawnPostProcess([move], color, C.GetOppCol(color));
super.showChoices(moves, r);
}
else
}
computeNextMove(move) {
+ if (move.koopa)
+ return null;
// Set potential random effects, so that play() is deterministic
// from opponent viewpoint:
const endPiece = this.getPiece(move.end.x, move.end.y);
p: this.getPiece(move.start.x, move.start.y)
}));
}
+ em.koopa = true; //avoid applying effect
break;
case "chomp":
// Eat piece
div.bonus-text {
position: relative;
- margin-top: 5%;
+ margin-top: 15px;
width: 100%;
text-align: center;
background-color: transparent;