Commit | Line | Data |
---|---|---|
0f7762c1 BA |
1 | import { ChessRules } from "@/base_rules"; |
2 | ||
3 | export class AlapoRules extends ChessRules { | |
4 | ||
5 | static get HasFlags() { | |
6 | return false; | |
7 | } | |
8 | ||
9 | static get HasEnpassant() { | |
10 | return false; | |
11 | } | |
12 | ||
13 | static get Lines() { | |
14 | return [ | |
15 | [[1, 0], [1, 6]], | |
16 | [[5, 0], [5, 6]] | |
17 | ]; | |
18 | } | |
19 | ||
20 | static get PIECES() { | |
21 | return [V.ROOK, V.BISHOP, V.QUEEN, V.ROOK_S, V.BISHOP_S, V.QUEEN_S]; | |
22 | } | |
23 | ||
24 | static get ROOK_S() { | |
25 | return "t"; | |
26 | } | |
27 | static get BISHOP_S() { | |
28 | return "c"; | |
29 | } | |
30 | static get QUEEN_S() { | |
31 | return "s"; | |
32 | } | |
33 | ||
34 | getPotentialMinirookMoves(sq) { | |
35 | return super.getSlideNJumpMoves(sq, V.steps[V.ROOK], "oneStep"); | |
36 | } | |
37 | getPotentialMinibishopMoves(sq) { | |
38 | return super.getSlideNJumpMoves(sq, V.steps[V.BISHOP], "oneStep"); | |
39 | } | |
40 | getPotentialMiniqueenMoves(sq) { | |
41 | return ( | |
42 | super.getSlideNJumpMoves( | |
43 | sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep") | |
44 | ); | |
45 | } | |
46 | ||
47 | getPotentialMovesFrom(sq) { | |
48 | switch (this.getPiece(sq[0], sq[1])) { | |
49 | case V.ROOK: return super.getPotentialRookMoves(sq); | |
50 | case V.BISHOP: return super.getPotentialBishopMoves(sq); | |
51 | case V.QUEEN: return super.getPotentialQueenMoves(sq); | |
52 | case V.ROOK_S: return this.getPotentialMinirookMoves(sq); | |
53 | case V.BISHOP_S: return this.getPotentialMinibishopMoves(sq); | |
54 | case V.QUEEN_S: return this.getPotentialMiniqueenMoves(sq); | |
55 | } | |
56 | return []; | |
57 | } | |
58 | ||
59 | static get size() { | |
60 | return { x: 6, y: 6 }; | |
61 | } | |
62 | ||
63 | getPpath(b, color, score, orientation) { | |
64 | // 'i' for "inversed": | |
65 | const suffix = (b[0] == orientation ? "" : "i"); | |
66 | return "Alapo/" + b + suffix; | |
67 | } | |
68 | ||
69 | static GenRandInitFen(randomness) { | |
70 | if (randomness == 0) | |
71 | return "rbqqbr/tcssct/6/6/TCSSCT/RBQQBR w 0"; | |
72 | ||
73 | const piece2pawn = { | |
74 | r: 't', | |
75 | q: 's', | |
76 | b: 'c' | |
77 | }; | |
78 | ||
79 | let pieces = { w: new Array(6), b: new Array(6) }; | |
80 | // Shuffle pieces on first (and last rank if randomness == 2) | |
81 | for (let c of ["w", "b"]) { | |
82 | if (c == 'b' && randomness == 1) { | |
83 | pieces['b'] = pieces['w']; | |
84 | break; | |
85 | } | |
86 | ||
87 | let positions = ArrayFun.range(6); | |
88 | ||
89 | // Get random squares for bishops | |
90 | let randIndex = 2 * randInt(3); | |
91 | const bishop1Pos = positions[randIndex]; | |
92 | let randIndex_tmp = 2 * randInt(3) + 1; | |
93 | const bishop2Pos = positions[randIndex_tmp]; | |
94 | positions.splice(Math.max(randIndex, randIndex_tmp), 1); | |
95 | positions.splice(Math.min(randIndex, randIndex_tmp), 1); | |
96 | ||
97 | // Get random square for queens | |
98 | randIndex = randInt(4); | |
99 | const queen1Pos = positions[randIndex]; | |
100 | positions.splice(randIndex, 1); | |
101 | randIndex = randInt(3); | |
102 | const queen2Pos = positions[randIndex]; | |
103 | positions.splice(randIndex, 1); | |
104 | ||
105 | // Rooks positions are now fixed, | |
106 | const rook1Pos = positions[0]; | |
107 | const rook2Pos = positions[1]; | |
108 | ||
109 | pieces[c][rook1Pos] = "r"; | |
110 | pieces[c][bishop1Pos] = "b"; | |
111 | pieces[c][queen1Pos] = "q"; | |
112 | pieces[c][queen2Pos] = "q"; | |
113 | pieces[c][bishop2Pos] = "b"; | |
114 | pieces[c][rook2Pos] = "r"; | |
115 | } | |
116 | return ( | |
117 | pieces["b"].join("") + "/" + | |
118 | pieces["b"].map(p => piece2pawn[p]).join() + | |
119 | "/8/8/8/8/" + | |
120 | pieces["w"].map(p => piece2pawn[p].toUpperCase()).join() + "/" + | |
121 | pieces["w"].join("").toUpperCase() + | |
122 | " w 0" | |
123 | ); | |
124 | } | |
125 | ||
126 | static IsGoodPosition(position) { | |
127 | if (position.length == 0) return false; | |
128 | const rows = position.split("/"); | |
129 | if (rows.length != V.size.x) return false; | |
130 | // Just check that at least one piece of each color is there: | |
131 | let pieces = { "w": 0, "b": 0 }; | |
132 | for (let row of rows) { | |
133 | let sumElts = 0; | |
134 | for (let i = 0; i < row.length; i++) { | |
135 | const lowerRi = row[i].toLowerCase(); | |
136 | if (V.PIECES.includes(lowerRi)) { | |
137 | pieces[row[i] == lowerRi ? "b" : "w"]++; | |
138 | sumElts++; | |
139 | } | |
140 | else { | |
141 | const num = parseInt(row[i], 10); | |
142 | if (isNaN(num)) return false; | |
143 | sumElts += num; | |
144 | } | |
145 | } | |
146 | if (sumElts != V.size.y) return false; | |
147 | } | |
148 | if (Object.values(pieces).some(v => v == 0)) return false; | |
149 | return true; | |
150 | } | |
151 | ||
152 | // Find possible captures by opponent on [x, y] | |
153 | findCaptures([x, y]) { | |
154 | const color = this.getColor(x, y); | |
155 | let moves = []; | |
156 | const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); | |
157 | const oppCol = V.GetOppCol(color); | |
158 | for (let loop = 0; loop < steps.length; loop++) { | |
159 | const step = steps[loop]; | |
160 | let i = x + step[0]; | |
161 | let j = y + step[1]; | |
162 | let stepsAfter = 1; | |
163 | while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { | |
164 | i += step[0]; | |
165 | j += step[1]; | |
166 | stepsAfter++; | |
167 | } | |
168 | if ( | |
169 | V.OnBoard(i, j) && | |
170 | this.board[i][j] != V.EMPTY && | |
171 | this.getColor(i, j) == oppCol | |
172 | ) { | |
173 | const oppPiece = this.getPiece(i, j); | |
174 | if ( | |
175 | ( | |
176 | stepsAfter >= 2 && | |
177 | [V.ROOK_S, V.BISHOP_S, V.QUEEN_S].includes(oppPiece) | |
178 | ) | |
179 | || | |
180 | ( | |
181 | [V.BISHOP, V.BISHOP_S].includes(oppPiece) && | |
182 | step.some(e => e == 0) | |
183 | ) | |
184 | || | |
185 | ( | |
186 | [V.ROOK, V.ROOK_S].includes(oppPiece) && | |
187 | step.every(e => e != 0) | |
188 | ) | |
189 | ) { | |
190 | continue; | |
191 | } | |
192 | return true; | |
193 | } | |
194 | } | |
195 | return false; | |
196 | } | |
197 | ||
198 | postPlay() {} | |
199 | postUndo() {} | |
200 | ||
201 | getCheckSquares() { | |
202 | return []; | |
203 | } | |
204 | filterValid(moves) { | |
205 | return moves; | |
206 | } | |
207 | ||
208 | getCurrentScore() { | |
209 | // Try both colors (to detect potential suicides) | |
210 | for (let c of ['w', 'b']) { | |
211 | const oppCol = V.GetOppCol(c); | |
212 | const goal = (c == 'w' ? 0 : 5); | |
213 | if ( | |
214 | this.board[goal].some( | |
215 | (b,j) => b[0] == c && !this.findCaptures([goal, j]) | |
216 | ) | |
217 | ) { | |
218 | return c == 'w' ? "1-0" : "0-1"; | |
219 | } | |
220 | } | |
221 | return super.getCurrentScore(); | |
222 | } | |
223 | ||
ded43c88 BA |
224 | static get VALUES() { |
225 | return { | |
226 | r: 5, | |
227 | b: 3, | |
228 | q: 9, | |
229 | t: 3, | |
230 | c: 2, | |
231 | s: 5 | |
232 | }; | |
233 | } | |
234 | ||
0f7762c1 | 235 | }; |