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
], steps
, oneStep
)
12 const color
= this.getColor(x
,y
);
14 let [sizeX
,sizeY
] = VariantRules
.size
;
16 for (var loop
=0; loop
<steps
.length
; loop
++)
18 var step
= steps
[loop
];
21 while (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
22 && this.board
[i
][j
] == VariantRules
.EMPTY
)
24 moves
.push(this.getBasicMove([x
,y
], [i
,j
]));
30 // No capture check: handled elsewhere (next method)
35 // follow steps from x,y until something is met.
36 // if met piece is opponent and same movement (asA): eat it!
37 findCaptures_aux([x
,y
], asA
)
39 const color
= this.getColor(x
,y
);
42 var steps
= asA
!= V
.PAWN
44 : color
=='w' ? [[-1,-1],[-1,1]] : [[1,-1],[1,1]];
45 var oneStep
= (asA
==V
.KNIGHT
|| asA
==V
.PAWN
); //we don't capture king
46 let [sizeX
,sizeY
] = V
.size
;
47 let lastRank
= (color
== 'w' ? 0 : sizeY
-1);
48 let promotionPieces
= [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
50 for (var loop
=0; loop
<steps
.length
; loop
++)
52 var step
= steps
[loop
];
55 while (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
56 && this.board
[i
][j
] == V
.EMPTY
)
63 if (i
>=0 && i
<sizeX
&& j
>=0 && j
<sizeY
&&
64 this.getColor(i
,j
) == this.getOppCol(color
) && this.getPiece(i
,j
) == asA
)
67 if (this.getPiece(x
,y
) == V
.PAWN
&& i
== lastRank
)
69 // Special case of promotion:
70 promotionPieces
.forEach(p
=> {
71 moves
.push(this.getBasicMove([x
,y
], [i
,j
], {c:color
,p:p
}));
77 moves
.push(this.getBasicMove([x
,y
], [i
,j
]));
84 // Find possible captures from a square: look in every direction!
90 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, VariantRules
.PAWN
));
93 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, VariantRules
.ROOK
));
96 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, VariantRules
.KNIGHT
));
99 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, VariantRules
.BISHOP
));
102 Array
.prototype.push
.apply(moves
, this.findCaptures_aux(sq
, VariantRules
.QUEEN
));
107 getPotentialPawnMoves([x
,y
])
109 const color
= this.getColor(x
,y
);
111 var V
= VariantRules
;
112 let [sizeX
,sizeY
] = VariantRules
.size
;
113 let shift
= (color
== 'w' ? -1 : 1);
114 let startRank
= (color
== 'w' ? sizeY
-2 : 1);
115 let firstRank
= (color
== 'w' ? sizeY
-1 : 0);
116 let lastRank
= (color
== "w" ? 0 : sizeY
-1);
118 if (x
+shift
>= 0 && x
+shift
< sizeX
&& x
+shift
!= lastRank
)
121 if (this.board
[x
+shift
][y
] == V
.EMPTY
)
123 moves
.push(this.getBasicMove([x
,y
], [x
+shift
,y
]));
124 if ([startRank
,firstRank
].includes(x
) && this.board
[x
+2*shift
][y
] == V
.EMPTY
)
127 moves
.push(this.getBasicMove([x
,y
], [x
+2*shift
,y
]));
132 if (x
+shift
== lastRank
)
135 let promotionPieces
= [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
136 promotionPieces
.forEach(p
=> {
138 if (this.board
[x
+shift
][y
] == V
.EMPTY
)
139 moves
.push(this.getBasicMove([x
,y
], [x
+shift
,y
], {c:color
,p:p
}));
143 // No en passant here
145 // Add "zen" captures
146 Array
.prototype.push
.apply(moves
, this.findCaptures([x
,y
]));
151 getPotentialRookMoves(sq
)
153 let noCaptures
= this.getSlideNJumpMoves(sq
, VariantRules
.steps
[VariantRules
.ROOK
]);
154 let captures
= this.findCaptures(sq
);
155 return noCaptures
.concat(captures
);
158 getPotentialKnightMoves(sq
)
160 let noCaptures
= this.getSlideNJumpMoves(sq
, VariantRules
.steps
[VariantRules
.KNIGHT
], "oneStep");
161 let captures
= this.findCaptures(sq
);
162 return noCaptures
.concat(captures
);
165 getPotentialBishopMoves(sq
)
167 let noCaptures
= this.getSlideNJumpMoves(sq
, VariantRules
.steps
[VariantRules
.BISHOP
]);
168 let captures
= this.findCaptures(sq
);
169 return noCaptures
.concat(captures
);
172 getPotentialQueenMoves(sq
)
174 let noCaptures
= this.getSlideNJumpMoves(sq
, VariantRules
.steps
[VariantRules
.QUEEN
]);
175 let captures
= this.findCaptures(sq
);
176 return noCaptures
.concat(captures
);
179 getPotentialKingMoves(sq
)
181 // Initialize with normal moves
182 let noCaptures
= this.getSlideNJumpMoves(sq
, VariantRules
.steps
[VariantRules
.QUEEN
], "oneStep");
183 let captures
= this.findCaptures(sq
);
184 return noCaptures
.concat(captures
).concat(this.getCastleMoves(sq
));
189 // Recognize special moves first
190 if (move.appear
.length
== 2)
193 if (move.end
.y
< move.start
.y
)
199 // Translate initial square (because pieces may fly unusually in this variant!)
201 String
.fromCharCode(97 + move.start
.y
) + (VariantRules
.size
[0]-move.start
.x
);
203 // Translate final square
205 String
.fromCharCode(97 + move.end
.y
) + (VariantRules
.size
[0]-move.end
.x
);
208 let piece
= this.getPiece(move.start
.x
, move.start
.y
);
209 if (piece
== VariantRules
.PAWN
)
211 // pawn move (TODO: enPassant indication)
212 if (move.vanish
.length
> 1)
215 notation
= initialSquare
+ "x" + finalSquare
;
218 notation
= finalSquare
;
219 if (piece
!= move.appear
[0].p
) //promotion
220 notation
+= "=" + move.appear
[0].p
.toUpperCase();
226 notation
= piece
.toUpperCase();
227 if (move.vanish
.length
> 1)
228 notation
+= initialSquare
+ "x";
229 notation
+= finalSquare
;
234 static get VALUES() { //TODO: experimental