From: Benjamin Auder <benjamin.auder@somewhere> Date: Wed, 12 Dec 2018 11:43:13 +0000 (+0100) Subject: Advance on Ultima variant code X-Git-Url: https://git.auder.net/variants/current/css/img/pieces/doc/common.css?a=commitdiff_plain;h=7688bf7781d10bdf7db2ff558a35852bebcaae53;p=vchess.git Advance on Ultima variant code --- diff --git a/public/javascripts/variants/Ultima.js b/public/javascripts/variants/Ultima.js index 4612da10..18afe402 100644 --- a/public/javascripts/variants/Ultima.js +++ b/public/javascripts/variants/Ultima.js @@ -52,7 +52,33 @@ class UltimaRules extends ChessRules getPotentialMovesFrom([x,y]) { - // TODO: pre-check: is thing on this square immobilized? If yes, return [] + // Pre-check: is thing on this square immobilized? + // In this case add potential suicide as a move "taking the immobilizer" + const piece = this.getPiece(x,y); + const color = this.getColor(x,y); + const oppCol = this.getOppCol(color); + const V = VariantRules; + const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); + const [sizeX,sizeY] = V.size; + for (let step of adjacentSteps) + { + const [i,j] = [x+step[0],y+step[1]]; + if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j] != V.EMPTY + && this.getColor(i,j) == oppCol) + { + const oppPiece = this.getPiece(i,j); + if (oppPiece == V.IMMOBILIZER + || (oppPiece == V.BISHOP && piece == V.IMMOBILIZER)) + { + return [ new Move({ + appear: [], + vanish: [{x:x,y:y,p:piece,c:color}], + start: {x:x,y:y}, + end: {x:i,y:j} + }) ]; + } + } + } switch (this.getPiece(x,y)) { case VariantRules.IMMOBILIZER: @@ -60,11 +86,6 @@ class UltimaRules extends ChessRules default: return super.getPotentialMovesFrom([x,y]); } - // TODO: add potential suicides as a move "taking the immobilizer" - // TODO: add long-leaper captures - // TODO: mark matching coordinator/withdrawer/chameleon moves as captures - // (will be a bit tedious for chameleons) - // --> filter directly in functions below } getSlideNJumpMoves([x,y], steps, oneStep) @@ -97,29 +118,110 @@ class UltimaRules extends ChessRules return moves; } + // "Pincher" getPotentialPawnMoves([x,y]) { - return super.getPotentialRookMoves([x,y]); + let moves = super.getPotentialRookMoves([x,y]); + // Add captures + moves.forEach(m => { + if (m + }); } + // Coordinator getPotentialRookMoves(sq) { - return super.getPotentialQueenMoves(sq); + const color = this.getColor(sq); + const oppCol = this.getOppCol(color); + const kp = this.kingPos[color]; + let moves = super.getPotentialQueenMoves(sq); + moves.forEach(m => { + // Check piece-king rectangle (if any) corners for enemy pieces + if (m.end.x == kp[0] || m.end.y == kp[1]) + return; //"flat rectangle" + const corner1 = [Math.max(m.end.x,kp[0]), Math.min(m.end.y,kp[1])]; + const corner2 = [Math.min(m.end.x,kp[0]), Math.max(m.end.y,kp[1])]; + for (let [i,j] of [corner1,corner2]) + { + if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) == oppCol) + { + m.vanish.push( new PiPo({ + x:i, + y:j, + p:this.getPiece(i,j), + c:oppCol + }) ); + } + } + }); + return moves; } - getPotentialKnightMoves(sq) + // Long-leaper + getPotentialKnightMoves([x,y]) { - return super.getPotentialQueenMoves(sq); + let moves = super.getPotentialQueenMoves(sq); + // Look in every direction for captures + const V = VariantRules; + const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); + const [sizeX,sizeY] = V.size; + const color = this.getColor(x,y); + for (let step of steps) + { + let [i,j] = [x+step[0], y+step[1]]; + while (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j]==V.EMPTY) + { + i += step[0]; + j += step[1]; + } + if (i<0 && i>=sizeX || j<0 || j>=sizeY || this.getColor(i,j)==color) + continue; + // Found an enemy piece: potential capture (if empty space behind) + // So, while we find enemy pieces + space in this direction, add captures! + i += step[0]; + j += step[1]; + while ( ) //TODO: finish........ + } + return moves; } getPotentialBishopMoves(sq) { return super.getPotentialQueenMoves(sq); + // TODO: add captures of coordinators,pinchers,withdrawers... by re-using code } - getPotentialQueenMoves(sq) + getPotentialQueenMoves([x,y]) { - return super.getPotentialQueenMoves(sq); + let moves = super.getPotentialQueenMoves(sq); + const V = VariantRules; + const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); + let capturingDirections = []; + const color = this.getColor(x,y); + const oppCol = this.getOppCol(color); + adjacentSteps.forEach(step => { + const [i,j] = [x+step[0],y+step[1]]; + if (this.board[i][j] != V.EMPTY && this.getColor(i,j) == oppCol) + capturingDirections.push(step); + }); + moves.forEach(m => { + const step = [ + m.end.x!=x ? (m.end.x-x)/Math.abs(m.end.x-x) : 0, + m.end.y!=y ? (m.end.y-y)/Math.abs(m.end.y-y) : 0 + ]; + // NOTE: includes() function does not work on complex array elements + // TODO: this test should be done only once per direction + if (capturingDirection.some(dir => _.isEqual(dir, step))) + { + const [i,j] = [x-step[0],y-step[1]]; + m.vanish.push(new PiPo({ + x:i, + y:j, + p:this.getPiece(i,j), + c:oppCol + })); + } + }); } getPotentialImmobilizerMoves(sq)