}
getPotentialMovesFrom([x, y]) {
- // At subTurn == 2, jailers aren't effective (Jeff K)
const piece = this.getPiece(x, y);
const L = this.sentryPush.length;
+ // At subTurn == 2, jailers aren't effective (Jeff K)
if (this.subTurn == 1) {
const jsq = this.isImmobilized([x, y]);
if (!!jsq) {
// Pawns might be pushed on 1st rank and attempt to move again:
if (!V.OnBoard(x + shiftX, y)) return [];
- const finalPieces =
- // A push cannot put a pawn on last rank (it goes backward)
- x + shiftX == lastRank
- ? Object.keys(V.LANCER_DIRS).concat(
- [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN, V.SENTRY, V.JAILER])
- : [V.PAWN];
+ // A push cannot put a pawn on last rank (it goes backward)
+ let finalPieces = [V.PAWN];
+ if (x + shiftX == lastRank) {
+ // Only allow direction facing inside board:
+ const allowedLancerDirs =
+ lastRank == 0
+ ? ['e', 'f', 'g', 'h', 'm']
+ : ['c', 'd', 'e', 'm', 'o'];
+ finalPieces =
+ allowedLancerDirs
+ .concat([V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN, V.SENTRY, V.JAILER]);
+ }
if (this.board[x + shiftX][y] == V.EMPTY) {
// One square forward
for (let piece of finalPieces) {
return moves;
}
+ doClick(square) {
+ if (isNaN(square[0])) return null;
+ const L = this.sentryPush.length;
+ const [x, y] = [square[0], square[1]];
+ const color = this.turn;
+ if (
+ this.subTurn == 2 ||
+ this.board[x][y] == V.EMPTY ||
+ this.getPiece(x, y) != V.LANCER ||
+ this.getColor(x, y) != color ||
+ !!this.sentryPush[L-1]
+ ) {
+ return null;
+ }
+ // Stuck lancer?
+ const orientation = this.board[x][y][1];
+ const step = V.LANCER_DIRS[orientation];
+ if (!V.OnBoard(x + step[0], y + step[1])) {
+ let choices = [];
+ Object.keys(V.LANCER_DIRS).forEach(k => {
+ const dir = V.LANCER_DIRS[k];
+ if (
+ (dir[0] != step[0] || dir[1] != step[1]) &&
+ V.OnBoard(x + dir[0], y + dir[1])
+ ) {
+ choices.push(
+ new Move({
+ vanish: [
+ new PiPo({
+ x: x,
+ y: y,
+ c: color,
+ p: orientation
+ })
+ ],
+ appear: [
+ new PiPo({
+ x: x,
+ y: y,
+ c: color,
+ p: k
+ })
+ ],
+ start: { x: x, y : y },
+ end: { x: -1, y: -1 }
+ })
+ );
+ }
+ });
+ return choices;
+ }
+ return null;
+ }
+
// Obtain all lancer moves in "step" direction
getPotentialLancerMoves_aux([x, y], step, tr) {
let moves = [];
// Except if just after a push: allow all movements from init square then
const L = this.sentryPush.length;
const color = this.getColor(x, y);
+ const dirCode = this.board[x][y][1];
+ const curDir = V.LANCER_DIRS[dirCode];
if (!!this.sentryPush[L-1]) {
// Maybe I was pushed
const pl = this.sentryPush[L-1].length;
// I was pushed: allow all directions (for this move only), but
// do not change direction after moving, *except* if I keep the
// same orientation in which I was pushed.
- const curDir = V.LANCER_DIRS[this.board[x][y].charAt(1)];
+ // Also allow simple reorientation ("capturing king"):
+ if (!V.OnBoard(x + curDir[0], y + curDir[1])) {
+ const kp = this.kingPos[color];
+ let reorientMoves = [];
+ Object.keys(V.LANCER_DIRS).forEach(k => {
+ const dir = V.LANCER_DIRS[k];
+ if (
+ (dir[0] != curDir[0] || dir[1] != curDir[1]) &&
+ V.OnBoard(x + dir[0], y + dir[1])
+ ) {
+ reorientMoves.push(
+ new Move({
+ vanish: [
+ new PiPo({
+ x: x,
+ y: y,
+ c: color,
+ p: dirCode
+ })
+ ],
+ appear: [
+ new PiPo({
+ x: x,
+ y: y,
+ c: color,
+ p: k
+ })
+ ],
+ start: { x: x, y : y },
+ end: { x: kp[0], y: kp[1] }
+ })
+ );
+ }
+ });
+ Array.prototype.push.apply(moves, reorientMoves);
+ }
Object.values(V.LANCER_DIRS).forEach(step => {
const dirCode = Object.keys(V.LANCER_DIRS).find(k => {
return (
let chooseMoves = [];
dirMoves.forEach(m => {
Object.keys(V.LANCER_DIRS).forEach(k => {
- let mk = JSON.parse(JSON.stringify(m));
- mk.appear[0].p = k;
- moves.push(mk);
+ const newDir = V.LANCER_DIRS[k];
+ // Prevent orientations toward outer board:
+ if (V.OnBoard(m.end.x + newDir[0], m.end.y + newDir[1])) {
+ let mk = JSON.parse(JSON.stringify(m));
+ mk.appear[0].p = k;
+ chooseMoves.push(mk);
+ }
});
});
Array.prototype.push.apply(moves, chooseMoves);
- } else Array.prototype.push.apply(moves, dirMoves);
+ }
+ else Array.prototype.push.apply(moves, dirMoves);
});
return moves;
}
}
// I wasn't pushed: standard lancer move
- const dirCode = this.board[x][y][1];
const monodirMoves =
this.getPotentialLancerMoves_aux([x, y], V.LANCER_DIRS[dirCode]);
// Add all possible orientations aftermove except if I'm being pushed
if (this.subTurn == 1) {
monodirMoves.forEach(m => {
Object.keys(V.LANCER_DIRS).forEach(k => {
- let mk = JSON.parse(JSON.stringify(m));
- mk.appear[0].p = k;
- moves.push(mk);
+ const newDir = V.LANCER_DIRS[k];
+ // Prevent orientations toward outer board:
+ if (V.OnBoard(m.end.x + newDir[0], m.end.y + newDir[1])) {
+ let mk = JSON.parse(JSON.stringify(m));
+ mk.appear[0].p = k;
+ moves.push(mk);
+ }
});
});
return moves;
- } else {
- // I'm pushed: add potential nudges
+ }
+ else {
+ // I'm pushed: add potential nudges, except for current orientation
let potentialNudges = [];
for (let step of V.steps[V.ROOK].concat(V.steps[V.BISHOP])) {
if (
+ (step[0] != curDir[0] || step[1] != curDir[1]) &&
V.OnBoard(x + step[0], y + step[1]) &&
this.board[x + step[0]][y + step[1]] == V.EMPTY
) {
coord.x += step[0];
coord.y += step[1];
}
+ const L = this.sentryPush.length;
+ const pl = (!!this.sentryPush[L-1] ? this.sentryPush[L-1].length : 0);
for (let xy of lancerPos) {
const dir = V.LANCER_DIRS[this.board[xy.x][xy.y].charAt(1)];
- if (dir[0] == -step[0] && dir[1] == -step[1]) return true;
+ if (
+ (dir[0] == -step[0] && dir[1] == -step[1]) ||
+ // If the lancer was just pushed, this is an attack too:
+ (
+ !!this.sentryPush[L-1] &&
+ this.sentryPush[L-1][pl-1].x == xy.x &&
+ this.sentryPush[L-1][pl-1].y == xy.y
+ )
+ ) {
+ return true;
+ }
}
}
return false;
end: move.end
};
notation = super.getNotation(simpleMove);
- } else notation = super.getNotation(move);
+ }
+ else if (
+ move.appear.length > 0 &&
+ move.vanish[0].x == move.appear[0].x &&
+ move.vanish[0].y == move.appear[0].y
+ ) {
+ // Lancer in-place reorientation:
+ notation = "L" + V.CoordsToSquare(move.start) + ":R";
+ }
+ else notation = super.getNotation(move);
if (Object.keys(V.LANCER_DIRNAMES).includes(move.vanish[0].p))
// Lancer: add direction info
notation += "=" + V.LANCER_DIRNAMES[move.appear[0].p];