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
], 1)
58 getPotentialPrincessMoves(sq
) {
59 return this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
]).concat(
60 this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], 1)
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(sq
, color
, V
.EMPRESS
, V
.steps
[V
.KNIGHT
], 1)
79 isAttackedByPrincess(sq
, color
) {
81 this.isAttackedBySlideNJump(sq
, color
, V
.PRINCESS
, V
.steps
[V
.BISHOP
]) ||
82 this.isAttackedBySlideNJump(sq
, color
, V
.PRINCESS
, V
.steps
[V
.KNIGHT
], 1)
93 static get SEARCH_DEPTH() {
97 static GenRandInitFen(options
) {
98 if (options
.randomness
== 0) {
100 "rnsbqkbenr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNSBQKBENR w 0 ajaj -"
104 let pieces
= { w: new Array(10), b: new Array(10) };
106 for (let c
of ["w", "b"]) {
107 if (c
== 'b' && options
.randomness
== 1) {
108 pieces
['b'] = pieces
['w'];
113 let positions
= ArrayFun
.range(10);
115 // Get random squares for bishops
116 let randIndex
= 2 * randInt(5);
117 const bishop1Pos
= positions
[randIndex
];
118 // The second bishop must be on a square of different color
119 let randIndex_tmp
= 2 * randInt(5) + 1;
120 const bishop2Pos
= positions
[randIndex_tmp
];
121 // Remove chosen squares
122 positions
.splice(Math
.max(randIndex
, randIndex_tmp
), 1);
123 positions
.splice(Math
.min(randIndex
, randIndex_tmp
), 1);
125 // Get random square for empress
126 randIndex
= randInt(8);
127 const empressPos
= positions
[randIndex
];
128 positions
.splice(randIndex
, 1);
130 // Get random square for princess
131 randIndex
= randInt(7);
132 const princessPos
= positions
[randIndex
];
133 positions
.splice(randIndex
, 1);
135 // Get random squares for knights
136 randIndex
= randInt(6);
137 const knight1Pos
= positions
[randIndex
];
138 positions
.splice(randIndex
, 1);
139 randIndex
= randInt(5);
140 const knight2Pos
= positions
[randIndex
];
141 positions
.splice(randIndex
, 1);
143 // Get random square for queen
144 randIndex
= randInt(4);
145 const queenPos
= positions
[randIndex
];
146 positions
.splice(randIndex
, 1);
148 // Now rooks + king positions are fixed:
149 const rook1Pos
= positions
[0];
150 const kingPos
= positions
[1];
151 const rook2Pos
= positions
[2];
153 // Finally put the shuffled pieces in the board array
154 pieces
[c
][rook1Pos
] = "r";
155 pieces
[c
][knight1Pos
] = "n";
156 pieces
[c
][bishop1Pos
] = "b";
157 pieces
[c
][queenPos
] = "q";
158 pieces
[c
][empressPos
] = "e";
159 pieces
[c
][princessPos
] = "s";
160 pieces
[c
][kingPos
] = "k";
161 pieces
[c
][bishop2Pos
] = "b";
162 pieces
[c
][knight2Pos
] = "n";
163 pieces
[c
][rook2Pos
] = "r";
164 flags
+= V
.CoordToColumn(rook1Pos
) + V
.CoordToColumn(rook2Pos
);
167 pieces
["b"].join("") + "/pppppppppp/91/91/91/91/PPPPPPPPPP/" +
168 pieces
["w"].join("").toUpperCase() + " w 0 " + flags
+ " - -"