4bd2ac925116722f77e632242978b197771ad4d8
1 import { ChessRules
} from "@/base_rules";
2 import { ArrayFun
} from "@/utils/array";
3 import { randInt
} from "@/utils/alea";
5 export class PerfectRules
extends ChessRules
{
7 static get PawnSpecs() {
13 ChessRules
.PawnSpecs
.promotions
14 .concat([V
.AMAZON
, V
.EMPRESS
, V
.PRINCESS
])
21 [V
.AMAZON
, V
.EMPRESS
, V
.PRINCESS
].includes(b
[1])
33 static get EMPRESS() {
38 static get PRINCESS() {
43 return ChessRules
.PIECES
.concat([V
.AMAZON
, V
.EMPRESS
, V
.PRINCESS
]);
46 getPotentialMovesFrom([x
, y
]) {
47 switch (this.getPiece(x
, y
)) {
49 return this.getPotentialAmazonMoves([x
, y
]);
51 return this.getPotentialEmpressMoves([x
, y
]);
53 return this.getPotentialPrincessMoves([x
, y
]);
55 return super.getPotentialMovesFrom([x
, y
]);
59 getPotentialAmazonMoves(sq
) {
60 return super.getPotentialQueenMoves(sq
).concat(
61 this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep")
65 getPotentialEmpressMoves(sq
) {
66 return this.getSlideNJumpMoves(sq
, V
.steps
[V
.ROOK
]).concat(
67 this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep")
71 getPotentialPrincessMoves(sq
) {
72 return this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
]).concat(
73 this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep")
77 isAttacked(sq
, color
) {
79 super.isAttacked(sq
, color
) ||
80 this.isAttackedByAmazon(sq
, color
) ||
81 this.isAttackedByEmpress(sq
, color
) ||
82 this.isAttackedByPrincess(sq
, color
)
86 isAttackedByAmazon(sq
, color
) {
88 this.isAttackedBySlideNJump(sq
, color
, V
.AMAZON
, V
.steps
[V
.BISHOP
]) ||
89 this.isAttackedBySlideNJump(sq
, color
, V
.AMAZON
, V
.steps
[V
.ROOK
]) ||
90 this.isAttackedBySlideNJump(
100 isAttackedByEmpress(sq
, color
) {
102 this.isAttackedBySlideNJump(sq
, color
, V
.EMPRESS
, V
.steps
[V
.ROOK
]) ||
103 this.isAttackedBySlideNJump(
113 isAttackedByPrincess(sq
, color
) {
115 this.isAttackedBySlideNJump(sq
, color
, V
.PRINCESS
, V
.steps
[V
.BISHOP
]) ||
116 this.isAttackedBySlideNJump(
126 static get VALUES() {
127 return Object
.assign(
128 { a: 12, e: 7, s: 5 }, //experimental
133 static get SEARCH_DEPTH() {
137 static GenRandInitFen(randomness
) {
139 return "esqakbnr/pppppppp/8/8/8/8/PPPPPPPP/ESQAKBNR w 0 ahah -";
141 let pieces
= { w: new Array(8), b: new Array(8) };
143 let whiteBishopPos
= -1;
144 for (let c
of ["w", "b"]) {
145 if (c
== 'b' && randomness
== 1) {
146 pieces
['b'] = pieces
['w'];
151 let positions
= ArrayFun
.range(8);
153 // Get random squares for bishop: if black, pick a different color
154 // than where the white one stands.
158 : 2 * randInt(4) + (1 - whiteBishopPos
% 2);
159 if (c
== 'w') whiteBishopPos
= randIndex
;
160 const bishopPos
= positions
[randIndex
];
161 positions
.splice(randIndex
, 1);
163 randIndex
= randInt(7);
164 const knightPos
= positions
[randIndex
];
165 positions
.splice(randIndex
, 1);
167 randIndex
= randInt(6);
168 const queenPos
= positions
[randIndex
];
169 positions
.splice(randIndex
, 1);
171 randIndex
= randInt(5);
172 const amazonPos
= positions
[randIndex
];
173 positions
.splice(randIndex
, 1);
175 randIndex
= randInt(4);
176 const princessPos
= positions
[randIndex
];
177 positions
.splice(randIndex
, 1);
179 // Rook, empress and king positions are now almost fixed,
180 // only the ordering rook->empress or empress->rook must be decided.
181 let rookPos
= positions
[0];
182 let empressPos
= positions
[2];
183 const kingPos
= positions
[1];
184 flags
+= V
.CoordToColumn(rookPos
) + V
.CoordToColumn(empressPos
);
185 if (Math
.random() < 0.5) [rookPos
, empressPos
] = [empressPos
, rookPos
];
187 pieces
[c
][rookPos
] = "r";
188 pieces
[c
][knightPos
] = "n";
189 pieces
[c
][bishopPos
] = "b";
190 pieces
[c
][queenPos
] = "q";
191 pieces
[c
][kingPos
] = "k";
192 pieces
[c
][amazonPos
] = "a";
193 pieces
[c
][princessPos
] = "s";
194 pieces
[c
][empressPos
] = "e";
196 // Add turn + flags + enpassant
198 pieces
["b"].join("") +
199 "/pppppppp/8/8/8/8/PPPPPPPP/" +
200 pieces
["w"].join("").toUpperCase() +
201 " w 0 " + flags
+ " -"