{
captureTarget: [x, y],
captureSteps: [{steps: [s], range: a.range}],
- segments: o.segments,
- attackOnly: true,
- one: false //one and captureTarget are mutually exclusive
+ segments: o.segments
},
allowed
);
oppCols.includes(this.getColor(x, this.epSquare.y))
) {
const [epx, epy] = [this.epSquare.x, this.epSquare.y];
- this.board[epx][epy] = this.board[x][this.epSquares.y];
+ this.board[epx][epy] = this.board[x][this.epSquare.y];
let enpassantMove = this.getBasicMove([x, y], [epx, epy]);
this.board[epx][epy] = "";
const lastIdx = enpassantMove.vanish.length - 1; //think Rifle
color = this.turn;
const oppCols = this.getOppCols(color);
let kingPos = this.searchKingPos(color);
- let filtered = {}; //avoid re-checking similar moves (promotions...)
return moves.filter(m => {
- const key = m.start.x + m.start.y + '.' + m.end.x + m.end.y;
- if (!filtered[key]) {
- this.playOnBoard(m);
- let newKingPP = null,
- sqIdx = 0,
- res = true; //a priori valid
- const oldKingPP =
- m.vanish.find(v => this.isKing(0, 0, v.p) && v.c == color);
- if (oldKingPP) {
- // Search king in appear array:
- newKingPP =
- m.appear.find(a => this.isKing(0, 0, a.p) && a.c == color);
- if (newKingPP) {
- sqIdx = kingPos.findIndex(kp =>
- kp[0] == oldKingPP.x && kp[1] == oldKingPP.y);
- kingPos[sqIdx] = [newKingPP.x, newKingPP.y];
- }
- else
- res = false; //king vanished
+ this.playOnBoard(m);
+ let newKingPP = null,
+ sqIdx = 0,
+ res = true; //a priori valid
+ const oldKingPP =
+ m.vanish.find(v => this.isKing(0, 0, v.p) && v.c == color);
+ if (oldKingPP) {
+ // Search king in appear array:
+ newKingPP =
+ m.appear.find(a => this.isKing(0, 0, a.p) && a.c == color);
+ if (newKingPP) {
+ sqIdx = kingPos.findIndex(kp =>
+ kp[0] == oldKingPP.x && kp[1] == oldKingPP.y);
+ kingPos[sqIdx] = [newKingPP.x, newKingPP.y];
}
- res &&= !this.underCheck(kingPos, oppCols);
- if (oldKingPP && newKingPP)
- kingPos[sqIdx] = [oldKingPP.x, oldKingPP.y];
- this.undoOnBoard(m);
- filtered[key] = res;
- return res;
+ else
+ res = false; //king vanished
}
- return filtered[key];
+ res &&= !this.underCheck(kingPos, oppCols);
+ if (oldKingPP && newKingPP)
+ kingPos[sqIdx] = [oldKingPP.x, oldKingPP.y];
+ this.undoOnBoard(m);
+ return res;
});
}
if (kingPos[this.turn].length == 0 && kingPos[oppTurn].length == 0)
return "1/2";
if (kingPos[this.turn].length == 0)
- return (color == "w" ? "0-1" : "1-0");
+ return (this.turn == "w" ? "0-1" : "1-0");
if (kingPos[oppTurn].length == 0)
- return (color == "w" ? "1-0" : "0-1");
+ return (this.turn == "w" ? "1-0" : "0-1");
if (this.atLeastOneMove(this.turn))
return "*";
// No valid move: stalemate or checkmate?
return C.GetColorClass(c);
}
- static board2fen(b) {
+ board2fen(b) {
const checkered_codes = {
p: "s",
q: "t",
return super.board2fen(b);
}
- static fen2board(f) {
+ fen2board(f) {
// Tolerate upper-case versions of checkered pieces (why not?)
const checkered_pieces = {
s: "p",
pieces(color, x, y) {
let baseRes = super.pieces(color, x, y);
- if (
- this.getPiece(x, y) == 'p' &&
- this.stage == 2 &&
- this.getColor(x, y) == 'c'
- ) {
+ if (this.getPiece(x, y) == 'p' && color == 'c') {
+ const pawnShift = this.getPawnShift(this.turn); //cannot trust color
+ const initRank = (
+ (this.stage == 2 && [1, 6].includes(x)) ||
+ (this.stage == 1 &&
+ ((x == 1 && this.turn == 'b') || (x == 6 && this.turn == 'w'))
+ )
+ );
// Checkered pawns on stage 2 are bidirectional
- const initRank = ((color == 'w' && x >= 6) || (color == 'b' && x <= 1));
+ let moveSteps = [[pawnShift, 0]],
+ attackSteps = [[pawnShift, 1], [pawnShift, -1]];
+ if (this.stage == 2) {
+ moveSteps.push([-pawnShift, 0]);
+ Array.prototype.push.apply(attackSteps,
+ [[-pawnShift, 1], [-pawnShift, -1]]);
+ }
baseRes['p'] = {
"class": "pawn",
moves: [
{
- steps: [[1, 0], [-1, 0]],
+ steps: moveSteps,
range: (initRank ? 2 : 1)
}
],
attack: [
{
- steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]],
+ steps: attackSteps,
range: 1
}
]
// Must consider both kings (attacked by checkered side)
kingPos = [kingPos, super.searchKingPos(C.GetOppTurn(this.turn))];
const oppCols = this.getOppCols(color);
- return moves.filter(m => {
+ // Artificial turn change required, because canTake uses turn info.
+ // canTake is called from underCheck --> ... --> findDestSquares
+ this.turn = C.GetOppTurn(this.turn);
+ const filteredMoves = moves.filter(m => {
this.playOnBoard(m);
+ if (m.vanish[0].p == 'k')
+ kingPos[0] = [m.appear[0].x, m.appear[0].y];
let res = true;
if (this.stage == 1)
res = !this.oppositeMoves(this.cmove, m);
if (res && m.appear.length > 0)
res = !this.underCheck(kingPos, oppCols);
+ if (m.vanish[0].p == 'k')
+ kingPos[0] = [m.vanish[0].x, m.vanish[0].y];
this.undoOnBoard(m);
return res;
});
+ this.turn = C.GetOppTurn(this.turn);
+ return filteredMoves;
}
atLeastOneMove(color) {