X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FEightpieces.js;h=6efb182f3c6302dfb833e21280c715ece3f17e9c;hb=1b56b73614509d1dca8c4353f18fb78349940cf8;hp=fa80824bef1fddef326a51e7e15017531c944b2a;hpb=d54f6261c9e30f4eabb402ad301dd5c5e40fb656;p=vchess.git diff --git a/client/src/variants/Eightpieces.js b/client/src/variants/Eightpieces.js index fa80824b..6efb182f 100644 --- a/client/src/variants/Eightpieces.js +++ b/client/src/variants/Eightpieces.js @@ -83,8 +83,15 @@ export class EightpiecesRules extends ChessRules { return "Eightpieces/tmp_png/" + b; } - getPPpath(b, orientation) { - return this.getPpath(b, null, null, orientation); + getPPpath(m, orientation) { + return ( + this.getPpath( + m.appear[0].c + m.appear[0].p, + null, + null, + orientation + ) + ); } static ParseFen(fen) { @@ -101,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; } @@ -120,9 +127,11 @@ export class EightpiecesRules extends ChessRules { const L = this.sentryPush.length; if (!this.sentryPush[L-1]) return "-"; let res = ""; - this.sentryPush[L-1].forEach(coords => - res += V.CoordsToSquare(coords) + ","); - return res.slice(0, -1); + const spL = this.sentryPush[L-1].length; + // Condensate path: just need initial and final squares: + return [0, spL - 1] + .map(i => V.CoordsToSquare(this.sentryPush[L-1][i])) + .join(""); } setOtherVariables(fen) { @@ -135,11 +144,26 @@ export class EightpiecesRules extends ChessRules { const parsedFen = V.ParseFen(fen); if (parsedFen.sentrypush == "-") this.sentryPush = [null]; else { - this.sentryPush = [ - parsedFen.sentrypush.split(",").map(sq => { - return V.SquareToCoords(sq); - }) - ]; + // Expand init + dest squares into a full path: + 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: + if (delta[0] == 0 || delta[1] == 0 || delta[0] == delta[1]) { + const step = ['x', 'y'].map((i, idx) => { + return (dest[i] - init[i]) / delta[idx] || 0 + }); + let x = init.x + step[0], + y = init.y + step[1]; + while (x != dest.x || y != dest.y) { + newPath.push({ x: x, y: y }); + x += step[0]; + y += step[1]; + } + } + newPath.push(dest); + this.sentryPush = [newPath]; } } @@ -286,15 +310,16 @@ export class EightpiecesRules extends ChessRules { canIplay(side, [x, y]) { return ( - (this.subTurn == 1 && this.turn == side && this.getColor(x, y) == side) || + (this.subTurn == 1 && this.turn == side && this.getColor(x, y) == side) + || (this.subTurn == 2 && x == this.sentryPos.x && y == this.sentryPos.y) ); } 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) { @@ -448,6 +473,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 = []; @@ -477,6 +556,7 @@ 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]; if (!!this.sentryPush[L-1]) { // Maybe I was pushed const pl = this.sentryPush[L-1].length; @@ -487,7 +567,43 @@ 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)]; + const curDir = V.LANCER_DIRS[dirCode]; + // 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 ( @@ -518,7 +634,6 @@ export class EightpiecesRules extends ChessRules { } } // 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 @@ -788,8 +903,8 @@ export class EightpiecesRules extends ChessRules { case V.QUEEN: return sliderAttack(V.steps[V.ROOK].concat(V.steps[V.BISHOP])); case V.LANCER: { - // Special case: as long as no enemy units stands in-between, it attacks - // (if it points toward the king). + // Special case: as long as no enemy units stands in-between, + // it attacks (if it points toward the king). const allowedStep = V.LANCER_DIRS[this.board[x1][y1].charAt(1)]; return sliderAttack([allowedStep], "lancer"); } @@ -1027,7 +1142,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]; @@ -1036,7 +1160,8 @@ export class EightpiecesRules extends ChessRules { Object.keys(V.LANCER_DIRNAMES).includes(move.appear[0].p) ) { // Fix promotions in lancer: - notation = notation.slice(0, -1) + "L:" + V.LANCER_DIRNAMES[move.appear[0].p]; + notation = notation.slice(0, -1) + + "L:" + V.LANCER_DIRNAMES[move.appear[0].p]; } return notation; }