Fix Eightpieces
[vchess.git] / client / src / variants / Capablanca.js
1 import { ChessRules } from "@/base_rules";
2 import { ArrayFun } from "@/utils/array";
3 import { randInt } from "@/utils/alea";
4
5 export class CapablancaRules extends ChessRules {
6
7 static get PawnSpecs() {
8 return Object.assign(
9 {},
10 ChessRules.PawnSpecs,
11 {
12 promotions:
13 ChessRules.PawnSpecs.promotions
14 .concat([V.EMPRESS, V.PRINCESS])
15 }
16 );
17 }
18
19 getPpath(b) {
20 return ([V.EMPRESS, V.PRINCESS].includes(b[1]) ? "Capablanca/" : "") + b;
21 }
22
23 static get size() {
24 return { x: 8, y: 10 };
25 }
26
27 // Rook + knight:
28 static get EMPRESS() {
29 return "e";
30 }
31
32 // Bishop + knight
33 static get PRINCESS() {
34 return "s";
35 }
36
37 static get PIECES() {
38 return ChessRules.PIECES.concat([V.EMPRESS, V.PRINCESS]);
39 }
40
41 getPotentialMovesFrom([x, y]) {
42 switch (this.getPiece(x, y)) {
43 case V.EMPRESS:
44 return this.getPotentialEmpressMoves([x, y]);
45 case V.PRINCESS:
46 return this.getPotentialPrincessMoves([x, y]);
47 default:
48 return super.getPotentialMovesFrom([x, y]);
49 }
50 }
51
52 getPotentialEmpressMoves(sq) {
53 return this.getSlideNJumpMoves(sq, V.steps[V.ROOK]).concat(
54 this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], 1)
55 );
56 }
57
58 getPotentialPrincessMoves(sq) {
59 return this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat(
60 this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], 1)
61 );
62 }
63
64 isAttacked(sq, color) {
65 return (
66 super.isAttacked(sq, color) ||
67 this.isAttackedByEmpress(sq, color) ||
68 this.isAttackedByPrincess(sq, color)
69 );
70 }
71
72 isAttackedByEmpress(sq, color) {
73 return (
74 this.isAttackedBySlideNJump(sq, color, V.EMPRESS, V.steps[V.ROOK]) ||
75 this.isAttackedBySlideNJump(sq, color, V.EMPRESS, V.steps[V.KNIGHT], 1)
76 );
77 }
78
79 isAttackedByPrincess(sq, color) {
80 return (
81 this.isAttackedBySlideNJump(sq, color, V.PRINCESS, V.steps[V.BISHOP]) ||
82 this.isAttackedBySlideNJump(sq, color, V.PRINCESS, V.steps[V.KNIGHT], 1)
83 );
84 }
85
86 static get VALUES() {
87 return Object.assign(
88 { s: 5, e: 7 },
89 ChessRules.VALUES
90 );
91 }
92
93 static get SEARCH_DEPTH() {
94 return 2;
95 }
96
97 static GenRandInitFen(options) {
98 if (options.randomness == 0) {
99 return (
100 "rnsbqkbenr/pppppppppp/91/91/91/91/PPPPPPPPPP/RNSBQKBENR w 0 ajaj -"
101 );
102 }
103
104 let pieces = { w: new Array(10), b: new Array(10) };
105 let flags = "";
106 for (let c of ["w", "b"]) {
107 if (c == 'b' && options.randomness == 1) {
108 pieces['b'] = pieces['w'];
109 flags += flags;
110 break;
111 }
112
113 let positions = ArrayFun.range(10);
114
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);
124
125 // Get random square for empress
126 randIndex = randInt(8);
127 const empressPos = positions[randIndex];
128 positions.splice(randIndex, 1);
129
130 // Get random square for princess
131 randIndex = randInt(7);
132 const princessPos = positions[randIndex];
133 positions.splice(randIndex, 1);
134
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);
142
143 // Get random square for queen
144 randIndex = randInt(4);
145 const queenPos = positions[randIndex];
146 positions.splice(randIndex, 1);
147
148 // Now rooks + king positions are fixed:
149 const rook1Pos = positions[0];
150 const kingPos = positions[1];
151 const rook2Pos = positions[2];
152
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);
165 }
166 return (
167 pieces["b"].join("") + "/pppppppppp/91/91/91/91/PPPPPPPPPP/" +
168 pieces["w"].join("").toUpperCase() + " w 0 " + flags + " - -"
169 );
170 }
171
172 };