Commit | Line | Data |
---|---|---|
d6d0a46e | 1 | import ChessRules from "/base_rules.js"; |
d6d0a46e BA |
2 | import PiPo from "/utils/PiPo.js"; |
3 | import Move from "/utils/Move.js"; | |
4 | ||
5 | export default class AvalancheRules extends ChessRules { | |
6 | ||
7 | static get Options() { | |
8 | return { | |
9 | select: C.Options.select, | |
bc97fdd1 BA |
10 | input: [ |
11 | { | |
12 | label: "Balanced", | |
13 | variable: "balanced", | |
14 | type: "checkbox", | |
15 | defaut: false | |
16 | } | |
17 | ], | |
d6d0a46e BA |
18 | styles: [ |
19 | "atomic", | |
20 | "cannibal", | |
21 | "capture", | |
22 | "crazyhouse", | |
23 | "cylinder", | |
24 | "dark", | |
25 | "madrasi", | |
26 | "recycle", | |
27 | "rifle", | |
28 | "teleport", | |
29 | "zen" | |
30 | ] | |
31 | }; | |
32 | } | |
33 | ||
34 | get hasEnpassant() { | |
35 | return false; | |
36 | } | |
37 | ||
38 | getPartFen(o) { | |
39 | return Object.assign( | |
40 | {promotion: o.init ? false : this.promotion}, | |
41 | super.getPartFen(o) | |
42 | ); | |
43 | } | |
44 | ||
45 | setOtherVariables(fenParsed) { | |
46 | super.setOtherVariables(fenParsed); | |
47 | this.promotion = (fenParsed.promotion == '1'); | |
48 | this.subTurn = 1 - (this.promotion ? 1 : 0); | |
49 | } | |
50 | ||
51 | doClick(coords) { | |
52 | const myLastRank = (this.turn == 'w' ? 0 : this.size.x - 1); | |
53 | if ( | |
54 | this.subTurn != 0 || | |
55 | coords.x != myLastRank || | |
56 | this.getPiece(coords.x, coords.y) != 'p' | |
57 | ) { | |
58 | return null; | |
59 | } | |
60 | let moves = []; | |
61 | this.pawnPromotions.forEach(pr => { | |
62 | moves.push( | |
63 | new Move({ | |
64 | vanish: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: 'p'})], | |
65 | appear: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: pr})] | |
66 | }) | |
67 | ); | |
68 | }); | |
69 | super.showChoices(moves); | |
70 | } | |
71 | ||
72 | canIplay(x, y) { | |
73 | const pieceColor = this.getColor(x, y); | |
74 | return ( | |
75 | this.playerColor == this.turn && | |
76 | ( | |
77 | (this.subTurn <= 1 && pieceColor == this.playerColor) || | |
78 | ( | |
79 | this.subTurn == 2 && | |
80 | pieceColor != this.playerColor && | |
81 | this.getPiece(x, y) == 'p' | |
82 | ) | |
83 | ) | |
84 | ); | |
85 | } | |
86 | ||
87 | getPotentialMovesFrom([x, y]) { | |
88 | if (this.subTurn == 0) | |
89 | return []; | |
90 | if (this.subTurn == 1) | |
91 | // Usual case: | |
92 | return super.getPotentialMovesFrom([x, y]); | |
93 | // subTurn == 2: only allowed to push an opponent's pawn (if possible) | |
94 | const oppPawnShift = (this.turn == 'w' ? 1 : -1); | |
95 | if ( | |
96 | this.onBoard(x + oppPawnShift, y) && | |
97 | this.board[x + oppPawnShift][y] == "" | |
98 | ) { | |
99 | return [this.getBasicMove([x, y], [x + oppPawnShift, y])]; | |
100 | } | |
101 | return []; | |
102 | } | |
103 | ||
104 | filterValid(moves) { | |
105 | if (this.subTurn != 1) | |
106 | return moves; //self-checks by pawns are allowed | |
107 | return super.filterValid(moves); | |
108 | } | |
109 | ||
110 | atLeastOnePawnPush(color) { | |
111 | const pawnShift = (color == 'w' ? -1 : 1); | |
112 | for (let i = 0; i < 8; i++) { | |
113 | for (let j = 0; j < 8; j++) { | |
114 | if ( | |
115 | this.board[i][j] != "" && | |
116 | this.getColor(i, j) == color && | |
117 | this.getPiece(i, j) == 'p' && | |
118 | this.board[i + pawnShift][j] == "" | |
119 | ) { | |
120 | return true; | |
121 | } | |
122 | } | |
123 | } | |
124 | return false; | |
125 | } | |
126 | ||
bc97fdd1 | 127 | tryChangeTurn(move) { |
d6d0a46e | 128 | const color = this.turn; |
616a8d7a | 129 | const oppCol = C.GetOppTurn(color); |
bc97fdd1 BA |
130 | const incrementTurn = () => { |
131 | if (this.options["balanced"] && this.movesCount == 0) { | |
132 | // No pawn push on move 1: | |
133 | return true; | |
d6d0a46e | 134 | } |
bc97fdd1 BA |
135 | this.promotion = ( |
136 | this.subTurn == 2 && | |
137 | move.end.x == (oppCol == 'w' ? 0 : this.size.x - 1) && | |
138 | move.vanish[0].p == 'p' | |
139 | ); | |
140 | if (this.subTurn == 0) { | |
141 | this.subTurn++; | |
142 | if (!this.atLeastOneMove(color)) { | |
143 | move.result = "1/2"; //avoid re-computation | |
144 | return true; | |
145 | } | |
146 | return false; | |
147 | } | |
148 | if (this.subTurn == 2) { | |
149 | this.subTurn = (this.promotion ? 0 : 1); | |
150 | return true; | |
151 | } | |
152 | // subTurn == 1, usual case | |
d6d0a46e BA |
153 | const kingCapture = this.searchKingPos(oppCol).length == 0; |
154 | if (kingCapture) | |
155 | move.result = (color == 'w' ? "1-0" : "0-1"); | |
bc97fdd1 BA |
156 | if (kingCapture || !this.atLeastOnePawnPush(oppCol)) { |
157 | this.subTurn = (this.promotion ? 0 : 1); | |
158 | return true; | |
d6d0a46e | 159 | } |
bc97fdd1 BA |
160 | // A pawn push is possible: usual case |
161 | this.subTurn++; | |
162 | return false; | |
163 | }; | |
164 | if (incrementTurn()) { | |
165 | this.turn = oppCol; | |
166 | this.movesCount++; | |
d6d0a46e BA |
167 | } |
168 | } | |
169 | ||
3232aba3 | 170 | atLeastOneMove(color) { |
d6d0a46e BA |
171 | if (this.subTurn == 0) |
172 | return true; | |
173 | return super.atLeastOneMove(color); | |
174 | } | |
175 | ||
176 | }; |