static get Options() {
return {
select: C.Options.select,
- check: [],
styles: [
"balance",
"capture",
"doublemove",
"progressive",
"recycle",
- "rifle", //TODO? absorb powers from afar?
+ //"rifle", //TODO
"teleport",
"zen"
]
};
}
- pieces(color) {
- const fusions = {{
+ pieces(color, x, y) {
+ let fusions = {
// amazon
'a': {
"class": "amazon",
- steps: [
- [0, 1], [0, -1], [1, 0], [-1, 0],
- [1, 1], [1, -1], [-1, 1], [-1, -1]
+ moves: [
+ {
+ steps: [
+ [0, 1], [0, -1], [1, 0], [-1, 0],
+ [1, 1], [1, -1], [-1, 1], [-1, -1]
+ ]
+ },
+ {
+ steps: [
+ [1, 2], [1, -2], [-1, 2], [-1, -2],
+ [2, 1], [-2, 1], [2, -1], [-2, -1]
+ ],
+ range: 1
+ }
]
-
-//TODO: steps object avec range + steps... "moving"?
-
- steps: [
- [1, 2], [1, -2], [-1, 2], [-1, -2],
- [2, 1], [-2, 1], [2, -1], [-2, -1]
- ],
- steps: [[0, 1], [0, -1], [1, 0], [-1, 0]]
},
// empress
'e': {
"class": "empress",
- steps: [
- [1, 2], [1, -2], [-1, 2], [-1, -2],
- [2, 1], [-2, 1], [2, -1], [-2, -1]
- ],
+ moves: [
+ {
+ steps: [
+ [1, 0], [-1, 0], [0, 1], [0, -1]
+ ]
+ },
+ {
+ steps: [
+ [1, 2], [1, -2], [-1, 2], [-1, -2],
+ [2, 1], [-2, 1], [2, -1], [-2, -1]
+ ],
+ range: 1
+ }
+ ]
},
// princess
- 'b': {
- "class": "bishop",
- steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]]
- },
- // queen
- 'q': {
- "class": "queen",
- },
-
- },
- return (
- Object.assign(
- super.pieces(color)
- )
- );
+ 's': {
+ "class": "princess",
+ moves: [
+ {
+ steps: [
+ [1, 1], [1, -1], [-1, 1], [-1, -1]
+ ]
+ },
+ {
+ steps: [
+ [1, 2], [1, -2], [-1, 2], [-1, -2],
+ [2, 1], [-2, 1], [2, -1], [-2, -1]
+ ],
+ range: 1
+ }
+ ]
+ }
+ };
+ return Object.assign(fusions, super.pieces(color, x, y));
}
static get MergeComposed() {
return {
"be": "a",
+ "bq": "q",
+ "br": "q",
"bs": "s",
+ "eq": "a",
"er": "e",
+ "es": "a",
"rs": "a",
- "eq": "a",
+ "qr": "q",
"qs": "a",
- "ee": "e",
- "es": "a",
- "ss": "s"
+ "rs": "a"
};
}
+ // Assumption p1 != p2
static Fusion(p1, p2) {
- if (p1 == V.KING) return p1;
- if (p1 == V.PAWN) return p2;
- if (p2 == V.PAWN) return p1;
- if ([p1, p2].includes(V.KNIGHT)) {
- if ([p1, p2].includes(V.QUEEN)) return V.QN;
- if ([p1, p2].includes(V.ROOK)) return V.RN;
- if ([p1, p2].includes(V.BISHOP)) return V.BN;
+ if (p1 == "k")
+ return p1;
+ if (p1 == "p")
+ return p2;
+ if (p2 == "p")
+ return p1;
+ if ([p1, p2].includes("n")) {
+ if ([p1, p2].includes("q"))
+ return "a";
+ if ([p1, p2].includes("r"))
+ return "e";
+ if ([p1, p2].includes("b"))
+ return "s";
// p1 or p2 already have knight + other piece
- return (p1 == V.KNIGHT ? p2 : p1);
- }
- if ([p1, p2].includes(V.QN)) return V.QN;
- for (let p of [p1, p2]) {
- if ([V.BN, V.RN].includes(p))
- return V.MergeComposed[[p1, p2].sort().join("")];
+ return (p1 == "n" ? p2 : p1);
}
- // bishop + rook, or queen + [bishop or rook]
- return V.QUEEN;
+ if ([p1, p2].includes("a"))
+ return "a";
+ // No king, no pawn, no knight or amazon => 5 remaining pieces
+ return V.MergeComposed[[p1, p2].sort().join("")];
}
- getPotentialMovesFrom(sq) {
- let moves = [];
- const piece = this.getPiece(sq[0], sq[1]);
- switch (piece) {
- case V.RN:
- moves =
- super.getPotentialRookMoves(sq).concat(
- super.getPotentialKnightMoves(sq));
- break;
- case V.BN:
- moves =
- super.getPotentialBishopMoves(sq).concat(
- super.getPotentialKnightMoves(sq));
- break;
- case V.QN:
- moves =
- super.getPotentialQueenMoves(sq).concat(
- super.getPotentialKnightMoves(sq));
- break;
- default:
- moves = super.getPotentialMovesFrom(sq);
- }
+ // TODO: interaction with rifle ?
+ postProcessPotentialMoves(moves) {
// Filter out capturing promotions (except one),
// because they are all the same.
moves = moves.filter(m => {
return (
m.vanish.length == 1 ||
- m.vanish[0].p != V.PAWN ||
- [V.PAWN, V.QUEEN].includes(m.appear[0].p)
+ m.vanish[0].p != "p" ||
+ ["p", "q"].includes(m.appear[0].p)
);
});
moves.forEach(m => {
if (
m.vanish.length == 2 &&
m.appear.length == 1 &&
- piece != m.vanish[1].p
+ m.vanish[0].p != m.vanish[1].p
) {
// Augment pieces abilities in case of captures
- m.appear[0].p = V.Fusion(piece, m.vanish[1].p);
+ m.appear[0].p = V.Fusion(m.vanish[0].p, m.vanish[1].p);
}
});
- return moves;
- }
-
- isAttacked(sq, color) {
- return (
- super.isAttacked(sq, color) ||
- this.isAttackedByBN(sq, color) ||
- this.isAttackedByRN(sq, color) ||
- this.isAttackedByQN(sq, color)
- );
- }
-
- isAttackedByBN(sq, color) {
- return (
- this.isAttackedBySlideNJump(sq, color, V.BN, V.steps[V.BISHOP]) ||
- this.isAttackedBySlideNJump(
- sq, color, V.BN, V.steps[V.KNIGHT], 1)
- );
- }
-
- isAttackedByRN(sq, color) {
- return (
- this.isAttackedBySlideNJump(sq, color, V.RN, V.steps[V.ROOK]) ||
- this.isAttackedBySlideNJump(
- sq, color, V.RN, V.steps[V.KNIGHT], 1)
- );
- }
-
- isAttackedByQN(sq, color) {
- return (
- this.isAttackedBySlideNJump(
- sq, color, V.QN, V.steps[V.BISHOP].concat(V.steps[V.ROOK])) ||
- this.isAttackedBySlideNJump(
- sq, color, V.QN, V.steps[V.KNIGHT], 1)
- );
- }
-
- static get VALUES() {
- return Object.assign(
- { a: 12, e: 7, s: 5 },
- ChessRules.VALUES
- );
- }
-
- getNotation(move) {
- let notation = super.getNotation(move);
- if (move.vanish[0].p != V.PAWN && move.appear[0].p != move.vanish[0].p)
- // Fusion (not from a pawn: handled in ChessRules)
- notation += "=" + move.appear[0].p.toUpperCase();
- return notation;
+ return super.postProcessPotentialMoves(moves);
}
};