+ let move = super.getBasicMove([x1, y1], [x2, y2], tr);
+ const color1 = this.getColor(x1, y1);
+ const color2 = this.getColor(x2, y2);
+ const piece1 = this.getPiece(x1, y1);
+ const piece2 = this.getPiece(x2, y2);
+ const oppCol = V.GetOppCol(color1);
+ if (
+ [V.PAWN, V.KNIGHT].includes(piece1) &&
+ (color2 != 'a' || !([V.BANANA, V.BOMB].includes(piece2)))
+ ) {
+ switch (piece1) {
+ case V.PAWN: {
+ const twoSquaresMove = (Math.abs(x2 - x1) == 2);
+ const mushroomX = x1 + (twoSquaresMove ? (x2 - x1) / 2 : 0);
+ move.appear.push(
+ new PiPo({
+ x: mushroomX,
+ y: y1,
+ c: 'a',
+ p: V.MUSHROOM
+ })
+ );
+ if (this.getColor(mushroomX, y1) == 'a') {
+ move.vanish.push(
+ new PiPo({
+ x: mushroomX,
+ y: y1,
+ c: 'a',
+ p: this.getPiece(mushroomX, y1)
+ })
+ );
+ }
+ break;
+ }
+ case V.KNIGHT: {
+ const deltaX = Math.abs(x2 - x1);
+ const deltaY = Math.abs(y2 - y1);
+ const eggSquare = [
+ x1 + (deltaX == 2 ? (x2 - x1) / 2 : 0),
+ y1 + (deltaY == 2 ? (y2 - y1) / 2 : 0)
+ ];
+ if (
+ this.board[eggSquare[0]][eggSquare[1]] == V.EMPTY ||
+ this.getColor(eggSquare[0], eggSquare[1]) == 'a'
+ ) {
+ move.appear.push(
+ new PiPo({
+ x: eggSquare[0],
+ y: eggSquare[1],
+ c: 'a',
+ p: V.EGG
+ })
+ );
+ if (this.getColor(eggSquare[0], eggSquare[1]) == 'a') {
+ move.vanish.push(
+ new PiPo({
+ x: eggSquare[0],
+ y: eggSquare[1],
+ c: 'a',
+ p: this.getPiece(eggSquare[0], eggSquare[1])
+ })
+ );
+ }
+ }
+ break;
+ }
+ }
+ }
+ const applyBeffect = (steps) => {
+ const [x, y] = [move.appear[0].x, move.appear[0].y];
+ const moveTo = this.getRandomSquare([x, y], steps);
+ move.appear[0].x = moveTo[0];
+ move.appear[0].y = moveTo[1];
+ };
+ // For (wa)luigi effect:
+ const changePieceColor = (color) => {
+ let pieces = [];
+ for (let i=0; i<8; i++) {
+ for (let j=0; j<8; j++) {
+ if (
+ this.board[i][j] != V.EMPTY &&
+ this.getColor(i, j) == color
+ ) {
+ const piece = this.getPiece(i, j);
+ if (piece != V.KING)
+ pieces.push({ x: i, y: j, p: piece });
+ }
+ }
+ }
+ const cp = pieces[randInt(pieces.length)];
+ move.vanish.push(
+ new PiPo({
+ x: cp.x,
+ y: cp.y,
+ c: color,
+ p: cp.p
+ })
+ );
+ move.appear.push(
+ new PiPo({
+ x: cp.x,
+ y: cp.y,
+ c: V.GetOppCol(color),
+ p: cp.p
+ })
+ );
+ };
+ const applyEggEffect = () => {
+ if (this.subTurn == 1) {
+ // 1) Determine the effect (some may be impossible)
+ let effects = ["kingboo", "koopa", "chomp", "bowser"];
+ if (this.captured[color1].some(c => c >= 1))
+ effects.push("toadette");
+ V.PlayOnBoard(this.board, move);
+ const canPlayAgain = this.getPotentialMovesFrom([x2, y2]).length > 0;
+ V.UndoOnBoard(this.board, move);
+ if (canPlayAgain) effects.push("daisy");
+ if (
+ board.some(b =>
+ b.some(cell => cell[0] == oppCol && cell[1] != V.KING))
+ ) {
+ effects.push("luigi");
+ }
+ if (
+ board.some(b =>
+ b.some(cell => cell[0] == color1 && cell[1] != V.KING))
+ ) {
+ effects.push("waluigi");
+ }
+ const effect = effects[randInd(effects.length)];
+ // 2) Apply it if possible, or set move.end.effect
+ if (["kingboo", "toadette", "daisy"].includes(effect))
+ move.end.effect = effect;
+ else {
+ switch (effect) {
+ case "koopa":
+ move.appear[0].x = x1;
+ move.appear[0].y = y1;
+ break;
+ case "chomp":
+ move.appear.unshift();
+ break;
+ case "bowser":
+ move.appear[0].p = V.IMMOBILIZE_CODE[piece1];
+ break;
+ case "luigi":
+ changePieceColor(oppCol);
+ break;
+ case "waluigi":
+ changePieceColor(color1);
+ break;
+ }
+ }
+ }
+ };
+ const applyMushroomEffect = () => {
+ if ([V.PAWN, V.KING, V.KNIGHT].includes(piece1)) {
+ // Just make another similar step, if possible (non-capturing)
+ const [i, j] = [
+ move.appear[0].x + 2 * (x2 - x1),
+ move.appear[0].y + 2 * (y2 - y1)
+ ];
+ if (
+ V.OnBoard(i, j) &&
+ (this.board[i][j] == V.EMPTY || this.getColor(i, j) == 'a')
+ ) {
+ move.appear[0].x = i;
+ move.appear[0].y = j;
+ if (this.board[i][j] != V.EMPTY) {
+ const object = this.getPiece(i, j);
+ move.vanish.push(
+ new PiPo({
+ x: i,
+ y: j,
+ c: 'a',
+ p: object
+ })
+ );
+ switch (object) {
+ case V.BANANA:
+ applyBeffect(V.steps[V.ROOK]);
+ break;
+ case V.BOMB:
+ applyBeffect(V.steps[V.BISHOP]);
+ break;
+ case V.EGG:
+ applyEggEffect();
+ break;
+ case V.MUSHROOM:
+ applyMushroomEffect();
+ break;
+ }
+ }
+ }
+ }
+ else {
+ // Queen, bishop or rook:
+ const step = [
+ (x2 - x1) / Math.abs(x2 - x1) || 0,
+ (y2 - y1) / Math.abs(y2 - y1) || 0
+ ];
+ const next = [move.appear[0].x + step[0], move.appear[0].y + step[1]];
+ if (
+ V.OnBoard(next[0], next[1]) &&
+ this.board[next[0]][next[1]] != V.EMPTY &&
+ this.getColor(next[0], next[1]) != 'a'
+ ) {
+ const afterNext = [next[0] + step[0], next[1] + step[1]];
+ if (
+ V.OnBoard(afterNext[0], afterNext[1]) &&
+ (
+ this.board[afterNext[0]][afterNext[1]] == V.EMPTY ||
+ this.getColor(afterNext[0], afterNext[1]) == 'a'
+ )
+ ) {
+ move.appear[0].x = afterNext[0];
+ move.appear[0].y = afterNext[1];
+ if (this.board[afterNext[0]][afterNext[1]] != V.EMPTY) {
+ const object = this.getPiece(afterNext[0], afterNext[1]);
+ move.vanish.push(
+ new PiPo({
+ x: afterNext[0],
+ y: afterNext[0],
+ c: 'a',
+ p: object
+ })
+ );
+ switch (object) {
+ case V.BANANA:
+ applyBeffect(V.steps[V.ROOK]);
+ break;
+ case V.BOMB:
+ applyBeffect(V.steps[V.BISHOP]);
+ break;
+ case V.EGG:
+ applyEggEffect();
+ break;
+ case V.MUSHROOM:
+ applyMushroomEffect();
+ break;
+ }
+ }
+ }
+ }
+ }
+ };
+ if (color2 == 'a') {
+ switch (piece2) {
+ case V.BANANA:
+ applyBeffect(V.steps[V.ROOK]);
+ break;
+ case V.BOMB:
+ applyBeffect(V.steps[V.BISHOP]);
+ break;
+ case V.MUSHROOM:
+ applyMushroomEffect();
+ break;
+ case V.EGG:
+ if (this.subTurn == 1) {
+ // No egg effect at subTurn 2
+ if ([V.ROOK, V.BISHOP].includes(piece1)) {
+ // Drop a bomb or banana at random, because even if bonus is
+ // "play again" nothing can be done after next move.
+ const steps = V.steps[piece1 == V.ROOK ? V.BISHOP : V.ROOK];
+ const object = (piece1 == V.ROOK ? V.BANANA : V.BOMB);
+ const dropOn = this.getRandomSquare([x, y], steps);
+ move.appear.push(
+ new PiPo({
+ x: dropOn[0],
+ y: dropOn[1],
+ c: 'a',
+ p: object
+ })
+ );
+ }
+ applyEggEffect();
+ }
+ break;
+ }
+ }
+ else if (
+ this.subTurn == 1 &&
+ [V.ROOK, V.BISHOP].includes(piece1)
+ ) {
+ move.end.effect = 0;
+ }