X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fclient_OLD%2Fjavascripts%2Fvariants%2FDark.js;fp=client%2Fclient_OLD%2Fjavascripts%2Fvariants%2FDark.js;h=3879d9dfa8cc18a22d957e16f28064c8af4f216f;hb=625022fdcf750f0aff8fcd699f7e9b89730e1d10;hp=0000000000000000000000000000000000000000;hpb=b955c65b942d09d24b5c3bed0d755d4f2f8f71f1;p=vchess.git diff --git a/client/client_OLD/javascripts/variants/Dark.js b/client/client_OLD/javascripts/variants/Dark.js new file mode 100644 index 00000000..3879d9df --- /dev/null +++ b/client/client_OLD/javascripts/variants/Dark.js @@ -0,0 +1,287 @@ +class DarkRules extends ChessRules +{ + // Standard rules, in the shadow + setOtherVariables(fen) + { + super.setOtherVariables(fen); + const [sizeX,sizeY] = [V.size.x,V.size.y]; + this.enlightened = { + "w": doubleArray(sizeX,sizeY), + "b": doubleArray(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) + { + // We took opponent king ! + this.kingPos[this.turn] = [-1,-1]; + } + + // Update moves for both colors: + this.updateEnlightened(); + } + + unupdateVariables(move) + { + super.unupdateVariables(move); + const c = move.vanish[0].c; + const oppCol = V.GetOppCol(c); + if (this.kingPos[oppCol][0] < 0) + { + // Last move took opponent's king + for (let psq of move.vanish) + { + if (psq.p == 'k') + { + this.kingPos[oppCol] = [psq.x, psq.y]; + break; + } + } + } + + // Update moves for both colors: + this.updateEnlightened(); + } + + checkGameEnd() + { + // No valid move: our king disappeared + return this.turn == "w" ? "0-1" : "1-0"; + } + + 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() + { + const maxeval = V.INFINITY; + const color = this.turn; + const oppCol = V.GetOppCol(color); + const pawnShift = (color == "w" ? -1 : 1); + const kp = this.kingPos[color]; + + // 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) => { + 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]) + ]; + } + } + 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; + // Check for obstacles + let obstacle = false; + for ( + 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) + { + obstacle = true; + break; + } + } + if (!obstacle) + return true; + return false; + }; + + // Do I see something which can take my king ? + const kingThreats = () => { + for (let i=0; i= 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; + + 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 + { + 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 + { + // 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); + } + } + } + + // 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); + let candidates = [0]; + for (let j=1; j