X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FDynamo.js;h=5955f64135187b52d81d368d9ce5884edbc2a323;hb=6e0c0bcba5c9e76a50a2676aa3e63bc317123bcb;hp=91920e074e3eb9c835ca31a714ccb7e7485bc810;hpb=156986e6b06dc5f0acd39860bd4fef6b030e263b;p=vchess.git diff --git a/client/src/variants/Dynamo.js b/client/src/variants/Dynamo.js index 91920e07..5955f641 100644 --- a/client/src/variants/Dynamo.js +++ b/client/src/variants/Dynamo.js @@ -9,7 +9,7 @@ export class DynamoRules extends ChessRules { canIplay(side, [x, y]) { // Sometimes opponent's pieces can be moved directly - return true; + return this.turn == side; } setOtherVariables(fen) { @@ -158,7 +158,6 @@ export class DynamoRules extends ChessRules { } // There was something on x2,y2, maybe our color, pushed/pulled. - // Also, the pushed/pulled piece must exit the board. isAprioriValidExit([x1, y1], [x2, y2], color2) { const color1 = this.getColor(x1, y1); const pawnShift = (color1 == 'w' ? -1 : 1); @@ -208,11 +207,28 @@ export class DynamoRules extends ChessRules { return false; } + isAprioriValidVertical([x1, y1], x2) { + const piece = this.getPiece(x1, y1); + const deltaX = Math.abs(x1 - x2); + const startRank = (this.getColor(x1, y1) == 'w' ? 6 : 1); + return ( + [V.QUEEN, V.ROOK].includes(piece) || + ( + [V.KING, V.PAWN].includes(piece) && + ( + deltaX == 1 || + (deltaX == 2 && piece == V.PAWN && x1 == startRank) + ) + ) + ); + } + // NOTE: for pushes, play the pushed piece first. // for pulls: play the piece doing the action first // NOTE: to push a piece out of the board, make it slide until its king getPotentialMovesFrom([x, y]) { const color = this.turn; + const sqCol = this.getColor(x, y); if (this.subTurn == 1) { const getMoveHash = (m) => { return V.CoordsToSquare(m.start) + V.CoordsToSquare(m.end); @@ -225,10 +241,20 @@ export class DynamoRules extends ChessRules { Array.prototype.push.apply(moves, newMoves); }; // Free to play any move (if piece of my color): - const moves = - this.getColor(x, y) == color + let moves = + sqCol == color ? super.getPotentialMovesFrom([x, y]) : []; + // There may be several suicide moves: keep only one + let hasExit = false; + moves = moves.filter(m => { + const suicide = (m.appear.length == 0); + if (suicide) { + if (hasExit) return false; + hasExit = true; + } + return true; + }); const pawnShift = (color == 'w' ? -1 : 1); const pawnStartRank = (color == 'w' ? 6 : 1); // Structure to avoid adding moves twice (can be action & move) @@ -259,7 +285,6 @@ export class DynamoRules extends ChessRules { ) { const deltaX = Math.abs(i - x); const deltaY = Math.abs(j - y); - // Can a priori go both ways, except with pawns switch (this.getPiece(i, j)) { case V.PAWN: if ( @@ -267,13 +292,12 @@ export class DynamoRules extends ChessRules { deltaX <= 2 && deltaY <= 1 ) { - const pColor = this.getColor(x, y); - if (pColor == color && deltaY == 0) { + if (sqCol == color && deltaY == 0) { // Pushed forward const maxSteps = (i == pawnStartRank && deltaX == 1 ? 2 : 1); addMoves(step, maxSteps); } - else if (pColor != color && deltaY == 1 && deltaX == 1) + else if (sqCol != color && deltaY == 1 && deltaX == 1) // Pushed diagonally addMoves(step, 1); } @@ -285,8 +309,8 @@ export class DynamoRules extends ChessRules { if (deltaX == deltaY) addMoves(step); break; case V.QUEEN: - if (deltaX == 0 || deltaY == 0 || deltaX == deltaY) - addMoves(step); + // All steps are valid for a queen: + addMoves(step); break; case V.KING: if (deltaX <= 1 && deltaY <= 1) addMoves(step, 1); @@ -302,13 +326,19 @@ export class DynamoRules extends ChessRules { // naturally limited in those cases. const L = this.firstMove.length; const fm = this.firstMove[L-1]; - if (fm.appear.length == 2 && fm.vanish.length == 2) - // Castle: no real move playable then. + if ( + (fm.appear.length == 2 && fm.vanish.length == 2) || + (fm.vanish[0].c == sqCol && sqCol != color) + ) { + // Castle or again opponent color: no move playable then. return []; + } if (fm.appear.length == 0) { // Piece at subTurn 1 just exited the board. // Can I be a piece which caused the exit? if ( + // Only "turn" color can do actions + sqCol == color && this.isAprioriValidExit( [x, y], [fm.start.x, fm.start.y], @@ -318,7 +348,9 @@ export class DynamoRules extends ChessRules { // Seems so: const dir = this.getNormalizedDirection( [fm.start.x - x, fm.start.y - y]); - return this.getMovesInDirection([x, y], dir); + const nbSteps = + ([V.PAWN,V.KING,V.KNIGHT].includes(this.getPiece(x, y)) ? 1 : null); + return this.getMovesInDirection([x, y], dir, nbSteps); } } else { @@ -328,6 +360,15 @@ export class DynamoRules extends ChessRules { [fm.start.x - x, fm.start.y - y]); // Normalized directions should match if (dir[0] == dirM[0] && dir[1] == dirM[1]) { + // If first move is a pawn move, only a queen, rook, or maybe king or + // pawn can follow (need vertical movement option). + if ( + fm.vanish[0].p == V.PAWN && + fm.vanish[0].c == color && + !this.isAprioriValidVertical([x, y], fm.start.x) + ) { + return []; + } // And nothing should stand between [x, y] and the square fm.start let [i, j] = [x + dir[0], y + dir[1]]; while ( @@ -344,6 +385,45 @@ export class DynamoRules extends ChessRules { return []; } + getSlideNJumpMoves([x, y], steps, oneStep) { + let moves = []; + const c = this.getColor(x, y); + const piece = this.getPiece(x, y); + outerLoop: for (let step of steps) { + let i = x + step[0]; + let j = y + step[1]; + while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) { + moves.push(this.getBasicMove([x, y], [i, j])); + if (oneStep) continue outerLoop; + i += step[0]; + j += step[1]; + } + if (V.OnBoard(i, j)) { + if (this.canTake([x, y], [i, j])) + moves.push(this.getBasicMove([x, y], [i, j])); + } + else { + // Add potential board exit (suicide), except for the king + if (piece != V.KING) { + moves.push({ + start: { x: x, y: y}, + end: { x: this.kingPos[c][0], y: this.kingPos[c][1] }, + appear: [], + vanish: [ + new PiPo({ + x: x, + y: y, + c: c, + p: piece + }) + ] + }); + } + } + } + return moves; + } + // Does m2 un-do m1 ? (to disallow undoing actions) oppositeMoves(m1, m2) { const isEqual = (av1, av2) => {