X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FDynamo.js;h=5955f64135187b52d81d368d9ce5884edbc2a323;hb=6e0c0bcba5c9e76a50a2676aa3e63bc317123bcb;hp=53eedfd50e81a7d285edecf69a03b485d9e11367;hpb=ad1e629eafacac9870bbcff3d9d7bece7582ddd2;p=vchess.git diff --git a/client/src/variants/Dynamo.js b/client/src/variants/Dynamo.js index 53eedfd5..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) { @@ -88,7 +88,7 @@ export class DynamoRules extends ChessRules { return ( ["appear","vanish"].map( mpart => { - if (mpart.length == 0) return "-"; + if (this.amoves[L-1][mpart].length == 0) return "-"; return ( this.amoves[L-1][mpart].map( av => { @@ -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); @@ -224,8 +240,21 @@ export class DynamoRules extends ChessRules { newMoves.forEach(m => { movesHash[getMoveHash(m)] = true; }); Array.prototype.push.apply(moves, newMoves); }; - // Free to play any move: - const moves = super.getPotentialMovesFrom([x, y]) + // Free to play any move (if piece of my 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) @@ -256,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 ( @@ -264,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); } @@ -282,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); @@ -299,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], @@ -315,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 { @@ -325,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 ( @@ -341,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) => { @@ -428,7 +511,19 @@ export class DynamoRules extends ChessRules { this.getPiece(rx, ry) == piece && this.getColor(rx, ry) == color ) { - // Now step in the other direction: if end of the world, then attacked + // Continue some steps in the same direction (pull) + rx += step[0]; + ry += step[1]; + while ( + V.OnBoard(rx, ry) && + this.board[rx][ry] == V.EMPTY && + !oneStep + ) { + rx += step[0]; + ry += step[1]; + } + if (!V.OnBoard(rx, ry)) return true; + // Step in the other direction (push) rx = x - step[0]; ry = y - step[1]; while ( @@ -464,6 +559,22 @@ export class DynamoRules extends ChessRules { return false; } + // No consideration of color: all pieces could be played + getAllPotentialMoves() { + let potentialMoves = []; + for (let i = 0; i < V.size.x; i++) { + for (let j = 0; j < V.size.y; j++) { + if (this.board[i][j] != V.EMPTY) { + Array.prototype.push.apply( + potentialMoves, + this.getPotentialMovesFrom([i, j]) + ); + } + } + } + return potentialMoves; + } + getCurrentScore() { if (this.subTurn == 2) // Move not over