X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fbase_rules.js;h=f1188ab5b1c544ca14b6d17c64d9e1a3ded05f8a;hb=a6abf094c35a26019e47fea21302c4be32ff030b;hp=f466624d653ebc5ec50e46036c7c3785ecb4b82d;hpb=a37076f1ac8f4c19d9b34a60cbe89df86b88fa0b;p=vchess.git diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js index f466624d..f1188ab5 100644 --- a/public/javascripts/base_rules.js +++ b/public/javascripts/base_rules.js @@ -284,7 +284,7 @@ class ChessRules i += step[0]; j += step[1]; } - if (i>=0 && i<8 && j>=0 && j<8 && this.canTake([x,y], [i,j])) + if (i>=0 && i=0 && j= 0 && x+shift < sizeX && x+shift != lastRank) { @@ -395,7 +395,8 @@ class ChessRules getCastleMoves([x,y]) { const c = this.getColor(x,y); - if (x != (c=="w" ? 7 : 0) || y != this.INIT_COL_KING[c]) + const [sizeX,sizeY] = VariantRules.size; + if (x != (c=="w" ? sizeX-1 : 0) || y != this.INIT_COL_KING[c]) return []; //x isn't first rank, or king has moved (shortcut) const V = VariantRules; @@ -404,7 +405,7 @@ class ChessRules const oppCol = this.getOppCol(c); let moves = []; let i = 0; - const finalSquares = [ [2,3], [6,5] ]; //king, then rook + const finalSquares = [ [2,3], [sizeY-2,sizeY-3] ]; //king, then rook castlingCheck: for (let castleSide=0; castleSide < 2; castleSide++) //large, then small { @@ -416,7 +417,7 @@ class ChessRules let step = finalSquares[castleSide][0] < y ? -1 : 1; for (i=y; i!=finalSquares[castleSide][0]; i+=step) { - if (this.isAttacked([x,i], oppCol) || (this.board[x][i] != V.EMPTY && + if (this.isAttacked([x,i], [oppCol]) || (this.board[x][i] != V.EMPTY && // NOTE: next check is enough, because of chessboard constraints (this.getColor(x,i) != c || ![V.KING,V.ROOK].includes(this.getPiece(x,i))))) { @@ -489,11 +490,11 @@ class ChessRules { const color = this.turn; const oppCol = this.getOppCol(color); - var potentialMoves = []; - let [sizeX,sizeY] = VariantRules.size; - for (var i=0; i=0 && x+pawnShift<8) + if (x+pawnShift>=0 && x+pawnShift=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN + if (y+i>=0 && y+i=0 && rx<8 && ry>=0 && ry<8 && this.board[rx][ry] == VariantRules.EMPTY - && !oneStep) + while (rx>=0 && rx=0 && ry=0 && rx<8 && ry>=0 && ry<8 && this.board[rx][ry] != VariantRules.EMPTY + if (rx>=0 && rx=0 && ry 0) @@ -677,7 +682,7 @@ class ChessRules return; } const oppCol = this.getOppCol(c); - const oppFirstRank = 7 - firstRank; + const oppFirstRank = (sizeX-1) - firstRank; if (move.start.x == firstRank //our rook moves? && this.INIT_COL_ROOK[c].includes(move.start.y)) { @@ -768,7 +773,7 @@ class ChessRules { const color = this.turn; // No valid move: stalemate or checkmate? - if (!this.isAttacked(this.kingPos[color], this.getOppCol(color))) + if (!this.isAttacked(this.kingPos[color], [this.getOppCol(color)])) return "1/2"; // OK, checkmate return color == "w" ? "0-1" : "1-0"; @@ -798,13 +803,28 @@ class ChessRules return VariantRules.INFINITY; } + static get SEARCH_DEPTH() { + return 3; //2 for high branching factor, 4 for small (Loser chess) + } + // Assumption: at least one legal move - getComputerMove(moves1) //moves1 might be precomputed (Magnetic chess) + // NOTE: works also for extinction chess because depth is 3... + getComputerMove() { + this.shouldReturn = false; const maxeval = VariantRules.INFINITY; const color = this.turn; - if (!moves1) - moves1 = this.getAllValidMoves(); + let moves1 = this.getAllValidMoves(); + + // Can I mate in 1 ? (for Magnetic & Extinction) + for (let i of _.shuffle(_.range(moves1.length))) + { + this.play(moves1[i]); + const finish = (Math.abs(this.evalPosition()) >= VariantRules.THRESHOLD_MATE); + this.undo(moves1[i]); + if (finish) + return moves1[i]; + } // Rank moves using a min-max at depth 2 for (let i=0; i { return (color=="w" ? 1 : -1) * (b.eval - a.eval); }); - // Skip depth 3 if we found a checkmate (or if we are checkmated in 1...) - if (Math.abs(moves1[0].eval) < VariantRules.THRESHOLD_MATE) + let candidates = [0]; //indices of candidates moves + for (let j=1; j= 3 + && Math.abs(moves1[0].eval) < VariantRules.THRESHOLD_MATE) { - // TODO: show current analyzed move for depth 3, allow stopping eval (return moves1[0]) for (let i=0; i { return (color=="w" ? 1 : -1) * (b.eval - a.eval); }); } + else + return currentBest; - let candidates = [0]; //indices of candidates moves + candidates = [0]; for (let j=1; j { return [this.getNotation(m), m.eval]; })); @@ -900,7 +930,7 @@ class ChessRules { const [sizeX,sizeY] = VariantRules.size; let evaluation = 0; - //Just count material for now + // Just count material for now for (let i=0; i