Fixed Checkered variant
[xogo.git] / variants / Avalam / class.js
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",
45 both: [{steps: steps, range: 1}]
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)
69 fen = "9/".repeat(8) + "9";
70 else if (this.options["randomness"] == 0) {
71 fen = "2Bb5/1BbBb4/1bBbBbB2/1BbBbBbBb/BbBb1bBbB/" +
72 "bBbBbBbB1/2BbBbBb1/4bBbB1/5bB2";
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) +
82 "1/4" + a.substr(42, 4) + "1/5" + a.substr(46, 2) + "2"
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 = [];
159 for (let s of this.pieces()['b'].moves[0].steps) {
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 };