Fix Musketeer, Joker, Shinobi. Start draft of Cwda
[vchess.git] / client / src / variants / Cwda.js
1 import { ChessRules, Move, PiPo } from "@/base_rules";
2 import { ArrayFun } from "@/utils/array";
3 import { randInt } from "@/utils/alea";
4
5 export class CwdaRules extends ChessRules {
6
7 static get PawnSpecs() {
8 return Object.assign(
9 {},
10 ChessRules.PawnSpecs,
11 {
12 promotions:
13 ChessRules.PawnSpecs.promotions.concat(
14 [V.C_ROOK, V.C_KNIGHT, V.C_BISHOP, V.C_QUEEN])
15 }
16 );
17 }
18
19 getPpath(b) {
20 if ([V.C_ROOK, V.C_KNIGHT, V.C_BISHOP, V.C_QUEEN].includes(b[1]))
21 return "Cwda/" + b;
22 return b;
23 }
24
25 static GenRandInitFen(randomness) {
26 if (randomness == 0)
27 return "dhaskahd/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w 0 ahah -";
28
29 // Mapping white --> black (at least at start):
30 const piecesMap = {
31 'r': 'd',
32 'n': 'h',
33 'b': 'a',
34 'q': 's',
35 'k': 'k'
36 };
37
38 const baseFen = ChessRules.GenRandInitFen(randomness);
39 return (
40 baseFen.substr(0, 8).split('').map(p => piecesMap[p]).join('') +
41 baseFen.substr(8)
42 );
43 }
44
45 static get C_ROOK() {
46 return 'd';
47 }
48 static get C_KNIGHT() {
49 return 'h';
50 }
51 static get C_BISHOP() {
52 return 'a';
53 }
54 static get C_QUEEN() {
55 return 's';
56 }
57
58 static get PIECES() {
59 return (
60 ChessRules.PIECES.concat([V.C_ROOK, V.C_KNIGHT, V.C_BISHOP, V.C_QUEEN])
61 );
62 }
63
64 getPotentialMovesFrom([x, y]) {
65 switch (this.getPiece(x, y)) {
66 case V.C_ROOK: return this.getPotentialC_rookMoves([x, y]);
67 case V.C_KNIGHT: return this.getPotentialC_knightMoves([x, y]);
68 case V.C_BISHOP: return this.getPotentialC_bishopMoves([x, y]);
69 case V.C_QUEEN: return this.getPotentialC_queenMoves([x, y]);
70 default: return super.getPotentialMovesFrom([x, y]);
71 }
72 return [];
73 }
74
75 static get steps() {
76 return Object.assign(
77 {},
78 ChessRules.steps,
79 {
80 // Dabbabah
81 'd': [
82 [-2, 0],
83 [0, -2],
84 [2, 0],
85 [0, 2]
86 ],
87 // Alfil
88 'a': [
89 [2, 2],
90 [2, -2],
91 [-2, 2],
92 [-2, -2]
93 ],
94 // Ferz
95 'f': [
96 [1, 1],
97 [1, -1],
98 [-1, 1],
99 [-1, -1]
100 ]
101 }
102 );
103 }
104
105 getPotentialC_rookMoves(sq) {
106 return (
107 this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat(
108 this.getSlideNJumpMoves(sq, V.steps['d'], "oneStep"))
109 );
110 }
111
112 getPotentialC_knightMoves(sq) {
113 return (
114 this.getSlideNJumpMoves(sq, V.steps['a'], "oneStep").concat(
115 this.getSlideNJumpMoves(sq, V.steps[V.ROOK], "oneStep"))
116 );
117 }
118
119 getPotentialC_bishopMoves(sq) {
120 return (
121 this.getSlideNJumpMoves(sq, V.steps['d'], "oneStep").concat(
122 this.getSlideNJumpMoves(sq, V.steps['a'], "oneStep")).concat(
123 this.getSlideNJumpMoves(sq, V.steps[V.BISHOP], "oneStep"))
124 );
125 }
126
127 getPotentialC_queenMoves(sq) {
128 return (
129 this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat(
130 this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep"))
131 );
132 }
133
134 getCastleMoves([x, y]) {
135 const color = this.getColor(x, y);
136 const finalSquares = [
137 // Black castle long in an unusual way:
138 (color == 'w' ? [2, 3] : [1, 2]),
139 [V.size.y - 2, V.size.y - 3]
140 ];
141 return super.getCastleMoves([x, y], finalSquares);
142 }
143
144 isAttacked(sq, color) {
145 return (
146 super.isAttacked(sq, color) ||
147 this.isAttackedByC_rook(sq, color) ||
148 this.isAttackedByC_knight(sq, color) ||
149 this.isAttackedByC_bishop(sq, color) ||
150 this.isAttackedByC_queen(sq, color)
151 );
152 }
153
154 isAttackedByC_rook(sq, color) {
155 return (
156 this.isAttackedBySlideNJump(sq, color, V.C_ROOK, V.steps[V.BISHOP]) ||
157 this.isAttackedBySlideNJump(
158 sq, color, V.C_ROOK, V.steps['d'], "oneStep")
159 );
160 }
161
162 isAttackedByC_knight(sq, color) {
163 return (
164 this.isAttackedBySlideNJump(
165 sq, color, V.C_KNIGHT, V.steps[V.ROOK], "oneStep") ||
166 this.isAttackedBySlideNJump(
167 sq, color, V.C_KNIGHT, V.steps['a'], "oneStep")
168 );
169 }
170
171 isAttackedByC_bishop(sq, color) {
172 return (
173 this.isAttackedBySlideNJump(
174 sq, color, V.C_BISHOP, V.steps['d'], "oneStep") ||
175 this.isAttackedBySlideNJump(
176 sq, color, V.C_BISHOP, V.steps['a'], "oneStep") ||
177 this.isAttackedBySlideNJump(
178 sq, color, V.C_BISHOP, V.steps['f'], "oneStep")
179 );
180 }
181
182 isAttackedByC_queen(sq, color) {
183 return (
184 this.isAttackedBySlideNJump(sq, color, V.C_QUEEN, V.steps[V.BISHOP]) ||
185 this.isAttackedBySlideNJump(
186 sq, color, V.C_QUEEN, V.steps[V.KNIGHT], "oneStep")
187 );
188 }
189
190 static get VALUES() {
191 return Object.assign(
192 {},
193 ChessRules.VALUES,
194 {
195 d: 4,
196 h: 3,
197 a: 5,
198 s: 6
199 }
200 );
201 }
202
203 static get SEARCH_DEPTH() {
204 return 2;
205 }
206
207 };