X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fvariants%2FUltima.js;h=04ef29b0023a98058c7d10ce0dbce5a1dc5d50fa;hb=0b7d99ecbb5dedc02cd96c457b5fc2962db9b297;hp=d6676436a24f21641ae57783ebd656a4bad85fff;hpb=a3c86ec9b60326a8ae3d8f237493fb09627aed95;p=vchess.git diff --git a/public/javascripts/variants/Ultima.js b/public/javascripts/variants/Ultima.js index d6676436..04ef29b0 100644 --- a/public/javascripts/variants/Ultima.js +++ b/public/javascripts/variants/Ultima.js @@ -50,38 +50,54 @@ class UltimaRules extends ChessRules // - a "bishop" is a chameleon, capturing as its prey // - a "queen" is a withdrawer, capturing by moving away from pieces - getPotentialMovesFrom([x,y]) + // Is piece on square (x,y) immobilized? + isImmobilized([x,y]) { - // 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; + outerLoop: for (let step of adjacentSteps) { const [i,j] = [x+step[0],y+step[1]]; - if (i>=0 && i=0 && j=0 && i=0 && j=0 && i=0 - && j { @@ -132,17 +142,16 @@ class UltimaRules extends ChessRules for (let step of steps) { const sq2 = [m.end.x+2*step[0],m.end.y+2*step[1]]; - if (sq2[0]>=0 && sq2[0]=0 && sq2[1]=0 && i=0 && j=sizeX || j<0 || j>=sizeY || this.getColor(i,j)==color + if (!V.OnBoard(i,j) || this.getColor(i,j)==color || (!!byChameleon && this.getPiece(i,j)!=V.KNIGHT)) { continue; @@ -236,7 +243,7 @@ class UltimaRules extends ChessRules let last = [i,j]; let cur = [i+step[0],j+step[1]]; let vanished = [ new PiPo({x:x,y:y,c:color,p:piece}) ]; - while (cur[0]>=0 && cur[0]=0 && cur[1] { - const key = m.end.x + sizeX * m.end.y; + const key = m.end.x + V.size.x * m.end.y; if (!mergedMoves[key]) mergedMoves[key] = m; else @@ -309,16 +315,13 @@ class UltimaRules extends ChessRules if (moves.length == 0) return; const [x,y] = [moves[0].start.x,moves[0].start.y]; - const V = VariantRules; const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); let capturingDirections = []; const color = this.turn; const oppCol = this.getOppCol(color); - const [sizeX,sizeY] = V.size; adjacentSteps.forEach(step => { const [i,j] = [x+step[0],y+step[1]]; - if (i>=0 && i=0 && j call the appropriate isAttackedBy... (exception of immobilizers) - // Other exception: a chameleon cannot attack a chameleon (seemingly...) + // We cheat a little here: since this function is used exclusively for king, + // it's enough to check the immediate surrounding of the square. + const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); + for (let step of adjacentSteps) + { + const [i,j] = [x+step[0],y+step[1]]; + if (V.OnBoard(i,j) && this.board[i][j]!=V.EMPTY + && colors.includes(this.getColor(i,j)) && this.getPiece(i,j) == V.BISHOP) + { + return true; //bishops are never immobilized + } + } return false; } - isAttackedByQueen(sq, colors) + isAttackedByQueen([x,y], colors) { // Square (x,y) must be adjacent to a queen, and the queen must have // some free space in the opposite direction from (x,y) + const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]); + for (let step of adjacentSteps) + { + const sq2 = [x+2*step[0],y+2*step[1]]; + if (V.OnBoard(sq2[0],sq2[1]) && this.board[sq2[0]][sq2[1]] == V.EMPTY) + { + const sq1 = [x+step[0],y+step[1]]; + if (this.board[sq1[0]][sq1[1]] != V.EMPTY + && colors.includes(this.getColor(sq1[0],sq1[1])) + && this.getPiece(sq1[0],sq1[1]) == V.QUEEN + && !this.isImmobilized(sq1)) + { + return true; + } + } + } return false; } updateVariables(move) { - // Just update king position + // Just update king(s) position(s) const piece = this.getPiece(move.start.x,move.start.y); const c = this.getColor(move.start.x,move.start.y); - if (piece == VariantRules.KING && move.appear.length > 0) + if (piece == V.KING && move.appear.length > 0) { this.kingPos[c][0] = move.appear[0].x; this.kingPos[c][1] = move.appear[0].y; } } - checkGameEnd() - { - // No valid move: game is lost (stalemate is a win) - return this.turn == "w" ? "0-1" : "1-0"; - } - static get VALUES() { //TODO: totally experimental! return { 'p': 1, @@ -494,12 +609,21 @@ class UltimaRules extends ChessRules getNotation(move) { - if (move.appear.length == 0) + const initialSquare = + String.fromCharCode(97 + move.start.y) + (V.size.x-move.start.x); + const finalSquare = String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x); + let notation = undefined; + if (move.appear[0].p == V.PAWN) { - const startSquare = - String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x); - return "^" + startSquare; //suicide + // Pawn: generally ambiguous short notation, so we use full description + notation = "P" + initialSquare + finalSquare; } - return super.getNotation(move); + else if (move.appear[0].p == V.KING) + notation = "K" + (move.vanish.length>1 ? "x" : "") + finalSquare; + else + notation = move.appear[0].p.toUpperCase() + finalSquare; + if (move.vanish.length > 1 && move.appear[0].p != V.KING) + notation += "X"; //capture mark (not describing what is captured...) + return notation; } }