X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FEightpieces.js;h=583b1c5ac5a14e609324a274136da6d39cea31ec;hb=7f1df0d95d2190fd69ef7c58f5a795aef3f92869;hp=a05ba1e220035b4d9644010b1b4c952e7c990b98;hpb=0a9cef131612079e55714f56f1466b4e2bd749af;p=vchess.git diff --git a/client/src/variants/Eightpieces.js b/client/src/variants/Eightpieces.js index a05ba1e2..583b1c5a 100644 --- a/client/src/variants/Eightpieces.js +++ b/client/src/variants/Eightpieces.js @@ -108,7 +108,7 @@ export class EightpiecesRules extends ChessRules { // 5) Check sentry push (if any) if ( fenParsed.sentrypush != "-" && - !fenParsed.sentrypush.match(/^([a-h][1-8],?)+$/) + !fenParsed.sentrypush.match(/^([a-h][1-8]){2,2}$/) ) { return false; } @@ -131,7 +131,7 @@ export class EightpiecesRules extends ChessRules { // Condensate path: just need initial and final squares: return [0, spL - 1] .map(i => V.CoordsToSquare(this.sentryPush[L-1][i])) - .join(","); + .join(""); } setOtherVariables(fen) { @@ -145,8 +145,8 @@ export class EightpiecesRules extends ChessRules { if (parsedFen.sentrypush == "-") this.sentryPush = [null]; else { // Expand init + dest squares into a full path: - const [init, dest] = - parsedFen.sentrypush.split(",").map(sq => V.SquareToCoords(sq)); + const init = V.SquareToCoords(parsedFen.sentrypush.substr(0, 2)), + dest = V.SquareToCoords(parsedFen.sentrypush.substr(2)); let newPath = [init]; const delta = ['x', 'y'].map(i => Math.abs(dest[i] - init[i])); // Check that it's not a knight movement: @@ -317,9 +317,9 @@ export class EightpiecesRules extends ChessRules { } 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) { @@ -406,12 +406,18 @@ export class EightpiecesRules extends ChessRules { // 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) { @@ -473,6 +479,60 @@ export class EightpiecesRules extends ChessRules { 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 = []; @@ -502,6 +562,8 @@ export class EightpiecesRules extends ChessRules { // 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; @@ -512,7 +574,42 @@ export class EightpiecesRules extends ChessRules { // 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 ( @@ -531,36 +628,46 @@ export class EightpiecesRules extends ChessRules { 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 ) { @@ -752,9 +859,21 @@ export class EightpiecesRules extends ChessRules { 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; @@ -1052,7 +1171,16 @@ export class EightpiecesRules extends ChessRules { 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];