X-Git-Url: https://git.auder.net/?p=vchess.git;a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FDark.js;h=358362c75ae2e6245a4e9486d1161e2424350e7d;hp=c0bfb09ca049876cd4dc25ee5dd3fd7c4aaa3b36;hb=6808d7a16ec1e761c6a2dffec2281c96953e4d89;hpb=ae2c49bb0bbaac3953f63be5b720e9c6835f00b6 diff --git a/client/src/variants/Dark.js b/client/src/variants/Dark.js index c0bfb09c..358362c7 100644 --- a/client/src/variants/Dark.js +++ b/client/src/variants/Dark.js @@ -1,52 +1,45 @@ import { ChessRules } from "@/base_rules"; -import { ArrayFun} from "@/utils/array"; +import { ArrayFun } from "@/utils/array"; import { randInt } from "@/utils/alea"; -export const VariantRules = class DarkRules extends ChessRules -{ +export const VariantRules = class DarkRules extends ChessRules { // Standard rules, in the shadow - setOtherVariables(fen) - { + setOtherVariables(fen) { super.setOtherVariables(fen); - const [sizeX,sizeY] = [V.size.x,V.size.y]; + const [sizeX, sizeY] = [V.size.x, V.size.y]; this.enlightened = { - "w": ArrayFun.init(sizeX,sizeY), - "b": ArrayFun.init(sizeX,sizeY) + w: ArrayFun.init(sizeX, sizeY), + b: ArrayFun.init(sizeX, sizeY) }; // Setup enlightened: squares reachable by each side // (TODO: one side would be enough ?) this.updateEnlightened(); } - updateEnlightened() - { - for (let i=0; i= 2 && move.vanish[1].p == V.KING) - { + if (move.vanish.length >= 2 && move.vanish[1].p == V.KING) { // We took opponent king ! (because if castle vanish[1] is a rook) - this.kingPos[this.turn] = [-1,-1]; + this.kingPos[this.turn] = [-1, -1]; } // Update lights for both colors: this.updateEnlightened(); } - unupdateVariables(move) - { + unupdateVariables(move) { super.unupdateVariables(move); const c = move.vanish[0].c; const oppCol = V.GetOppCol(c); - if (this.kingPos[oppCol][0] < 0) - { + if (this.kingPos[oppCol][0] < 0) { // Last move took opponent's king - for (let psq of move.vanish) - { - if (psq.p == 'k') - { + for (let psq of move.vanish) { + if (psq.p == "k") { this.kingPos[oppCol] = [psq.x, psq.y]; break; } @@ -134,96 +116,85 @@ export const VariantRules = class DarkRules extends ChessRules this.updateEnlightened(); } - getCurrentScore() - { + getCurrentScore() { const color = this.turn; const kp = this.kingPos[color]; - if (kp[0] < 0) //king disappeared - return (color == "w" ? "0-1" : "1-0"); - if (this.atLeastOneMove()) // game not over + if (kp[0] < 0) + //king disappeared + return color == "w" ? "0-1" : "1-0"; + if (this.atLeastOneMove()) + // game not over return "*"; return "1/2"; //no moves but kings still there (seems impossible) } - static get THRESHOLD_MATE() - { + static get THRESHOLD_MATE() { return 500; //checkmates evals may be slightly below 1000 } // In this special situation, we just look 1 half move ahead - getComputerMove() - { + getComputerMove() { const maxeval = V.INFINITY; const color = this.turn; const oppCol = V.GetOppCol(color); - const pawnShift = (color == "w" ? -1 : 1); + const pawnShift = color == "w" ? -1 : 1; // Do not cheat: the current enlightment is all we can see const myLight = JSON.parse(JSON.stringify(this.enlightened[color])); // Can a slider on (i,j) apparently take my king? // NOTE: inaccurate because assume yes if some squares are shadowed - const sliderTake = ([i,j], piece) => { + const sliderTake = ([i, j], piece) => { const kp = this.kingPos[color]; let step = undefined; - if (piece == V.BISHOP) - { - if (Math.abs(kp[0] - i) == Math.abs(kp[1] - j)) - { - step = - [ - (i-kp[0]) / Math.abs(i-kp[0]), - (j-kp[1]) / Math.abs(j-kp[1]) + if (piece == V.BISHOP) { + if (Math.abs(kp[0] - i) == Math.abs(kp[1] - j)) { + step = [ + (i - kp[0]) / Math.abs(i - kp[0]), + (j - kp[1]) / Math.abs(j - kp[1]) ]; } + } else if (piece == V.ROOK) { + if (kp[0] == i) step = [0, (j - kp[1]) / Math.abs(j - kp[1])]; + else if (kp[1] == j) step = [(i - kp[0]) / Math.abs(i - kp[0]), 0]; } - else if (piece == V.ROOK) - { - if (kp[0] == i) - step = [0, (j-kp[1]) / Math.abs(j-kp[1])]; - else if (kp[1] == j) - step = [(i-kp[0]) / Math.abs(i-kp[0]), 0]; - } - if (!step) - return false; + if (!step) return false; // Check for obstacles let obstacle = false; for ( - let x=kp[0]+step[0], y=kp[1]+step[1]; + let x = kp[0] + step[0], y = kp[1] + step[1]; x != i && y != j; - x += step[0], y += step[1]) - { - if (myLight[x][y] && this.board[x][y] != V.EMPTY) - { + x += step[0], y += step[1] + ) { + if (myLight[x][y] && this.board[x][y] != V.EMPTY) { obstacle = true; break; } } - if (!obstacle) - return true; + if (!obstacle) return true; return false; }; // Do I see something which can take my king ? const kingThreats = () => { const kp = this.kingPos[color]; - for (let i=0; i= 0 && kingThreats()) - { + if (this.kingPos[oppCol][0] >= 0 && kingThreats()) { // We didn't take opponent king, and our king will be captured: bad move.eval = -maxeval; } this.undo(move); - if (!!move.eval) - continue; + if (move.eval) continue; move.eval = 0; //a priori... // Can I take something ? If yes, do it if it seems good... - if (move.vanish.length == 2 && move.vanish[1].c != color) //avoid castle - { + if (move.vanish.length == 2 && move.vanish[1].c != color) { + //avoid castle const myPieceVal = V.VALUES[move.appear[0].p]; const hisPieceVal = V.VALUES[move.vanish[1].p]; - if (myPieceVal <= hisPieceVal) - move.eval = hisPieceVal - myPieceVal + 2; //favor captures - else - { + if (myPieceVal <= hisPieceVal) move.eval = hisPieceVal - myPieceVal + 2; + //favor captures + else { // Taking a pawn with minor piece, // or minor piece or pawn with a rook, // or anything but a queen with a queen, // or anything with a king. // ==> Do it at random, although // this is clearly inferior to what a human can deduce... - move.eval = (Math.random() < 0.5 ? 1 : -1); + move.eval = Math.random() < 0.5 ? 1 : -1; } } } @@ -289,10 +254,10 @@ export const VariantRules = class DarkRules extends ChessRules // TODO: also need to implement the case when an opponent piece (in light) // is threatening something - maybe not the king, but e.g. pawn takes rook. - moves.sort((a,b) => b.eval - a.eval); + moves.sort((a, b) => b.eval - a.eval); let candidates = [0]; - for (let j=1; j