Bugs fixing, finalization of rules in french+english
[vchess.git] / public / javascripts / variants / Zen.js
CommitLineData
1d184b4c
BA
1class ZenRules extends ChessRules
2{
33ee1916 3 // NOTE: enPassant, if enabled, would need to redefine carefully getEpSquare
fb6ceeff 4 static get HasEnpassant() { return false; }
33ee1916 5
92342261 6 // TODO(?): some duplicated code in 2 next functions
46302e64 7 getSlideNJumpMoves([x,y], steps, oneStep)
1d184b4c 8 {
46302e64 9 const color = this.getColor(x,y);
1221ac47 10 let moves = [];
1d184b4c 11 outerLoop:
1221ac47 12 for (let loop=0; loop<steps.length; loop++)
1d184b4c 13 {
1221ac47
BA
14 const step = steps[loop];
15 let i = x + step[0];
16 let j = y + step[1];
0b7d99ec 17 while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
1d184b4c 18 {
46302e64
BA
19 moves.push(this.getBasicMove([x,y], [i,j]));
20 if (!!oneStep)
1d184b4c
BA
21 continue outerLoop;
22 i += step[0];
23 j += step[1];
24 }
25 // No capture check: handled elsewhere (next method)
26 }
27 return moves;
28 }
29
30 // follow steps from x,y until something is met.
31 // if met piece is opponent and same movement (asA): eat it!
46302e64 32 findCaptures_aux([x,y], asA)
1d184b4c 33 {
46302e64 34 const color = this.getColor(x,y);
1d184b4c 35 var moves = [];
1221ac47
BA
36 const steps = asA != V.PAWN
37 ? (asA==V.QUEEN ? V.steps[V.ROOK].concat(V.steps[V.BISHOP]) : V.steps[asA])
1d184b4c 38 : color=='w' ? [[-1,-1],[-1,1]] : [[1,-1],[1,1]];
1221ac47 39 const oneStep = (asA==V.KNIGHT || asA==V.PAWN); //we don't capture king
0b7d99ec 40 const lastRank = (color == 'w' ? 0 : V.size.x-1);
1221ac47 41 const promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
1d184b4c 42 outerLoop:
1221ac47 43 for (let loop=0; loop<steps.length; loop++)
1d184b4c 44 {
1221ac47
BA
45 const step = steps[loop];
46 let i = x + step[0];
47 let j = y + step[1];
0b7d99ec 48 while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
1d184b4c
BA
49 {
50 if (oneStep)
51 continue outerLoop;
52 i += step[0];
53 j += step[1];
54 }
0b7d99ec
BA
55 if (V.OnBoard(i,j) && this.getColor(i,j) == this.getOppCol(color)
56 && this.getPiece(i,j) == asA)
1d184b4c
BA
57 {
58 // eat!
59 if (this.getPiece(x,y) == V.PAWN && i == lastRank)
60 {
61 // Special case of promotion:
62 promotionPieces.forEach(p => {
46302e64 63 moves.push(this.getBasicMove([x,y], [i,j], {c:color,p:p}));
1d184b4c
BA
64 });
65 }
66 else
67 {
68 // All other cases
46302e64 69 moves.push(this.getBasicMove([x,y], [i,j]));
1d184b4c
BA
70 }
71 }
72 }
73 return moves;
74 }
75
76 // Find possible captures from a square: look in every direction!
46302e64 77 findCaptures(sq)
1d184b4c 78 {
92342261 79 let moves = [];
1d184b4c 80
0b7d99ec
BA
81 Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.PAWN));
82 Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.ROOK));
83 Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.KNIGHT));
84 Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.BISHOP));
85 Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.QUEEN));
1d184b4c
BA
86
87 return moves;
88 }
89
46302e64 90 getPotentialPawnMoves([x,y])
1d184b4c 91 {
46302e64 92 const color = this.getColor(x,y);
0b7d99ec
BA
93 let moves = [];
94 const [sizeX,sizeY] = [V.size.x,V.size.y];
95 const shift = (color == 'w' ? -1 : 1);
96 const startRank = (color == 'w' ? sizeY-2 : 1);
97 const firstRank = (color == 'w' ? sizeY-1 : 0);
98 const lastRank = (color == "w" ? 0 : sizeY-1);
1d184b4c 99
69f3d801 100 if (x+shift != lastRank)
1d184b4c
BA
101 {
102 // Normal moves
103 if (this.board[x+shift][y] == V.EMPTY)
104 {
46302e64 105 moves.push(this.getBasicMove([x,y], [x+shift,y]));
01ca2adc 106 if ([startRank,firstRank].includes(x) && this.board[x+2*shift][y] == V.EMPTY)
1d184b4c
BA
107 {
108 //two squares jump
46302e64 109 moves.push(this.getBasicMove([x,y], [x+2*shift,y]));
1d184b4c
BA
110 }
111 }
112 }
113
69f3d801 114 else //promotion
1d184b4c 115 {
1d184b4c
BA
116 let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
117 promotionPieces.forEach(p => {
118 // Normal move
119 if (this.board[x+shift][y] == V.EMPTY)
46302e64 120 moves.push(this.getBasicMove([x,y], [x+shift,y], {c:color,p:p}));
1d184b4c
BA
121 });
122 }
123
33ee1916 124 // No en passant here
1d184b4c
BA
125
126 // Add "zen" captures
46302e64 127 Array.prototype.push.apply(moves, this.findCaptures([x,y]));
1d184b4c
BA
128
129 return moves;
130 }
131
46302e64 132 getPotentialRookMoves(sq)
1d184b4c 133 {
0b7d99ec 134 let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.ROOK]);
46302e64 135 let captures = this.findCaptures(sq);
1d184b4c
BA
136 return noCaptures.concat(captures);
137 }
138
46302e64 139 getPotentialKnightMoves(sq)
1d184b4c 140 {
0b7d99ec 141 let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep");
46302e64 142 let captures = this.findCaptures(sq);
1d184b4c
BA
143 return noCaptures.concat(captures);
144 }
145
46302e64 146 getPotentialBishopMoves(sq)
1d184b4c 147 {
0b7d99ec 148 let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]);
46302e64 149 let captures = this.findCaptures(sq);
1d184b4c
BA
150 return noCaptures.concat(captures);
151 }
152
46302e64 153 getPotentialQueenMoves(sq)
1d184b4c 154 {
92342261
BA
155 let noCaptures = this.getSlideNJumpMoves(
156 sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]));
46302e64 157 let captures = this.findCaptures(sq);
1d184b4c
BA
158 return noCaptures.concat(captures);
159 }
160
46302e64 161 getPotentialKingMoves(sq)
1d184b4c
BA
162 {
163 // Initialize with normal moves
a37076f1
BA
164 let noCaptures = this.getSlideNJumpMoves(sq,
165 V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
46302e64
BA
166 let captures = this.findCaptures(sq);
167 return noCaptures.concat(captures).concat(this.getCastleMoves(sq));
1d184b4c
BA
168 }
169
170 getNotation(move)
171 {
172 // Recognize special moves first
173 if (move.appear.length == 2)
174 {
175 // castle
176 if (move.end.y < move.start.y)
177 return "0-0-0";
178 else
179 return "0-0";
180 }
181
182 // Translate initial square (because pieces may fly unusually in this variant!)
2d7194bd 183 const initialSquare = V.CoordsToSquare(move.start);
1d184b4c
BA
184
185 // Translate final square
2d7194bd 186 const finalSquare = V.CoordsToSquare(move.end);
1d184b4c
BA
187
188 let notation = "";
15c1295a 189 const piece = this.getPiece(move.start.x, move.start.y);
0b7d99ec 190 if (piece == V.PAWN)
1d184b4c
BA
191 {
192 // pawn move (TODO: enPassant indication)
193 if (move.vanish.length > 1)
194 {
195 // capture
196 notation = initialSquare + "x" + finalSquare;
197 }
198 else //no capture
199 notation = finalSquare;
200 if (piece != move.appear[0].p) //promotion
201 notation += "=" + move.appear[0].p.toUpperCase();
202 }
203
204 else
205 {
206 // Piece movement
207 notation = piece.toUpperCase();
208 if (move.vanish.length > 1)
209 notation += initialSquare + "x";
210 notation += finalSquare;
211 }
212 return notation;
213 }
214
2d7194bd
BA
215 static get VALUES()
216 {
217 // TODO: experimental
1d184b4c
BA
218 return {
219 'p': 1,
220 'r': 3,
221 'n': 2,
222 'b': 2,
223 'q': 5,
224 'k': 1000
225 }
226 }
227}
643479f8
BA
228
229const VariantRules = ZenRules;