Commit | Line | Data |
---|---|---|
472c0c4f BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | import { ArrayFun } from "@/utils/array"; | |
3 | import { shuffle } from "@/utils/alea"; | |
4 | ||
5 | export class TencubedRules extends ChessRules { | |
7e8a7ea1 | 6 | |
472c0c4f BA |
7 | static get PawnSpecs() { |
8 | return Object.assign( | |
9 | {}, | |
10 | ChessRules.PawnSpecs, | |
11 | { | |
12 | initShift: { w: 2, b: 2 }, | |
13 | promotions: [V.QUEEN, V.MARSHALL, V.ARCHBISHOP] | |
14 | } | |
15 | ); | |
16 | } | |
17 | ||
18 | static get HasFlags() { | |
19 | return false; | |
20 | } | |
21 | ||
22 | getPpath(b) { | |
23 | return ( | |
24 | [V.MARSHALL, V.ARCHBISHOP, V.CHAMPION, V.WIZARD].includes(b[1]) | |
25 | ? "Tencubed/" | |
26 | : "" | |
27 | ) + b; | |
28 | } | |
29 | ||
30 | static get size() { | |
31 | return { x: 10, y: 10 }; | |
32 | } | |
33 | ||
34 | // Rook + knight: | |
35 | static get MARSHALL() { | |
36 | return "m"; | |
37 | } | |
38 | ||
39 | // Bishop + knight | |
40 | static get ARCHBISHOP() { | |
41 | return "a"; | |
42 | } | |
43 | ||
44 | // Dabbabah + alfil + wazir | |
45 | static get CHAMPION() { | |
46 | return "c"; | |
47 | } | |
48 | ||
49 | // Camel + ferz | |
50 | static get WIZARD() { | |
51 | return "w"; | |
52 | } | |
53 | ||
54 | static get PIECES() { | |
55 | return ( | |
56 | ChessRules.PIECES | |
57 | .concat([V.MARSHALL, V.ARCHBISHOP, V.CHAMPION, V.WIZARD]) | |
58 | ); | |
59 | } | |
60 | ||
61 | static get steps() { | |
62 | return Object.assign( | |
63 | {}, | |
64 | ChessRules.steps, | |
65 | { | |
66 | w: [ | |
67 | [-3, -1], | |
68 | [-3, 1], | |
69 | [-1, -3], | |
70 | [-1, 3], | |
71 | [1, -3], | |
72 | [1, 3], | |
73 | [3, -1], | |
74 | [3, 1], | |
75 | [-1, -1], | |
76 | [-1, 1], | |
77 | [1, -1], | |
78 | [1, 1] | |
79 | ], | |
80 | c: [ | |
81 | [1, 0], | |
82 | [-1, 0], | |
83 | [0, 1], | |
84 | [0, -1], | |
85 | [2, 2], | |
86 | [2, -2], | |
87 | [-2, 2], | |
88 | [-2, -2], | |
89 | [-2, 0], | |
90 | [0, -2], | |
91 | [2, 0], | |
92 | [0, 2] | |
93 | ] | |
94 | } | |
95 | ); | |
96 | } | |
97 | ||
98 | static GenRandInitFen(randomness) { | |
99 | if (randomness == 0) { | |
100 | return ( | |
101 | "2cwamwc2/1rnbqkbnr1/pppppppppp/91/91/" + | |
102 | "91/91/PPPPPPPPPP/1RNBQKBNR1/2CWAMWC2/ " + | |
103 | "w 0 bibi -" | |
104 | ); | |
105 | } | |
106 | ||
107 | const baseFen = V.ParseFen(ChessRules.GenRandInitFen(randomness)); | |
108 | const positionParts = baseFen.position.split("/"); | |
109 | const bFen = ( | |
110 | "1" + positionParts[0] + | |
111 | "1/pppppppppp/91/91/91/91/PPPPPPPPPP/1" + | |
112 | positionParts[7] + "1" | |
113 | ); | |
114 | // Now just obtain randomized new pieces placements: | |
115 | let pieces = { w: new Array(6), b: new Array(6) }; | |
116 | for (let c of ["w", "b"]) { | |
117 | if (c == 'b' && randomness == 1) { | |
118 | pieces['b'] = pieces['w']; | |
119 | break; | |
120 | } | |
121 | ||
122 | let positions = shuffle(ArrayFun.range(6)); | |
123 | const composition = ['w', 'w', 'c', 'c', 'a', 'm']; | |
124 | let rem2 = positions[0] % 2; | |
125 | if (rem2 == positions[1] % 2) { | |
126 | // Fix wizards (on different colors) | |
127 | for (let i=4; i<6; i++) { | |
128 | if (positions[i] % 2 != rem2) | |
129 | [positions[1], positions[i]] = [positions[i], positions[1]]; | |
130 | } | |
131 | } | |
132 | rem2 = positions[2] % 2; | |
133 | if (rem2 == positions[3] % 2) { | |
134 | // Fix champions too: [NOTE: positions[4] & [5] should do] | |
135 | for (let i=4; i<6; i++) { | |
136 | if (positions[i] % 2 != rem2) | |
137 | [positions[3], positions[i]] = [positions[i], positions[3]]; | |
138 | } | |
139 | } | |
140 | for (let i = 0; i < 9; i++) pieces[c][positions[i]] = composition[i]; | |
141 | } | |
142 | return ( | |
143 | "2" + pieces["b"].join("") + "2/" + | |
144 | bFen + | |
145 | "/2" + pieces["w"].join("").toUpperCase() + "2" + | |
146 | " w 0 -" | |
147 | ); | |
148 | } | |
149 | ||
150 | getPotentialMovesFrom([x, y]) { | |
151 | switch (this.getPiece(x, y)) { | |
152 | case V.MARSHALL: | |
153 | return this.getPotentialMarshallMoves([x, y]); | |
154 | case V.ARCHBISHOP: | |
155 | return this.getPotentialArchbishopMoves([x, y]); | |
156 | case V.CHAMPION: | |
157 | return this.getPotentialChampionMoves([x, y]); | |
158 | case V.WIZARD: | |
159 | return this.getPotentialWizardMoves([x, y]); | |
160 | default: | |
161 | return super.getPotentialMovesFrom([x, y]); | |
162 | } | |
163 | } | |
164 | ||
165 | getPotentialMarshallMoves(sq) { | |
166 | return this.getSlideNJumpMoves(sq, V.steps[V.ROOK]).concat( | |
167 | this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep") | |
168 | ); | |
169 | } | |
170 | ||
171 | getPotentialArchbishopMoves(sq) { | |
172 | return this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat( | |
173 | this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep") | |
174 | ); | |
175 | } | |
176 | ||
177 | getPotentialChampionMoves(sq) { | |
178 | return this.getSlideNJumpMoves(sq, V.steps[V.CHAMPION], "oneStep"); | |
179 | } | |
180 | ||
181 | getPotentialWizardMoves(sq) { | |
182 | return this.getSlideNJumpMoves(sq, V.steps[V.WIZARD], "oneStep"); | |
183 | } | |
184 | ||
185 | isAttacked(sq, color) { | |
186 | return ( | |
187 | super.isAttacked(sq, color) || | |
188 | this.isAttackedByMarshall(sq, color) || | |
189 | this.isAttackedByArchbishop(sq, color) || | |
190 | this.isAttackedByChampion(sq, color) || | |
191 | this.isAttackedByWizard(sq, color) | |
192 | ); | |
193 | } | |
194 | ||
195 | isAttackedByMarshall(sq, color) { | |
196 | return ( | |
197 | this.isAttackedBySlideNJump(sq, color, V.MARSHALL, V.steps[V.ROOK]) || | |
198 | this.isAttackedBySlideNJump( | |
199 | sq, | |
200 | color, | |
201 | V.MARSHALL, | |
202 | V.steps[V.KNIGHT], | |
203 | "oneStep" | |
204 | ) | |
205 | ); | |
206 | } | |
207 | ||
208 | isAttackedByArchbishop(sq, color) { | |
209 | return ( | |
b2655276 | 210 | this.isAttackedBySlideNJump(sq, color, V.ARCHBISHOP, V.steps[V.BISHOP]) || |
472c0c4f BA |
211 | this.isAttackedBySlideNJump( |
212 | sq, | |
213 | color, | |
b2655276 | 214 | V.ARCHBISHOP, |
472c0c4f BA |
215 | V.steps[V.KNIGHT], |
216 | "oneStep" | |
217 | ) | |
218 | ); | |
219 | } | |
220 | ||
221 | isAttackedByWizard(sq, color) { | |
222 | return ( | |
223 | this.isAttackedBySlideNJump( | |
224 | sq, color, V.WIZARD, V.steps[V.WIZARD], "oneStep") | |
225 | ); | |
226 | } | |
227 | ||
228 | isAttackedByChampion(sq, color) { | |
229 | return ( | |
230 | this.isAttackedBySlideNJump( | |
231 | sq, color, V.CHAMPION, V.steps[V.CHAMPION], "oneStep") | |
232 | ); | |
233 | } | |
234 | ||
235 | static get SEARCH_DEPTH() { | |
236 | return 2; | |
237 | } | |
238 | ||
239 | static get VALUES() { | |
240 | return Object.assign( | |
241 | {}, | |
242 | ChessRules.VALUES, | |
243 | { c: 4, w: 3, a: 6, m: 8 } | |
244 | ); | |
245 | } | |
7e8a7ea1 | 246 | |
472c0c4f | 247 | }; |