+ capturePostProcess(moves, oppCol) {
+ // Filter out non-capturing moves (not using m.vanish because of
+ // self captures of Recycle and Teleport).
+ return moves.filter(m => {
+ return (
+ this.board[m.end.x][m.end.y] != "" &&
+ this.getColor(m.end.x, m.end.y) == oppCol
+ );
+ });
+ }
+
+ atomicPostProcess(moves, oppCol) {
+ moves.forEach(m => {
+ if (
+ this.board[m.end.x][m.end.y] != "" &&
+ this.getColor(m.end.x, m.end.y) == oppCol
+ ) {
+ // Explosion!
+ let steps = [
+ [-1, -1],
+ [-1, 0],
+ [-1, 1],
+ [0, -1],
+ [0, 1],
+ [1, -1],
+ [1, 0],
+ [1, 1]
+ ];
+ for (let step of steps) {
+ let x = m.end.x + step[0];
+ let y = this.getY(m.end.y + step[1]);
+ if (
+ this.onBoard(x, y) &&
+ this.board[x][y] != "" &&
+ this.getPieceType(x, y) != "p"
+ ) {
+ m.vanish.push(
+ new PiPo({
+ p: this.getPiece(x, y),
+ c: this.getColor(x, y),
+ x: x,
+ y: y
+ })
+ );
+ }
+ }
+ if (!this.options["rifle"])
+ m.appear.pop(); //nothing appears
+ }
+ });
+ }
+
+ pawnPostProcess(moves, color, oppCol) {
+ let moreMoves = [];
+ const lastRank = (color == "w" ? 0 : this.size.x - 1);
+ const initPiece = this.getPiece(moves[0].start.x, moves[0].start.y);
+ moves.forEach(m => {
+ const [x1, y1] = [m.start.x, m.start.y];
+ const [x2, y2] = [m.end.x, m.end.y];
+ const promotionOk = (
+ x2 == lastRank &&
+ (!this.options["rifle"] || this.board[x2][y2] == "")
+ );
+ if (!promotionOk)
+ return; //nothing to do
+ if (this.options["pawnfall"]) {
+ m.appear.shift();
+ return;
+ }
+ let finalPieces = ["p"];
+ if (
+ this.options["cannibal"] &&
+ this.board[x2][y2] != "" &&
+ this.getColor(x2, y2) == oppCol
+ ) {
+ finalPieces = [this.getPieceType(x2, y2)];
+ }
+ else
+ finalPieces = this.pawnPromotions;
+ m.appear[0].p = finalPieces[0];
+ if (initPiece == "!") //cannibal king-pawn
+ m.appear[0].p = C.CannibalKingCode[finalPieces[0]];
+ for (let i=1; i<finalPieces.length; i++) {
+ const piece = finalPieces[i];
+ const tr = {
+ c: color,
+ p: (initPiece != "!" ? piece : C.CannibalKingCode[piece])
+ };
+ let newMove = this.getBasicMove([x1, y1], [x2, y2], tr);
+ moreMoves.push(newMove);
+ }
+ });
+ Array.prototype.push.apply(moves, moreMoves);
+ }
+
+ riflePromotePostProcess(moves, color) {
+ const lastRank = (color == "w" ? 0 : this.size.x - 1);
+ let newMoves = [];
+ moves.forEach(m => {
+ if (
+ m.start.x == lastRank &&
+ m.appear.length >= 1 &&
+ m.appear[0].p == "p" &&
+ m.appear[0].x == m.start.x &&
+ m.appear[0].y == m.start.y
+ ) {
+ m.appear[0].p = this.pawnPromotions[0];
+ for (let i=1; i<this.pawnPromotions.length; i++) {
+ let newMv = JSON.parse(JSON.stringify(m));
+ newMv.appear[0].p = this.pawnSpecs.promotions[i];
+ newMoves.push(newMv);
+ }
+ }
+ });
+ Array.prototype.push.apply(moves, newMoves);
+ }
+