X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fvariants%2FProgressive.js;fp=client%2Fsrc%2Fvariants%2FProgressive.js;h=67654286f1b1028c3feb710d976c9225bc017b57;hb=737a5dafb39740ebe304b8d0a82df85070def571;hp=0000000000000000000000000000000000000000;hpb=1b56b73614509d1dca8c4353f18fb78349940cf8;p=vchess.git diff --git a/client/src/variants/Progressive.js b/client/src/variants/Progressive.js new file mode 100644 index 00000000..67654286 --- /dev/null +++ b/client/src/variants/Progressive.js @@ -0,0 +1,111 @@ +import { ChessRules } from "@/base_rules"; +import { randInt } from "@/utils/alea"; + +export class ProgressiveRules extends ChessRules { + static get HasEnpassant() { + return false; + } + + setOtherVariables(fen) { + super.setOtherVariables(fen); + this.subTurn = 1; + } + + filterValid(moves) { + if (moves.length == 0) return []; + const color = this.turn; + return moves.filter(m => { + // Not using this.play() (would result ininfinite recursive calls) + V.PlayOnBoard(this.board, m); + if (m.appear[0].p == V.KING) + this.kingPos[color] = [m.appear[0].x, m.appear[0].y]; + const res = !this.underCheck(color); + V.UndoOnBoard(this.board, m); + if (m.appear[0].p == V.KING) + this.kingPos[color] = [m.vanish[0].x, m.vanish[0].y]; + return res; + }); + } + + play(move) { + move.flags = JSON.stringify(this.aggregateFlags()); + const color = this.turn; + const oppCol = V.GetOppCol(color); + move.turn = [color, this.subTurn]; + V.PlayOnBoard(this.board, move); + if ( + this.subTurn > this.movesCount || + this.underCheck(oppCol) || + !this.atLeastOneMove() + ) { + this.turn = oppCol; + this.subTurn = 1; + this.movesCount++; + } + else this.subTurn++; + this.postPlay(move); + } + + postPlay(move) { + const c = move.turn[0]; + const piece = move.vanish[0].p; + const firstRank = c == "w" ? V.size.x - 1 : 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; + this.castleFlags[c] = [V.size.y, V.size.y]; + return; + } + const oppCol = V.GetOppCol(c); + const oppFirstRank = V.size.x - 1 - firstRank; + if ( + move.start.x == firstRank && //our rook moves? + this.castleFlags[c].includes(move.start.y) + ) { + const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1); + this.castleFlags[c][flagIdx] = V.size.y; + } + if ( + move.end.x == oppFirstRank && //we took opponent rook? + this.castleFlags[oppCol].includes(move.end.y) + ) { + const flagIdx = (move.end.y == this.castleFlags[oppCol][0] ? 0 : 1); + this.castleFlags[oppCol][flagIdx] = V.size.y; + } + } + + undo(move) { + this.disaggregateFlags(JSON.parse(move.flags)); + V.UndoOnBoard(this.board, move); + if (this.turn != move.turn[0]) this.movesCount--; + this.turn = move.turn[0]; + this.subTurn = move.turn[1]; + super.postUndo(move); + } + + static get VALUES() { + return { + p: 1, + r: 5, + n: 3, + b: 3, + q: 7, //slightly less than in orthodox game + k: 1000 + }; + } + + // Random moves (too high branching factor otherwise). TODO + getComputerMove() { + let res = []; + const color = this.turn; + while (this.turn == color) { + const moves = this.getAllValidMoves(); + const m = moves[randInt(moves.length)]; + res.push(m); + this.play(m); + } + for (let i=res.length - 1; i>= 0; i--) this.undo(res[i]); + return res; + } +};