-import { ChessRules, PiPo, Move } from "@/base_rules";
-import { ArrayFun } from "@/utils/array";
+import ChessRules from "/base_rules.js";
export default class ClorangeRules extends ChessRules {
+ // TODO: options : disable teleport/recycle at least ?
+
get hasReserve() {
return true;
}
-// TODO
-
- static GenRandInitFen(options) {
- // Capturing and non-capturing reserves:
- return ChessRules.GenRandInitFen(options) + " 00000000000000000000";
- }
-
- getFen() {
- return super.getFen() + " " + this.getReserveFen();
- }
-
- getFenForRepeat() {
- return super.getFenForRepeat() + "_" + this.getReserveFen();
- }
-
- getReserveFen() {
+ getReserveFen(o) {
+ if (o.init)
+ return "00000000000000000000";
return (
- Object.keys(this.reserve).map(
- c => Object.values(this.reserve[c]).join("")).join("")
+ ["w","b"].map(c => Object.values(this.reserve[c]).join("")).join("")
);
}
- getEpSquare(moveOrSquare) {
- if (!moveOrSquare) return undefined;
- if (typeof moveOrSquare === "string") {
- const square = moveOrSquare;
- if (square == "-") return undefined;
- return V.SquareToCoords(square);
- }
- const move = moveOrSquare;
- const s = move.start,
- e = move.end;
- if (
- s.y == e.y &&
- Math.abs(s.x - e.x) == 2 &&
- move.vanish.length > 0 && ['p', 's'].includes(move.vanish[0].p)
- ) {
- return {
- x: (s.x + e.x) / 2,
- y: s.y
- };
- }
- return undefined;
+ pieces(color, x, y) {
+ let res = super.pieces(color, x, y);
+ res['s'] = {"class": "nv-pawn", moveas: "p"};
+ res['u'] = {"class": "nv-rook", moveas: "r"};
+ res['o'] = {"class": "nv-knight", moveas: "n"};
+ res['c'] = {"class": "nv-bishop", moveas: "b"};
+ res['t'] = {"class": "nv-queen", moveas: "q"};
}
setOtherVariables(fen) {
- super.setOtherVariables(fen);
- // Also init reserves (used by the interface to show landable pieces)
- const reserve =
- V.ParseFen(fen).reserve.split("").map(x => parseInt(x, 10));
- this.reserve = {
- w: {
- 'p': reserve[0],
- 'r': reserve[1],
- 'n': reserve[2],
- 'b': reserve[3],
- 'q': reserve[4],
- 's': reserve[5],
- 'u': reserve[6],
- 'o': reserve[7],
- 'c': reserve[8],
- 't': reserve[9]
- },
- b: {
- 'p': reserve[10],
- 'r': reserve[11],
- 'n': reserve[12],
- 'b': reserve[13],
- 'q': reserve[14],
- 's': reserve[15],
- 'u': reserve[16],
- 'o': reserve[17],
- 'c': reserve[18],
- 't': reserve[19]
- }
- };
+ super.setOtherVariables(fen,
+ ['p', 'r', 'n', 'b', 'q', 's', 'u', 'o', 'c', 't']);
}
- getColor(i, j) {
- if (i >= V.size.x) return i == V.size.x ? "w" : "b";
- return this.board[i][j].charAt(0);
- }
-
- getPiece(i, j) {
- if (i >= V.size.x) return V.RESERVE_PIECES[j];
- return this.board[i][j].charAt(1);
- }
-
- getPpath(b) {
- return (V.NON_VIOLENT.includes(b[1]) ? "Clorange/" : "") + b;
- }
-
- getReservePpath(index, color) {
- const prefix =
- (V.NON_VIOLENT.includes(V.RESERVE_PIECES[index]) ? "Clorange/" : "");
- return prefix + color + V.RESERVE_PIECES[index];
- }
-
- static get NON_VIOLENT() {
- return ['s', 'u', 'o', 'c', 't'];
- }
-
- static get PIECES() {
- return ChessRules.PIECES.concat(V.NON_VIOLENT);
- }
-
- // Ordering on reserve pieces
- static get RESERVE_PIECES() {
- return V.PIECES.filter(p => p != 'k');
- }
-
- getReserveMoves([x, y]) {
- const color = this.turn;
- const p = V.RESERVE_PIECES[y];
- if (this.reserve[color][p] == 0) return [];
- let moves = [];
- let rank1 = 0;
- let rank2 = V.size.x - 1;
- if (['p', 's'].includes(p)) {
- if (color == 'w') rank1++;
- else rank2--;
- }
- for (let i = rank1; i <= rank2; i++) {
- for (let j = 0; j < V.size.y; j++) {
- if (this.board[i][j] == V.EMPTY) {
- let mv = new Move({
- appear: [
- new PiPo({
- x: i,
- y: j,
- c: color,
- p: p
- })
- ],
- vanish: [],
- start: { x: x, y: y }, //a bit artificial...
- end: { x: i, y: j }
- });
- moves.push(mv);
- }
- }
- }
- return moves;
- }
-
- getPotentialMovesFrom([x, y]) {
- if (x >= V.size.x)
- // Reserves, outside of board: x == sizeX(+1)
- return this.getReserveMoves([x, y]);
- // Standard moves
- switch (this.getPiece(x, y)) {
- case 's': return this.getPotentialPawnMoves([x, y]);
- case 'u': return super.getPotentialRookMoves([x, y]);
- case 'o': return super.getPotentialKnightMoves([x, y]);
- case 'c': return super.getPotentialBishopMoves([x, y]);
- case 't': return super.getPotentialQueenMoves([x, y]);
- default: return super.getPotentialMovesFrom([x, y]);
- }
- return []; //never reached
- }
-
- getPotentialPawnMoves(sq) {
- let moves = super.getPotentialPawnMoves(sq);
- if (moves.length > 0 && moves[0].vanish[0].p == 's') {
- // Remove captures for non-violent pawns:
- moves = moves.filter(m => m.vanish.length == 1);
- moves.forEach(m => {
- if (m.appear[0].p != 's') {
- // Promotion pieces should be non-violent as well:
- const pIdx = ChessRules.PIECES.findIndex(p => p == m.appear[0].p)
- m.appear[0].p = V.NON_VIOLENT[pIdx];
- }
- });
- }
- return moves;
+ postProcessPotentialMoves(moves) {
+ // Remove captures for non-violent pieces:
+ return super.postProcessPotentialMoves(moves).filter(m => {
+ return (
+ m.vanish.length != 2 ||
+ m.appear.length != 1 ||
+ ['p', 'r', 'n', 'b', 'q'].includes(m.vanish[0].p)
+ );
+ });
}
canTake([x1, y1], [x2, y2]) {
return (
this.getColor(x1, y1) !== this.getColor(x2, y2) &&
- ChessRules.PIECES.includes(this.getPiece(x1, y1))
+ ['p', 'r', 'n', 'b', 'q', 'k'].includes(this.getPiece(x1, y1))
);
}
- getAllValidMoves() {
- let moves = super.getAllPotentialMoves();
- const color = this.turn;
- for (let i = 0; i < V.RESERVE_PIECES.length; i++) {
- moves = moves.concat(
- this.getReserveMoves([V.size.x + (color == "w" ? 0 : 1), i])
- );
- }
- return this.filterValid(moves);
- }
-
- atLeastOneMove() {
- if (!super.atLeastOneMove()) {
- // Search one reserve move
- for (let i = 0; i < V.RESERVE_PIECES.length; i++) {
- let moves = this.filterValid(
- this.getReserveMoves([V.size.x + (this.turn == "w" ? 0 : 1), i])
- );
- if (moves.length > 0) return true;
- }
- return false;
- }
- return true;
- }
-
prePlay(move) {
super.prePlay(move);
- // Skip castle:
- if (move.vanish.length == 2 && move.appear.length == 2) return;
- const color = this.turn;
- if (move.vanish.length == 0) this.reserve[color][move.appear[0].p]--;
- else if (move.vanish.length == 2) {
- // Capture
- const normal = ChessRules.PIECES.includes(move.vanish[1].p);
- const pIdx =
- normal
+ // No crazyhouse or recycle, so the last call didn't update reserve:
+ if (move.vanish.length == 2 && move.appear.length == 1) {
+ // Capture: update reserves
+ this.Reserve[move.vanish
+ const pIdx = ['p', 'r', 'n', 'b', 'q'].indexOf(move.vanish[1].p);
+ // TODO
+ if normal
? ChessRules.PIECES.findIndex(p => p == move.vanish[1].p)
: V.NON_VIOLENT.findIndex(p => p == move.vanish[1].p);
const rPiece = (normal ? V.NON_VIOLENT : ChessRules.PIECES)[pIdx];