import { randInt } from "@/utils/alea";
export class PerfectRules extends ChessRules {
+
static get PawnSpecs() {
return Object.assign(
{},
isAttackedByAmazon(sq, color) {
return (
- super.isAttackedByQueen(sq, color) ||
+ this.isAttackedBySlideNJump(sq, color, V.AMAZON, V.steps[V.BISHOP]) ||
+ this.isAttackedBySlideNJump(sq, color, V.AMAZON, V.steps[V.ROOK]) ||
this.isAttackedBySlideNJump(
sq,
color,
- V.MARSHALL,
+ V.AMAZON,
V.steps[V.KNIGHT],
"oneStep"
)
isAttackedByEmpress(sq, color) {
return (
- this.isAttackedBySlideNJump(sq, color, V.MARSHALL, V.steps[V.ROOK]) ||
+ this.isAttackedBySlideNJump(sq, color, V.EMPRESS, V.steps[V.ROOK]) ||
this.isAttackedBySlideNJump(
sq,
color,
- V.MARSHALL,
+ V.EMPRESS,
V.steps[V.KNIGHT],
"oneStep"
)
isAttackedByPrincess(sq, color) {
return (
- this.isAttackedBySlideNJump(sq, color, V.CARDINAL, V.steps[V.BISHOP]) ||
+ this.isAttackedBySlideNJump(sq, color, V.PRINCESS, V.steps[V.BISHOP]) ||
this.isAttackedBySlideNJump(
sq,
color,
- V.CARDINAL,
+ V.PRINCESS,
V.steps[V.KNIGHT],
"oneStep"
)
if (randomness == 0)
return "esqakbnr/pppppppp/8/8/8/8/PPPPPPPP/ESQAKBNR w 0 ahah -";
- let pieces = { w: new Array(8), b: new Array(8) };
- let flags = "";
- let whiteBishopPos = -1;
- for (let c of ["w", "b"]) {
- if (c == 'b' && randomness == 1) {
- pieces['b'] = pieces['w'];
- flags += flags;
- break;
+ const baseFen = ChessRules.GenRandInitFen(randomness);
+ const fenParts = baseFen.split(' ');
+ const posParts = fenParts[0].split('/');
+
+ // Replace a random rook per side by an empress,
+ // a random knight by a princess, and a bishop by an amazon
+ // (Constraint: the two remaining bishops on different colors).
+
+ let newPos = { 0: "", 7: "" };
+ let amazonOddity = -1;
+ for (let rank of [0, 7]) {
+ let replaced = { 'b': -2, 'n': -2, 'r': -2 };
+ for (let i = 0; i < 8; i++) {
+ const curChar = posParts[rank].charAt(i).toLowerCase();
+ if (['b', 'n', 'r'].includes(curChar)) {
+ if (
+ replaced[curChar] == -1 ||
+ (curChar == 'b' && rank == 7 && i % 2 == amazonOddity) ||
+ (
+ (curChar != 'b' || rank == 0) &&
+ replaced[curChar] == -2 &&
+ randInt(2) == 0
+ )
+ ) {
+ replaced[curChar] = i;
+ if (curChar == 'b') {
+ if (amazonOddity < 0) amazonOddity = i % 2;
+ newPos[rank] += 'a';
+ }
+ else if (curChar == 'r') newPos[rank] += 'e';
+ else newPos[rank] += 's';
+ }
+ else {
+ if (replaced[curChar] == -2) replaced[curChar]++;
+ newPos[rank] += curChar;
+ }
+ }
+ else newPos[rank] += curChar;
}
-
- let positions = ArrayFun.range(8);
-
- // Get random squares for bishop: if black, pick a different color
- // than where the white one stands.
- let randIndex =
- c == 'w'
- ? randInt(8)
- : 2 * randInt(4) + (1 - whiteBishopPos % 2);
- if (c == 'w') whiteBishopPos = randIndex;
- const bishopPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- randIndex = randInt(7);
- const knightPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- randIndex = randInt(6);
- const queenPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- randIndex = randInt(5);
- const amazonPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- randIndex = randInt(4);
- const princessPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- // Rook, empress and king positions are now almost fixed,
- // only the ordering rook->empress or empress->rook must be decided.
- let rookPos = positions[0];
- let empressPos = positions[2];
- const kingPos = positions[1];
- flags += V.CoordToColumn(rookPos) + V.CoordToColumn(empressPos);
- if (Math.random() < 0.5) [rookPos, empressPos] = [empressPos, rookPos];
-
- pieces[c][rookPos] = "r";
- pieces[c][knightPos] = "n";
- pieces[c][bishopPos] = "b";
- pieces[c][queenPos] = "q";
- pieces[c][kingPos] = "k";
- pieces[c][amazonPos] = "a";
- pieces[c][princessPos] = "s";
- pieces[c][empressPos] = "e";
}
- // Add turn + flags + enpassant
+
return (
- pieces["b"].join("") +
- "/pppppppp/8/8/8/8/PPPPPPPP/" +
- pieces["w"].join("").toUpperCase() +
- " w 0 " + flags + " -"
+ newPos[0] + "/" + posParts.slice(1, 7).join('/') + "/" +
+ newPos[7].toUpperCase() + " " + fenParts.slice(1, 5).join(' ') + " -"
);
}
+
};