export default class ConvertRules extends ChessRules {
- // TODO
static get Options() {
return {
select: C.Options.select,
- input: C.Options.input,
- styles: [
- "atomic", "cannibal", "capture", "cylinder",
- "dark", "madrasi", "rifle", "teleport"
- ]
+ styles: ["cylinder", "dark", "recycle", "teleport"]
};
}
setOtherVariables(fenParsed, pieceArray) {
super.setOtherVariables(fenParsed, pieceArray);
// Stack of "last move" only for intermediate chaining
- this.lastMoveEnd = [null];
+ this.lastMoveEnd = [];
}
genRandInitBaseFen() {
getBasicMove([sx, sy], [ex, ey], tr) {
const L = this.lastMoveEnd.length;
- const lm = this.lastMoveEnd[L-1];
- const piece = (!!lm ? lm.p : null);
- const c = this.turn;
+ const piece = (L >= 1 ? this.lastMoveEnd[L-1].p : null);
if (this.board[ex][ey] == "") {
if (piece && !tr)
- tr = {c: c, p: piece};
+ tr = {c: this.turn, p: piece};
let mv = super.getBasicMove([sx, sy], [ex, ey], tr);
if (piece)
- mv.vanish.pop();
+ mv.vanish.pop(); //end of a chain: initial piece remains
return mv;
}
// Capture: initial, or inside a chain
- const initPiece = (piece || this.getPiece(sx, sy));
- const oppCol = C.GetOppTurn(c);
- const oppPiece = this.getPiece(ex, ey);
+ const initPiece = (piece || this.getPiece(sx, sy)),
+ destPiece = this.getPiece(ex, ey);
let mv = new Move({
start: {x: sx, y: sy},
end: {x: ex, y: ey},
new PiPo({
x: ex,
y: ey,
- c: c,
+ c: this.turn,
p: (!!tr ? tr.p : initPiece)
})
],
new PiPo({
x: ex,
y: ey,
- c: oppCol,
- p: oppPiece
+ c: C.GetOppTurn(this.turn),
+ p: destPiece
})
]
});
new PiPo({
x: sx,
y: sy,
- c: c,
+ c: this.turn,
p: initPiece
})
);
}
+ mv.converted = destPiece; //easier (no need to detect it)
+// mv.drag = {c: this.turn, p: initPiece}; //TODO: doesn't work
return mv;
}
-// TODO from here
-
- getPotentialMovesFrom([x, y], asA) {
+ getPiece(x, y) {
const L = this.lastMoveEnd.length;
- if (!!this.lastMoveEnd[L-1]) {
- if (x != this.lastMoveEnd[L-1].x || y != this.lastMoveEnd[L-1].y)
- // A capture was played: wrong square
- return [];
- asA = this.lastMoveEnd[L-1].p;
- }
- switch (asA || this.getPiece(x, y)) {
- case V.PAWN: return super.getPotentialPawnMoves([x, y]);
- case V.ROOK: return super.getPotentialRookMoves([x, y]);
- case V.KNIGHT: return super.getPotentialKnightMoves([x, y]);
- case V.BISHOP: return super.getPotentialBishopMoves([x, y]);
- case V.QUEEN: return super.getPotentialQueenMoves([x, y]);
- case V.KING: return super.getPotentialKingMoves([x, y]);
- }
- return [];
+ if (L >= 1 && this.lastMoveEnd[L-1].x == x && this.lastMoveEnd[L-1].y == y)
+ return this.lastMoveEnd[L-1].p;
+ return super.getPiece(x, y);
}
- getPossibleMovesFrom(sq) {
+ getPotentialMovesFrom([x, y], color) {
const L = this.lastMoveEnd.length;
- let asA = undefined;
- if (!!this.lastMoveEnd[L-1]) {
- if (
- sq[0] != this.lastMoveEnd[L-1].x ||
- sq[1] != this.lastMoveEnd[L-1].y
- ) {
- return [];
- }
- asA = this.lastMoveEnd[L-1].p;
+ if (
+ L >= 1 &&
+ (x != this.lastMoveEnd[L-1].x || y != this.lastMoveEnd[L-1].y)
+ ) {
+ // A capture was played: wrong square
+ return [];
}
- return this.filterValid(this.getPotentialMovesFrom(sq, asA));
+ return super.getPotentialMovesFrom([x, y], color);
}
- isAttacked_aux([x, y], color, explored) {
+ underAttack_aux([x, y], color, explored) {
if (explored.some(sq => sq[0] == x && sq[1] == y))
// Start of an infinite loop: exit
return false;
explored.push([x, y]);
- if (super.isAttacked([x, y], color)) return true;
+ if (super.underAttack([x, y], [color]))
+ return true;
// Maybe indirect "chaining" attack:
- const myColor = this.turn
+ const myColor = this.turn;
let res = false;
let toCheck = []; //check all but king (no need)
// Pawns:
for (let yShift of [-1, 1]) {
const [i, j] = [x + shiftToPawn, y + yShift];
if (
- V.OnBoard(i, j) &&
- this.board[i][j] != V.EMPTY &&
+ this.onBoard(i, j) &&
+ this.board[i][j] != "" &&
// NOTE: no need to check color (no enemy pawn can take directly)
- this.getPiece(i, j) == V.PAWN
+ this.getPiece(i, j) == 'p'
) {
toCheck.push([i, j]);
}
}
// Knights:
- V.steps[V.KNIGHT].forEach(s => {
+ this.pieces()['n'].both[0].steps.forEach(s => {
const [i, j] = [x + s[0], y + s[1]];
if (
- V.OnBoard(i, j) &&
- this.board[i][j] != V.EMPTY &&
- this.getPiece(i, j) == V.KNIGHT
+ this.onBoard(i, j) &&
+ this.board[i][j] != "" &&
+ this.getPiece(i, j) == 'n'
) {
toCheck.push([i, j]);
}
});
// Sliders:
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]).forEach(s => {
+ this.pieces()['q'].both[0].steps.forEach(s => {
let [i, j] = [x + s[0], y + s[1]];
- while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+ while (this.onBoard(i, j) && this.board[i][j] == "") {
i += s[0];
j += s[1];
}
- if (!V.OnBoard(i, j)) return;
+ if (!this.onBoard(i, j))
+ return;
const piece = this.getPiece(i, j);
if (
- piece == V.QUEEN ||
- (piece == V.ROOK && (s[0] == 0 || s[1] == 0)) ||
- (piece == V.BISHOP && (s[0] != 0 && s[1] != 0))
+ piece == 'q' ||
+ (piece == 'r' && (s[0] == 0 || s[1] == 0)) ||
+ (piece == 'b' && (s[0] != 0 && s[1] != 0))
) {
toCheck.push([i, j]);
}
});
for (let ij of toCheck) {
- if (this.isAttacked_aux(ij, color, explored)) return true;
+ if (this.underAttack_aux(ij, color, explored))
+ return true;
}
return false;
}
- isAttacked([x, y], color) {
+ underAttack([x, y], [color]) {
let explored = [];
- return this.isAttacked_aux([x, y], color, explored);
+ return this.underAttack_aux([x, y], color, explored);
}
filterValid(moves) {
return moves;
}
- prePlay(move) {
- const c = this.turn;
- // Extra conditions to avoid tracking converted kings:
- if (
- move.appear[0].p == V.KING &&
- move.vanish.length >= 1 &&
- move.vanish[0].p == V.KING
- ) {
- this.kingPos[c][0] = move.appear[0].x;
- this.kingPos[c][1] = move.appear[0].y;
- }
+ isLastMove(move) {
+ return !move.converted;
}
- play(move) {
- this.prePlay(move);
- const c = this.turn;
- move.flags = JSON.stringify(this.aggregateFlags());
- V.PlayOnBoard(this.board, move);
- if (!move.end.converted) {
- // Not a capture: change turn
- this.turn = V.GetOppCol(this.turn);
- this.movesCount++;
- this.lastMoveEnd.push(null);
- }
- else {
- this.lastMoveEnd.push(
- Object.assign({}, move.end, { p: move.end.converted })
- );
+ postPlay(move) {
+ super.postPlay(move);
+ if (!!move.converted) {
+ this.lastMoveEnd.push({
+ x: move.end.x,
+ y: move.end.y,
+ p: move.converted
+ });
}
- super.updateCastleFlags(move, move.appear[0].p, c);
+ else
+ this.lastMoveEnd = [];
}
};