import { ChessRules, Move, PiPo } from "@/base_rules";
export class DynamoRules extends ChessRules {
- // TODO: later, allow to push out pawns on a and h files?
+ // TODO: later, allow to push out pawns on a and h files
static get HasEnpassant() {
return false;
}
// Local stack of "action moves"
this.amoves = [];
const amove = V.ParseFen(fen).amove;
- if (cmove == "-") this.amoves.push(null);
+ if (amove == "-") this.amoves.push(null);
else {
const amoveParts = amove.split("/");
let amove = {
return true;
}
- getAmove(move) {
+ // TODO: local stack of "last moves" to know move1
+ getAmove(move1, move2) {
+ // TODO: merge (one is action one is move)
if (move.appear.length == 2 && move.vanish.length == 2)
return { appear: move.appear, vanish: move.vanish };
return null;
}
- // TODO: this.firstMove + rooks location in setOtherVariables
- // only rooks location in FEN (firstMove is forgotten if quit game and come back)
doClick(square) {
// If subTurn == 2 && square is the final square of last move,
// then return an empty move
+ const L = this.lastMoves.length;
if (
this.subTurn == 2 &&
- square.x == this.firstMove.end.x &&
- square.y == this.firstMove.end.y)
+ square.x == this.lastMoves[L-1].end.x &&
+ square.y == this.lastMoves[L-1].end.y
) {
return {
appear: [],
return false;
}
+ // TODO: re-think these next 3 methods:
+ // Idea = have the info about lastMove in lastMoves[L-1],
+ // In particular if moving a piece or doing an action.
+
// "pa" : piece (as a square) doing this push/pull action
getActionMoves([sx, sy], [ex, ey], pa) {
const color = this.getColor(sx, sy);
// (doing the action, moving or not)
// TODO: for pushes, play the pushed piece first.
// for pulls: play the piece doing the action first
+ // If castle, then no options available next (just re-click)
+
getPotentialMovesFrom([x, y]) {
const color = this.turn;
if (this.getColor(x, y) != color)
// The only moves possible with enemy pieces are pulls and pushes:
return this.getPactions([x, y], color);
- else {
- // Playing my pieces: either on their own, or pushed by another
- // If subTurn == 2 then we should have a first move,
- // TODO = use it to allow some type of action
- if (this.subTurn == 2) {
- return (
- this.moveOnSubturn1.isAnAction
- ? super.getPotentialMovesFrom([x, y])
- : this.getPactions([x, y], color, TODO_arg)
- );
- } else {
- // Both options are possible at subTurn1: normal move, or push
- moves =
- super.getPotentialMovesFrom([x, y])
- .concat(this.getPactions([x, y], color, "push");
- // TODO: discard moves that let the king underCheck, and no second
- // move can counter check. Example: pinned queen pushes pinned pawn.
- .filter(m => {
- this.play(m);
- const res = this.filterMoves(this.getPotentialMoves(/* TODO: args? */)).length > 0;
- this.undo(m);
- return res;
- });
- }
+ // Playing my pieces: either on their own, or pushed by another
+ // If subTurn == 2 then we should have a first move,
+ // TODO = use it to allow some type of action
+ if (this.subTurn == 2) {
+ return (
+ this.moveOnSubturn1.isAnAction
+ ? super.getPotentialMovesFrom([x, y])
+ : this.getPactions([x, y], color, TODO_arg)
+ );
}
- return moves;
- }
-
- // TODO: track rooks locations, should be a field in FEN, in castleflags?
- // --> only useful if castleFlags is still ON
- getCastleMoves(sq) {
- // TODO: if rook1 isn't at its place (with castleFlags ON), set it off
- // same for rook2.
- let moves = super.getCastleMoves(sq);
- // TODO: restore castleFlags
+ // Both options are possible at subTurn1: normal move, or push
+ return (
+ super.getPotentialMovesFrom([x, y])
+ .concat(this.getPactions([x, y], color, "push"))
+ // TODO: discard moves that let the king underCheck, and no second
+ // move can counter check. Example: pinned queen pushes pinned pawn.
+ .filter(m => {
+ this.play(m);
+ const res = this.filterMoves(this.getPotentialMoves(/* TODO: args? */)).length > 0;
+ this.undo(m);
+ return res;
+ })
+ );
+ // Check opposite moves here --> we have lastMoves[L-1],
+ // which is completed (merged) with current played move if subTurn == 2
+// return moves.filter(m => {
+// const L = this.amoves.length; //at least 1: init from FEN
+// return !this.oppositeMoves(this.amoves[L - 1], m);
+// });
}
// Does m2 un-do m1 ? (to disallow undoing actions)
);
}
+ // TODO:
+ // Si on se met en échec au coup 1, peut-on le contrer au coup 2 ? (cf. take n make)
filterValid(moves) {
- if (moves.length == 0) return [];
- const color = this.turn;
- return moves.filter(m => {
- const L = this.amoves.length; //at least 1: init from FEN
- return !this.oppositeMoves(this.amoves[L - 1], m);
- });
+ if (this.subTurn == 1)
+ // Validity of subTurn 1 should be checked in getPotentialMoves...
+ return moves;
+ return super.filterMoves(moves);
}
isAttackedBySlideNJump([x, y], color, piece, steps, oneStep) {
play(move) {
move.flags = JSON.stringify(this.aggregateFlags());
V.PlayOnBoard(this.board, move);
- if (this.subTurn == 1) {
- // TODO: is there a second move possible?
- // (if the first move is a normal one, there may be no actions available)
- // --> If not, just change turn as ion the else {} section
- this.subTurn = 2;
- this.movesCount++;
- } else {
- // subTurn == 2
+ if (this.subTurn == 2) {
this.turn = V.GetOppCol(this.turn);
- this.subTurn = 1;
+ this.movesCount++;
}
+ this.subTurn = 3 - this.subTurn;
this.postPlay(move);
}
updateCastleFlags(move, piece) {
const c = V.GetOppCol(this.turn);
const firstRank = (c == "w" ? V.size.x - 1 : 0);
- // Update castling flags if rooks are moved (only)
- if (piece == V.KING && move.appear.length > 0)
- this.castleFlags[c] = [V.size.y, V.size.y];
- else if (
- move.start.x == firstRank &&
- this.castleFlags[c].includes(move.start.y)
- ) {
- const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1);
- this.castleFlags[c][flagIdx] = V.size.y;
+ // Update castling flags
+ if (piece == V.KING) this.castleFlags[c] = [V.size.y, V.size.y];
+ for (let v of move.vanish) {
+ if (v.x == firstRank && this.castleFlags[c].includes(v.y)) {
+ const flagIdx = (v.y == this.castleFlags[c][0] ? 0 : 1);
+ this.castleFlags[c][flagIdx] = V.size.y;
+ }
}
}
undo(move) {
this.disaggregateFlags(JSON.parse(move.flags));
V.UndoOnBoard(this.board, move);
- if (this.subTurn == 2) {
- this.subTurn = 1;
- this.movesCount--;
- }
- else {
- // subTurn == 1 (after a move played)
+ if (this.subTurn == 1) {
this.turn = V.GetOppCol(this.turn);
- this.subTurn = 2;
+ this.movesCount--;
}
+ this.subTurn = 3 - this.subTurn;
this.postUndo(move);
}
};