Fixed Checkered variant
[xogo.git] / variants / Avalanche / class.js
1 import ChessRules from "/base_rules.js";
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,
10 styles: [
11 "atomic",
12 "cannibal",
13 "capture",
14 "crazyhouse",
15 "cylinder",
16 "dark",
17 "madrasi",
18 "recycle",
19 "rifle",
20 "teleport",
21 "zen"
22 ]
23 };
24 }
25
26 get hasEnpassant() {
27 return false;
28 }
29
30 getPartFen(o) {
31 return Object.assign(
32 {promotion: o.init ? false : this.promotion},
33 super.getPartFen(o)
34 );
35 }
36
37 setOtherVariables(fenParsed) {
38 super.setOtherVariables(fenParsed);
39 this.promotion = (fenParsed.promotion == '1');
40 this.subTurn = 1 - (this.promotion ? 1 : 0);
41 }
42
43 doClick(coords) {
44 const myLastRank = (this.turn == 'w' ? 0 : this.size.x - 1);
45 if (
46 this.subTurn != 0 ||
47 coords.x != myLastRank ||
48 this.getPiece(coords.x, coords.y) != 'p'
49 ) {
50 return null;
51 }
52 let moves = [];
53 this.pawnPromotions.forEach(pr => {
54 moves.push(
55 new Move({
56 vanish: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: 'p'})],
57 appear: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: pr})]
58 })
59 );
60 });
61 super.showChoices(moves);
62 }
63
64 canIplay(x, y) {
65 const pieceColor = this.getColor(x, y);
66 return (
67 this.playerColor == this.turn &&
68 (
69 (this.subTurn <= 1 && pieceColor == this.playerColor) ||
70 (
71 this.subTurn == 2 &&
72 pieceColor != this.playerColor &&
73 this.getPiece(x, y) == 'p'
74 )
75 )
76 );
77 }
78
79 getPotentialMovesFrom([x, y]) {
80 if (this.subTurn == 0)
81 return [];
82 if (this.subTurn == 1)
83 // Usual case:
84 return super.getPotentialMovesFrom([x, y]);
85 // subTurn == 2: only allowed to push an opponent's pawn (if possible)
86 const oppPawnShift = (this.turn == 'w' ? 1 : -1);
87 if (
88 this.onBoard(x + oppPawnShift, y) &&
89 this.board[x + oppPawnShift][y] == ""
90 ) {
91 return [this.getBasicMove([x, y], [x + oppPawnShift, y])];
92 }
93 return [];
94 }
95
96 filterValid(moves) {
97 if (this.subTurn != 1)
98 return moves; //self-checks by pawns are allowed
99 return super.filterValid(moves);
100 }
101
102 atLeastOnePawnPush(color) {
103 const pawnShift = (color == 'w' ? -1 : 1);
104 for (let i = 0; i < 8; i++) {
105 for (let j = 0; j < 8; j++) {
106 if (
107 this.board[i][j] != "" &&
108 this.getColor(i, j) == color &&
109 this.getPiece(i, j) == 'p' &&
110 this.board[i + pawnShift][j] == ""
111 ) {
112 return true;
113 }
114 }
115 }
116 return false;
117 }
118
119 postPlay(move) {
120 const color = this.turn;
121 const oppCol = C.GetOppTurn(color);
122 this.promotion = (
123 this.subTurn == 2 &&
124 move.end.x == (oppCol == 'w' ? 0 : this.size.x - 1) &&
125 move.vanish[0].p == 'p'
126 );
127 if (this.subTurn == 0) {
128 this.subTurn++;
129 if (!this.atLeastOneMove(color)) {
130 move.result = "1/2"; //avoid re-computation
131 this.turn = oppCol;
132 }
133 }
134 else if (this.subTurn == 2) {
135 this.turn = oppCol;
136 this.subTurn = this.promotion ? 0 : 1;
137 }
138 else { //subTurn == 1, usual case
139 const kingCapture = this.searchKingPos(oppCol).length == 0;
140 if (kingCapture)
141 move.result = (color == 'w' ? "1-0" : "0-1");
142 if (!kingCapture && this.atLeastOnePawnPush(oppCol))
143 this.subTurn++;
144 else {
145 this.turn = oppCol;
146 this.subTurn = this.promotion ? 0 : 1;
147 }
148 }
149 }
150
151 atLeastOneMove(color, lastMove) {
152 if (this.subTurn == 0)
153 return true;
154 return super.atLeastOneMove(color);
155 }
156
157 };