X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fbase_rules.js;h=0868a3670178e8a855786f9b422f9d38ca52478b;hb=46302e643947a66a5593a8eb1140d314effcea95;hp=163049536c8a44e041008972a2ee9b96fa4fd999;hpb=818ede16c09c2f5650d7a6b7b5ea42d6dd1a0c30;p=vchess.git diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js index 16304953..0868a367 100644 --- a/public/javascripts/base_rules.js +++ b/public/javascripts/base_rules.js @@ -106,7 +106,7 @@ class ChessRules static GetBoard(fen) { let rows = fen.split(" ")[0].split("/"); - let [sizeX,sizeY] = VariantRules.size; + const [sizeX,sizeY] = VariantRules.size; let board = doubleArray(sizeX, sizeY, ""); for (let i=0; i=0 && i=0 && j=0 && i<8 && j>=0 && j<8 && this.canTake(color, this.getColor(i,j))) - moves.push(this.getBasicMove(x, y, i, j)); + if (i>=0 && i<8 && j>=0 && j<8 && this.canTake([x,y], [i,j])) + moves.push(this.getBasicMove([x,y], [i,j])); } return moves; } // What are the pawn moves from square x,y considering color "color" ? - getPotentialPawnMoves(x, y, color) + getPotentialPawnMoves([x,y]) { + const color = this.getColor(x,y); var moves = []; var V = VariantRules; - let [sizeX,sizeY] = VariantRules.size; + const [sizeX,sizeY] = VariantRules.size; let shift = (color == "w" ? -1 : 1); let startRank = (color == "w" ? sizeY-2 : 1); let lastRank = (color == "w" ? 0 : sizeY-1); @@ -297,24 +297,18 @@ class ChessRules // Normal moves if (this.board[x+shift][y] == V.EMPTY) { - moves.push(this.getBasicMove(x, y, x+shift, y)); + moves.push(this.getBasicMove([x,y], [x+shift,y])); if (x==startRank && this.board[x+2*shift][y] == V.EMPTY) { // Two squares jump - moves.push(this.getBasicMove(x, y, x+2*shift, y)); + moves.push(this.getBasicMove([x,y], [x+2*shift,y])); } } // Captures - if (y>0 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y-1)) - && this.board[x+shift][y-1] != V.EMPTY) - { - moves.push(this.getBasicMove(x, y, x+shift, y-1)); - } - if (y0 && this.canTake([x,y], [x+shift,y-1]) && this.board[x+shift][y-1] != V.EMPTY) + moves.push(this.getBasicMove([x,y], [x+shift,y-1])); + if (y { // Normal move if (this.board[x+shift][y] == V.EMPTY) - moves.push(this.getBasicMove(x, y, x+shift, y, p)); + moves.push(this.getBasicMove([x,y], [x+shift,y], {c:color,p:p})); // Captures - if (y>0 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y-1)) - && this.board[x+shift][y-1] != V.EMPTY) - { - moves.push(this.getBasicMove(x, y, x+shift, y-1, p)); - } - if (y0 && this.canTake([x,y], [x+shift,y-1]) && this.board[x+shift][y-1] != V.EMPTY) + moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:color,p:p})); + if (y { - return !this.underCheck(m, color); - }); + let color = this.turn; + return moves.filter(m => { return !this.underCheck(m, color); }); } // Search for all valid moves considering current turn (for engine and game end) - getAllValidMoves(color) + getAllValidMoves() { + const color = this.turn; const oppCol = this.getOppCol(color); var potentialMoves = []; let [sizeX,sizeY] = VariantRules.size; @@ -512,8 +493,9 @@ class ChessRules } // Stop at the first move found - atLeastOneMove(color) + atLeastOneMove() { + const color = this.turn; const oppCol = this.getOppCol(color); let [sizeX,sizeY] = VariantRules.size; for (var i=0; i=0 && x+pawnShift<8) + for (let c of colors) { - for (let i of [-1,1]) + let pawnShift = (c=="w" ? 1 : -1); + if (x+pawnShift>=0 && x+pawnShift<8) { - if (y+i>=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN - && this.getColor(x+pawnShift,y+i)==c) + for (let i of [-1,1]) { - return true; + if (y+i>=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN + && this.getColor(x+pawnShift,y+i)==c) + { + return true; + } } } } @@ -567,42 +552,42 @@ class ChessRules } // Is square x,y attacked by rooks of color c ? - isAttackedByRook(sq, color) + isAttackedByRook(sq, colors) { - return this.isAttackedBySlideNJump(sq, color, + return this.isAttackedBySlideNJump(sq, colors, VariantRules.ROOK, VariantRules.steps[VariantRules.ROOK]); } // Is square x,y attacked by knights of color c ? - isAttackedByKnight(sq, color) + isAttackedByKnight(sq, colors) { - return this.isAttackedBySlideNJump(sq, color, + return this.isAttackedBySlideNJump(sq, colors, VariantRules.KNIGHT, VariantRules.steps[VariantRules.KNIGHT], "oneStep"); } // Is square x,y attacked by bishops of color c ? - isAttackedByBishop(sq, color) + isAttackedByBishop(sq, colors) { - return this.isAttackedBySlideNJump(sq, color, + return this.isAttackedBySlideNJump(sq, colors, VariantRules.BISHOP, VariantRules.steps[VariantRules.BISHOP]); } // Is square x,y attacked by queens of color c ? - isAttackedByQueen(sq, color) + isAttackedByQueen(sq, colors) { - return this.isAttackedBySlideNJump(sq, color, + return this.isAttackedBySlideNJump(sq, colors, VariantRules.QUEEN, VariantRules.steps[VariantRules.QUEEN]); } // Is square x,y attacked by king of color c ? - isAttackedByKing(sq, color) + isAttackedByKing(sq, colors) { - return this.isAttackedBySlideNJump(sq, color, + return this.isAttackedBySlideNJump(sq, colors, VariantRules.KING, VariantRules.steps[VariantRules.QUEEN], "oneStep"); } // Generic method for non-pawn pieces ("sliding or jumping"): is x,y attacked by piece != color ? - isAttackedBySlideNJump([x,y], c,piece,steps,oneStep) + isAttackedBySlideNJump([x,y], colors, piece, steps, oneStep) { for (let step of steps) { @@ -614,7 +599,7 @@ class ChessRules ry += step[1]; } if (rx>=0 && rx<8 && ry>=0 && ry<8 && this.board[rx][ry] != VariantRules.EMPTY - && this.getPiece(rx,ry) == piece && this.getColor(rx,ry) == c) + && this.getPiece(rx,ry) == piece && colors.includes(this.getColor(rx,ry))) { return true; } @@ -623,20 +608,22 @@ class ChessRules } // Is color c under check after move ? - underCheck(move, c) + underCheck(move) { + const color = this.turn; this.play(move); - let res = this.isAttacked(this.kingPos[c], this.getOppCol(c)); + let res = this.isAttacked(this.kingPos[color], this.getOppCol(color)); this.undo(move); return res; } // On which squares is color c under check (after move) ? - getCheckSquares(move, c) + getCheckSquares(move) { this.play(move); - let res = this.isAttacked(this.kingPos[c], this.getOppCol(c)) - ? [ JSON.parse(JSON.stringify(this.kingPos[c])) ] //need to duplicate! + const color = this.turn; + let res = this.isAttacked(this.kingPos[color], this.getOppCol(color)) + ? [ JSON.parse(JSON.stringify(this.kingPos[color])) ] //need to duplicate! : [ ]; this.undo(move); return res; @@ -723,7 +710,7 @@ class ChessRules ////////////// // END OF GAME - checkGameOver(color) + checkGameOver() { // Check for 3 repetitions if (this.moves.length >= 8) @@ -739,19 +726,20 @@ class ChessRules } } - if (this.atLeastOneMove(color)) + if (this.atLeastOneMove()) { // game not over return "*"; } // Game over - return this.checkGameEnd(color); + return this.checkGameEnd(); } - // Useful stand-alone for engine - checkGameEnd(color) + // No moves are possible: compute score + checkGameEnd() { + const color = this.turn; // No valid move: stalemate or checkmate? if (!this.isAttacked(this.kingPos[color], this.getOppCol(color))) return "1/2"; @@ -775,12 +763,12 @@ class ChessRules } // Assumption: at least one legal move - getComputerMove(color) + getComputerMove() { - const oppCol = this.getOppCol(color); + const color = this.turn; // Rank moves using a min-max at depth 2 - let moves1 = this.getAllValidMoves(color); + let moves1 = this.getAllValidMoves(); for (let i=0; i { return (color=="w" ? 1 : -1) * (b.eval - a.eval); }); @@ -825,11 +813,12 @@ class ChessRules return moves1[_.sample(candidates, 1)]; } - alphabeta(color, oppCol, depth, alpha, beta) + alphabeta(depth, alpha, beta) { - if (!this.atLeastOneMove(color)) + const color = this.turn; + if (!this.atLeastOneMove()) { - switch (this.checkGameEnd(color)) + switch (this.checkGameEnd()) { case "1/2": return 0; default: return color=="w" ? -1000 : 1000; @@ -837,14 +826,14 @@ class ChessRules } if (depth == 0) return this.evalPosition(); - const moves = this.getAllValidMoves(color); + const moves = this.getAllValidMoves(); let v = color=="w" ? -1000 : 1000; if (color == "w") { for (let i=0; i= beta) @@ -856,7 +845,7 @@ class ChessRules for (let i=0; i= beta)