Commit | Line | Data |
---|---|---|
9b760538 BA |
1 | import ChessRules from "/base_rules.js"; |
2 | import {Random} from "/utils/alea.js"; | |
3 | import PiPo from "/utils/PiPo.js"; | |
4 | import Move from "/utils/Move.js"; | |
5 | ||
6 | export default class AvalamRules extends ChessRules { | |
7 | ||
8 | static get Options() { | |
9 | return { | |
10 | select: [{ | |
11 | label: "Randomness", | |
12 | variable: "randomness", | |
13 | defaut: 1, | |
14 | options: [ | |
15 | {label: "Deterministic", value: 0}, | |
16 | {label: "Random", value: 1}, | |
17 | ] | |
18 | }], | |
19 | input: [ | |
20 | { | |
21 | label: "Free placement", | |
22 | variable: "freefill", | |
23 | type: "checkbox", | |
24 | defaut: false | |
25 | } | |
26 | ] | |
27 | }; | |
28 | } | |
29 | ||
30 | get hasFlags() { | |
31 | return false; | |
32 | } | |
33 | get hasEnpassant() { | |
34 | return false; | |
35 | } | |
36 | ||
37 | pieces(color, x, y) { | |
38 | const steps = [ | |
39 | [1, 0], [0, 1], [-1, 0], [0, -1], | |
40 | [1, 1], [1, -1], [-1, 1], [-1, -1] | |
41 | ]; | |
42 | return { | |
43 | 'b': { | |
44 | "class": "stack", | |
33b42748 | 45 | both: [{steps: steps, range: 1}] |
9b760538 BA |
46 | }, |
47 | 'c': { | |
48 | "class": "stack2", | |
49 | moveas: 'b' | |
50 | }, | |
51 | 'd': { | |
52 | "class": "stack3", | |
53 | moveas: 'b' | |
54 | }, | |
55 | 'e': { | |
56 | "class": "stack4", | |
57 | moveas: 'b' | |
58 | }, | |
59 | 'f': { | |
60 | "class": "stack5", | |
61 | moveas: 'b' | |
62 | } | |
63 | }; | |
64 | } | |
65 | ||
66 | genRandInitBaseFen() { | |
67 | let fen = ""; | |
68 | if (this.freefill) | |
dc10e429 | 69 | fen = "9/".repeat(8) + "9"; |
9b760538 BA |
70 | else if (this.options["randomness"] == 0) { |
71 | fen = "2Bb5/1BbBb4/1bBbBbB2/1BbBbBbBb/BbBb1bBbB/" + | |
dc10e429 | 72 | "bBbBbBbB1/2BbBbBb1/4bBbB1/5bB2"; |
9b760538 BA |
73 | } |
74 | else { | |
75 | const pieces = ('B'.repeat(24) + 'b'.repeat(24)).split(""); | |
76 | const a = Random.shuffle(pieces, 48).join(""); | |
77 | fen = ( | |
78 | "2" + a.substr(0, 2) + "5/1" + a.substr(2, 4) + | |
79 | "4/1" + a.substr(6, 6) + "2/1" + a.substr(12, 8) + | |
80 | "/" + a.substr(20, 4) + "1" + a.substr(24, 4) + | |
81 | "/" + a.substr(28, 8) + "1/2" + a.substr(36, 6) + | |
dc10e429 | 82 | "1/4" + a.substr(42, 4) + "1/5" + a.substr(46, 2) + "2" |
9b760538 BA |
83 | ); |
84 | } | |
85 | return { fen: fen, o: {} }; | |
86 | } | |
87 | ||
88 | getSquareColorClass(x, y) { | |
89 | return "board-sq"; | |
90 | } | |
91 | ||
92 | get size() { | |
93 | return {x: 9, y: 9}; | |
94 | } | |
95 | ||
96 | onBoard(x, y) { | |
97 | if (!super.onBoard(x, y)) | |
98 | return false; | |
99 | switch (x) { | |
100 | case 0: | |
101 | return [2, 3].includes(y); | |
102 | case 1: | |
103 | return [1, 2, 3, 4].includes(y); | |
104 | case 2: | |
105 | return [1, 2, 3, 4, 5, 6].includes(y); | |
106 | case 3: | |
107 | return y >= 1; | |
108 | case 4: | |
109 | return y != 4; | |
110 | case 5: | |
111 | return y <= 7; | |
112 | case 6: | |
113 | return [2, 3, 4, 5, 6, 7].includes(y); | |
114 | case 7: | |
115 | return [4, 5, 6, 7].includes(y); | |
116 | case 8: | |
117 | return [5, 6].includes(y); | |
118 | } | |
119 | return false; //never reached | |
120 | } | |
121 | ||
122 | canIplay() { | |
123 | return this.playerColor == this.turn; | |
124 | } | |
125 | ||
126 | doClick(coords) { | |
127 | if (!this.freefill || this.board[coords.x][coords.y] != "") | |
128 | return null; | |
129 | return new Move({ | |
130 | start: {x: coords.x, y: coords.y}, | |
131 | vanish: [], | |
132 | appear: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: 'b'})] | |
133 | }); | |
134 | } | |
135 | ||
136 | getBasicMove([x1, y1], [x2, y2]) { | |
137 | const cp1 = this.board[x1][y1], | |
138 | cp2 = this.board[x2][y2]; | |
139 | const newPiece = | |
140 | String.fromCharCode(cp1.charCodeAt(1) + cp2.charCodeAt(1) - 97); | |
141 | return ( | |
142 | new Move({ | |
143 | vanish: [ | |
144 | new PiPo({ x: x1, y: y1, c: cp1.charAt(0), p: cp1.charAt(1) }), | |
145 | new PiPo({ x: x2, y: y2, c: cp2.charAt(0), p: cp2.charAt(1) }) | |
146 | ], | |
147 | appear: [ | |
148 | new PiPo({ x: x2, y: y2, c: cp1.charAt(0), p: newPiece }) | |
149 | ] | |
150 | }) | |
151 | ); | |
152 | } | |
153 | ||
154 | getPotentialMovesFrom([x, y]) { | |
155 | const height = this.board[x][y].charCodeAt(1) - 97; | |
156 | if (height == 5) | |
157 | return []; | |
158 | let moves = []; | |
bc97fdd1 | 159 | for (let s of this.pieces(this.turn, x, y)['b'].both[0].steps) { |
9b760538 BA |
160 | const [i, j] = [x + s[0], y + s[1]]; |
161 | if ( | |
162 | this.onBoard(i, j) && | |
163 | this.board[i][j] != "" && | |
164 | (height + this.board[i][j].charCodeAt(1) - 97 <= 5) | |
165 | ) { | |
166 | moves.push(this.getBasicMove([x, y], [i, j])); | |
167 | } | |
168 | } | |
169 | return moves; | |
170 | } | |
171 | ||
172 | filterValid(moves) { | |
173 | return moves; | |
174 | } | |
175 | ||
176 | getCurrentScore() { | |
177 | let towersCount = {w: 0, b: 0}; | |
178 | for (let i = 0; i < this.size.x; i++) { | |
179 | for (let j = 0; j < this.size.y; j++) { | |
180 | if (this.board[i][j] != "") { | |
181 | if (this.getPotentialMovesFrom([i, j]).length > 0) | |
182 | return '*'; | |
183 | towersCount[ this.board[i][j][0] ]++; | |
184 | } | |
185 | } | |
186 | } | |
187 | if (towersCount['w'] > towersCount['b']) | |
188 | return "1-0"; | |
189 | if (towersCount['b'] > towersCount['w']) | |
190 | return "0-1"; | |
191 | return "1/2"; | |
192 | } | |
193 | ||
194 | }; |