1 class ZenRules
extends ChessRules
3 // NOTE: enPassant, if enabled, would need to redefine carefully getEpSquare
9 // TODO: some duplicated code in 2 next functions
10 getSlideNJumpMoves(x
, y
, color
, steps
, oneStep
)
13 let [sizeX
,sizeY
] = VariantRules
.size
;
15 for (var loop
=0; loop
<steps
.length
; loop
++)
17 var step
= steps
[loop
];
20 while (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
21 && this.board
[i
][j
] == VariantRules
.EMPTY
)
23 moves
.push(this.getBasicMove(x
, y
, i
, j
));
24 if (oneStep
!== undefined)
29 // No capture check: handled elsewhere (next method)
34 // follow steps from x,y until something is met.
35 // if met piece is opponent and same movement (asA): eat it!
36 findCaptures_aux(x
, y
, color
, asA
)
40 var steps
= asA
!= V
.PAWN
42 : color
=='w' ? [[-1,-1],[-1,1]] : [[1,-1],[1,1]];
43 var oneStep
= (asA
==V
.KNIGHT
|| asA
==V
.PAWN
); //we don't capture king
44 let [sizeX
,sizeY
] = V
.size
;
45 let lastRank
= (color
== 'w' ? 0 : sizeY
-1);
46 let promotionPieces
= [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
48 for (var loop
=0; loop
<steps
.length
; loop
++)
50 var step
= steps
[loop
];
53 while (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
54 && this.board
[i
][j
] == V
.EMPTY
)
61 if (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
&&
62 this.getColor(i
,j
) == this.getOppCol(color
) && this.getPiece(i
,j
) == asA
)
65 if (this.getPiece(x
,y
) == V
.PAWN
&& i
== lastRank
)
67 // Special case of promotion:
68 promotionPieces
.forEach(p
=> {
69 moves
.push(this.getBasicMove(x
, y
, i
, j
, p
));
75 moves
.push(this.getBasicMove(x
, y
, i
, j
));
82 // Find possible captures from a square: look in every direction!
83 findCaptures(x
, y
, color
)
88 Array
.prototype.push
.apply(moves
,
89 this.findCaptures_aux(x
, y
, color
, VariantRules
.PAWN
));
92 Array
.prototype.push
.apply(moves
,
93 this.findCaptures_aux(x
, y
, color
, VariantRules
.ROOK
));
96 Array
.prototype.push
.apply(moves
,
97 this.findCaptures_aux(x
, y
, color
, VariantRules
.KNIGHT
));
100 Array
.prototype.push
.apply(moves
,
101 this.findCaptures_aux(x
, y
, color
, VariantRules
.BISHOP
));
104 Array
.prototype.push
.apply(moves
,
105 this.findCaptures_aux(x
, y
, color
, VariantRules
.QUEEN
));
110 getPotentialPawnMoves(x
, y
, color
)
113 var V
= VariantRules
;
114 let [sizeX
,sizeY
] = VariantRules
.size
;
115 let shift
= (color
== 'w' ? -1 : 1);
116 let startRank
= (color
== 'w' ? sizeY
-2 : 1);
117 let firstRank
= (color
== 'w' ? sizeY
-1 : 0);
118 let lastRank
= (color
== "w" ? 0 : sizeY
-1);
120 if (x
+shift
>= 0 && x
+shift
< sizeX
&& x
+shift
!= lastRank
)
123 if (this.board
[x
+shift
][y
] == V
.EMPTY
)
125 moves
.push(this.getBasicMove(x
, y
, x
+shift
, y
));
126 if ([startRank
,firstRank
].includes(x
) && this.board
[x
+2*shift
][y
] == V
.EMPTY
)
129 moves
.push(this.getBasicMove(x
, y
, x
+2*shift
, y
));
134 if (x
+shift
== lastRank
)
137 let promotionPieces
= [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
138 promotionPieces
.forEach(p
=> {
140 if (this.board
[x
+shift
][y
] == V
.EMPTY
)
141 moves
.push(this.getBasicMove(x
, y
, x
+shift
, y
, p
));
145 // No en passant here
147 // Add "zen" captures
148 Array
.prototype.push
.apply(moves
, this.findCaptures(x
, y
, color
));
153 getPotentialRookMoves(x
, y
, color
)
155 let noCaptures
= this.getSlideNJumpMoves(
156 x
, y
, color
, VariantRules
.steps
[VariantRules
.ROOK
]);
157 let captures
= this.findCaptures(x
, y
, color
);
158 return noCaptures
.concat(captures
);
161 getPotentialKnightMoves(x
, y
, color
)
163 let noCaptures
= this.getSlideNJumpMoves(
164 x
, y
, color
, VariantRules
.steps
[VariantRules
.KNIGHT
], "oneStep");
165 let captures
= this.findCaptures(x
, y
, color
);
166 return noCaptures
.concat(captures
);
169 getPotentialBishopMoves(x
, y
, color
)
171 let noCaptures
= this.getSlideNJumpMoves(
172 x
, y
, color
, VariantRules
.steps
[VariantRules
.BISHOP
]);
173 let captures
= this.findCaptures(x
, y
, color
);
174 return noCaptures
.concat(captures
);
177 getPotentialQueenMoves(x
, y
, color
)
179 let noCaptures
= this.getSlideNJumpMoves(
180 x
, y
, color
, VariantRules
.steps
[VariantRules
.QUEEN
]);
181 let captures
= this.findCaptures(x
, y
, color
);
182 return noCaptures
.concat(captures
);
185 getPotentialKingMoves(x
, y
, c
)
187 // Initialize with normal moves
188 let noCaptures
= this.getSlideNJumpMoves(
189 x
, y
, c
, VariantRules
.steps
[VariantRules
.QUEEN
], "oneStep");
190 let captures
= this.findCaptures(x
, y
, c
);
192 let moves
= noCaptures
194 .concat(this.getCastleMoves(x
, y
, c
));
201 // Recognize special moves first
202 if (move.appear
.length
== 2)
205 if (move.end
.y
< move.start
.y
)
211 // Translate initial square (because pieces may fly unusually in this variant!)
213 String
.fromCharCode(97 + move.start
.y
) + (VariantRules
.size
[0]-move.start
.x
);
215 // Translate final square
217 String
.fromCharCode(97 + move.end
.y
) + (VariantRules
.size
[0]-move.end
.x
);
220 let piece
= this.getPiece(move.start
.x
, move.start
.y
);
221 if (piece
== VariantRules
.PAWN
)
223 // pawn move (TODO: enPassant indication)
224 if (move.vanish
.length
> 1)
227 notation
= initialSquare
+ "x" + finalSquare
;
230 notation
= finalSquare
;
231 if (piece
!= move.appear
[0].p
) //promotion
232 notation
+= "=" + move.appear
[0].p
.toUpperCase();
238 notation
= piece
.toUpperCase();
239 if (move.vanish
.length
> 1)
240 notation
+= initialSquare
+ "x";
241 notation
+= finalSquare
;
246 static get VALUES() { //TODO: experimental