6a568db926c5ca2617d61c8070ead4b97b3160b8
1 class ZenRules
extends ChessRules
3 // NOTE: enPassant, if enabled, would need to redefine carefully getEpSquare
4 static get HasEnpassant() { return false; }
6 // TODO(?): some duplicated code in 2 next functions
7 getSlideNJumpMoves([x
,y
], steps
, oneStep
)
9 const color
= this.getColor(x
,y
);
12 for (let loop
=0; loop
<steps
.length
; loop
++)
14 const step
= steps
[loop
];
17 while (V
.OnBoard(i
,j
) && this.board
[i
][j
] == V
.EMPTY
)
19 moves
.push(this.getBasicMove([x
,y
], [i
,j
]));
25 // No capture check: handled elsewhere (next method)
30 // follow steps from x,y until something is met.
31 // if met piece is opponent and same movement (asA): eat it!
32 findCaptures_aux([x
,y
], asA
)
34 const color
= this.getColor(x
,y
);
36 const steps
= asA
!= V
.PAWN
37 ? (asA
==V
.QUEEN
? V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]) : V
.steps
[asA
])
38 : color
=='w' ? [[-1,-1],[-1,1]] : [[1,-1],[1,1]];
39 const oneStep
= (asA
==V
.KNIGHT
|| asA
==V
.PAWN
); //we don't capture king
40 const lastRank
= (color
== 'w' ? 0 : V
.size
.x
-1);
41 const promotionPieces
= [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
43 for (let loop
=0; loop
<steps
.length
; loop
++)
45 const step
= steps
[loop
];
48 while (V
.OnBoard(i
,j
) && this.board
[i
][j
] == V
.EMPTY
)
55 if (V
.OnBoard(i
,j
) && this.getColor(i
,j
) == V
.GetOppCol(color
)
56 && this.getPiece(i
,j
) == asA
)
59 if (this.getPiece(x
,y
) == V
.PAWN
&& i
== lastRank
)
61 // Special case of promotion:
62 promotionPieces
.forEach(p
=> {
63 moves
.push(this.getBasicMove([x
,y
], [i
,j
], {c:color
,p:p
}));
69 moves
.push(this.getBasicMove([x
,y
], [i
,j
]));
76 // Find possible captures from a square: look in every direction!
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
));
90 getPotentialPawnMoves([x
,y
])
92 const color
= this.getColor(x
,y
);
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);
100 if (x
+shift
!= lastRank
)
103 if (this.board
[x
+shift
][y
] == V
.EMPTY
)
105 moves
.push(this.getBasicMove([x
,y
], [x
+shift
,y
]));
106 if ([startRank
,firstRank
].includes(x
) && this.board
[x
+2*shift
][y
] == V
.EMPTY
)
109 moves
.push(this.getBasicMove([x
,y
], [x
+2*shift
,y
]));
116 let promotionPieces
= [V
.ROOK
,V
.KNIGHT
,V
.BISHOP
,V
.QUEEN
];
117 promotionPieces
.forEach(p
=> {
119 if (this.board
[x
+shift
][y
] == V
.EMPTY
)
120 moves
.push(this.getBasicMove([x
,y
], [x
+shift
,y
], {c:color
,p:p
}));
124 // No en passant here
126 // Add "zen" captures
127 Array
.prototype.push
.apply(moves
, this.findCaptures([x
,y
]));
132 getPotentialRookMoves(sq
)
134 let noCaptures
= this.getSlideNJumpMoves(sq
, V
.steps
[V
.ROOK
]);
135 let captures
= this.findCaptures(sq
);
136 return noCaptures
.concat(captures
);
139 getPotentialKnightMoves(sq
)
141 let noCaptures
= this.getSlideNJumpMoves(sq
, V
.steps
[V
.KNIGHT
], "oneStep");
142 let captures
= this.findCaptures(sq
);
143 return noCaptures
.concat(captures
);
146 getPotentialBishopMoves(sq
)
148 let noCaptures
= this.getSlideNJumpMoves(sq
, V
.steps
[V
.BISHOP
]);
149 let captures
= this.findCaptures(sq
);
150 return noCaptures
.concat(captures
);
153 getPotentialQueenMoves(sq
)
155 let noCaptures
= this.getSlideNJumpMoves(
156 sq
, V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]));
157 let captures
= this.findCaptures(sq
);
158 return noCaptures
.concat(captures
);
161 getPotentialKingMoves(sq
)
163 // Initialize with normal moves
164 let noCaptures
= this.getSlideNJumpMoves(sq
,
165 V
.steps
[V
.ROOK
].concat(V
.steps
[V
.BISHOP
]), "oneStep");
166 let captures
= this.findCaptures(sq
);
167 return noCaptures
.concat(captures
).concat(this.getCastleMoves(sq
));
172 // Recognize special moves first
173 if (move.appear
.length
== 2)
176 if (move.end
.y
< move.start
.y
)
182 // Translate initial square (because pieces may fly unusually in this variant!)
183 const initialSquare
= V
.CoordsToSquare(move.start
);
185 // Translate final square
186 const finalSquare
= V
.CoordsToSquare(move.end
);
189 const piece
= this.getPiece(move.start
.x
, move.start
.y
);
192 // pawn move (TODO: enPassant indication)
193 if (move.vanish
.length
> 1)
196 notation
= initialSquare
+ "x" + finalSquare
;
199 notation
= finalSquare
;
200 if (piece
!= move.appear
[0].p
) //promotion
201 notation
+= "=" + move.appear
[0].p
.toUpperCase();
207 notation
= piece
.toUpperCase();
208 if (move.vanish
.length
> 1)
209 notation
+= initialSquare
+ "x";
210 notation
+= finalSquare
;
217 // TODO: experimental