85f81ef3765979d26832a2d7bb72ce19e8ae1f97
[vchess.git] / client / src / variants / Colorbound.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 ColorboundRules 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 "Colorbound/" + 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:
67 return this.getPotentialC_rookMoves([x, y]);
68 case V.C_KNIGHT:
69 return this.getPotentialC_knightMoves([x, y]);
70 case V.C_BISHOP:
71 return this.getPotentialC_bishopMoves([x, y]);
72 case V.C_QUEEN:
73 return this.getPotentialC_queenMoves([x, y]);
74 default:
75 return super.getPotentialMovesFrom([x, y]);
76 }
77 return [];
78 }
79
80 static get steps() {
81 return Object.assign(
82 {},
83 ChessRules.steps,
84 {
85 // Dabbabah
86 'd': [
87 [-2, 0],
88 [0, -2],
89 [2, 0],
90 [0, 2]
91 ],
92 // Alfil
93 'a': [
94 [2, 2],
95 [2, -2],
96 [-2, 2],
97 [-2, -2]
98 ],
99 // Ferz
100 'f': [
101 [1, 1],
102 [1, -1],
103 [-1, 1],
104 [-1, -1]
105 ]
106 }
107 );
108 }
109
110 getPotentialC_rookMoves(sq) {
111 return (
112 this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat(
113 this.getSlideNJumpMoves(sq, V.steps['d'], "oneStep"))
114 );
115 }
116
117 getPotentialC_knightMoves(sq) {
118 return (
119 this.getSlideNJumpMoves(sq, V.steps['a'], "oneStep").concat(
120 this.getSlideNJumpMoves(sq, V.steps[V.ROOK], "oneStep"))
121 );
122 }
123
124 getPotentialC_bishopMoves(sq) {
125 return (
126 this.getSlideNJumpMoves(sq, V.steps['d'], "oneStep").concat(
127 this.getSlideNJumpMoves(sq, V.steps['a'], "oneStep")).concat(
128 this.getSlideNJumpMoves(sq, V.steps[V.BISHOP], "oneStep"))
129 );
130 }
131
132 getPotentialC_queenMoves(sq) {
133 return (
134 this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat(
135 this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep"))
136 );
137 }
138
139 getCastleMoves([x, y]) {
140 const color = this.getColor(x, y);
141 const finalSquares = [
142 // Black castle long in an unusual way:
143 (color == 'w' ? [2, 3] : [1, 2]),
144 [V.size.y - 2, V.size.y - 3]
145 ];
146 return super.getCastleMoves([x, y], finalSquares);
147 }
148
149 isAttacked(sq, color) {
150 return (
151 super.isAttacked(sq, color) ||
152 this.isAttackedByC_rook(sq, color) ||
153 this.isAttackedByC_knight(sq, color) ||
154 this.isAttackedByC_bishop(sq, color) ||
155 this.isAttackedByC_queen(sq, color)
156 );
157 }
158
159 isAttackedByC_rook(sq, color) {
160 return (
161 this.isAttackedBySlideNJump(sq, color, V.C_ROOK, V.steps[V.BISHOP]) ||
162 this.isAttackedBySlideNJump(
163 sq, color, V.C_ROOK, V.steps['d'], "oneStep")
164 );
165 }
166
167 isAttackedByC_knight(sq, color) {
168 return (
169 this.isAttackedBySlideNJump(
170 sq, color, V.C_KNIGHT, V.steps[V.ROOK], "oneStep") ||
171 this.isAttackedBySlideNJump(
172 sq, color, V.C_KNIGHT, V.steps['a'], "oneStep")
173 );
174 }
175
176 isAttackedByC_bishop(sq, color) {
177 return (
178 this.isAttackedBySlideNJump(
179 sq, color, V.C_BISHOP, V.steps['d'], "oneStep") ||
180 this.isAttackedBySlideNJump(
181 sq, color, V.C_BISHOP, V.steps['a'], "oneStep") ||
182 this.isAttackedBySlideNJump(
183 sq, color, V.C_BISHOP, V.steps['f'], "oneStep")
184 );
185 }
186
187 isAttackedByC_queen(sq, color) {
188 return (
189 this.isAttackedBySlideNJump(sq, color, V.C_QUEEN, V.steps[V.BISHOP]) ||
190 this.isAttackedBySlideNJump(
191 sq, color, V.C_QUEEN, V.steps[V.KNIGHT], "oneStep")
192 );
193 }
194
195 static get VALUES() {
196 return Object.assign(
197 {},
198 ChessRules.VALUES,
199 {
200 d: 4,
201 h: 3,
202 a: 5,
203 s: 6
204 }
205 );
206 }
207
208 static get SEARCH_DEPTH() {
209 return 2;
210 }
211
212 };