1 import { ChessRules
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
3 import { randInt
} from "@/utils/alea";
5 export class CapablancaRules
extends ChessRules
{
7 static get PawnSpecs() {
13 ChessRules
.PawnSpecs
.promotions
14 .concat([V
.EMPRESS
, V
.PRINCESS
])
20 return ([V
.EMPRESS
, V
.PRINCESS
].includes(b
[1]) ? "Capablanca/" : "") + b
;
24 return { x: 8, y: 10 };
28 static get EMPRESS() {
33 static get PRINCESS() {
38 return ChessRules
.PIECES
.concat([V
.EMPRESS
, V
.PRINCESS
]);
41 getPotentialMovesFrom([x
, y
]) {
42 switch (this.getPiece(x
, y
)) {
44 return this.getPotentialEmpressMoves([x
, y
]);
46 return this.getPotentialPrincessMoves([x
, y
]);
48 return super.getPotentialMovesFrom([x
, y
]);
52 getPotentialEmpressMoves(sq
) {
53 return this.getSlideNJumpMoves(sq
, V
.steps
[V
.ROOK
]).concat(
54 this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep")
58 getPotentialPrincessMoves(sq
) {
59 return this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
]).concat(
60 this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep")
64 isAttacked(sq
, color
) {
66 super.isAttacked(sq
, color
) ||
67 this.isAttackedByEmpress(sq
, color
) ||
68 this.isAttackedByPrincess(sq
, color
)
72 isAttackedByEmpress(sq
, color
) {
74 this.isAttackedBySlideNJump(sq
, color
, V
.EMPRESS
, V
.steps
[V
.ROOK
]) ||
75 this.isAttackedBySlideNJump(
85 isAttackedByPrincess(sq
, color
) {
87 this.isAttackedBySlideNJump(sq
, color
, V
.PRINCESS
, V
.steps
[V
.BISHOP
]) ||
88 this.isAttackedBySlideNJump(
105 static get SEARCH_DEPTH() {
109 static GenRandInitFen(randomness
) {
110 if (randomness
== 0) {
112 "rnsbqkbenr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNSBQKBENR w 0 ajaj -"
116 let pieces
= { w: new Array(10), b: new Array(10) };
118 for (let c
of ["w", "b"]) {
119 if (c
== 'b' && randomness
== 1) {
120 pieces
['b'] = pieces
['w'];
125 let positions
= ArrayFun
.range(10);
127 // Get random squares for bishops
128 let randIndex
= 2 * randInt(5);
129 const bishop1Pos
= positions
[randIndex
];
130 // The second bishop must be on a square of different color
131 let randIndex_tmp
= 2 * randInt(5) + 1;
132 const bishop2Pos
= positions
[randIndex_tmp
];
133 // Remove chosen squares
134 positions
.splice(Math
.max(randIndex
, randIndex_tmp
), 1);
135 positions
.splice(Math
.min(randIndex
, randIndex_tmp
), 1);
137 // Get random square for empress
138 randIndex
= randInt(8);
139 const empressPos
= positions
[randIndex
];
140 positions
.splice(randIndex
, 1);
142 // Get random square for princess
143 randIndex
= randInt(7);
144 const princessPos
= positions
[randIndex
];
145 positions
.splice(randIndex
, 1);
147 // Get random squares for knights
148 randIndex
= randInt(6);
149 const knight1Pos
= positions
[randIndex
];
150 positions
.splice(randIndex
, 1);
151 randIndex
= randInt(5);
152 const knight2Pos
= positions
[randIndex
];
153 positions
.splice(randIndex
, 1);
155 // Get random square for queen
156 randIndex
= randInt(4);
157 const queenPos
= positions
[randIndex
];
158 positions
.splice(randIndex
, 1);
160 // Now rooks + king positions are fixed:
161 const rook1Pos
= positions
[0];
162 const kingPos
= positions
[1];
163 const rook2Pos
= positions
[2];
165 // Finally put the shuffled pieces in the board array
166 pieces
[c
][rook1Pos
] = "r";
167 pieces
[c
][knight1Pos
] = "n";
168 pieces
[c
][bishop1Pos
] = "b";
169 pieces
[c
][queenPos
] = "q";
170 pieces
[c
][empressPos
] = "e";
171 pieces
[c
][princessPos
] = "s";
172 pieces
[c
][kingPos
] = "k";
173 pieces
[c
][bishop2Pos
] = "b";
174 pieces
[c
][knight2Pos
] = "n";
175 pieces
[c
][rook2Pos
] = "r";
176 flags
+= V
.CoordToColumn(rook1Pos
) + V
.CoordToColumn(rook2Pos
);
179 pieces
["b"].join("") + "/pppppppppp/91/91/91/91/PPPPPPPPPP/" +
180 pieces
["w"].join("").toUpperCase() + " w 0 " + flags
+ " - -"