X-Git-Url: https://git.auder.net/?p=vchess.git;a=blobdiff_plain;f=public%2Fjavascripts%2Fbase_rules.js;h=e405cbaa4e595da56210f09a7e0920c27c406be1;hp=891948b91dddcb1aab0a895d7fcb2f21c49494c8;hb=b6487fb9c41705187cf97215fc9e8f86a59057c7;hpb=5915f72002ae63b04620cebe47adf778174b1bee diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js index 891948b9..e405cbaa 100644 --- a/public/javascripts/base_rules.js +++ b/public/javascripts/base_rules.js @@ -66,10 +66,13 @@ class ChessRules // 2) Check turn if (!fenParsed.turn || !V.IsGoodTurn(fenParsed.turn)) return false; - // 3) Check flags + // 3) Check moves count + if (!fenParsed.movesCount || !(parseInt(fenParsed.movesCount) >= 0)) + return false; + // 4) Check flags if (V.HasFlags && (!fenParsed.flags || !V.IsGoodFlags(fenParsed.flags))) return false; - // 4) Check enpassant + // 5) Check enpassant if (V.HasEnpassant && (!fenParsed.enpassant || !V.IsGoodEnpassant(fenParsed.enpassant))) { @@ -186,7 +189,8 @@ class ChessRules // Argument is a move: const move = moveOrSquare; const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x]; - if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) == 2) + // TODO: next conditions are first for Atomic, and third for Checkered + if (move.appear.length > 0 && move.appear[0].p == V.PAWN && ["w","b"].includes(move.appear[0].c) && Math.abs(sx - ex) == 2) { return { x: (sx + ex)/2, @@ -287,8 +291,9 @@ class ChessRules { position: fenParts[0], turn: fenParts[1], + movesCount: fenParts[2], }; - let nextIdx = 2; + let nextIdx = 3; if (V.HasFlags) Object.assign(res, {flags: fenParts[nextIdx++]}); if (V.HasEnpassant) @@ -299,7 +304,8 @@ class ChessRules // Return current fen (game state) getFen() { - return this.getBaseFen() + " " + this.getTurnFen() + + return this.getBaseFen() + " " + + this.getTurnFen() + " " + this.movesCount + (V.HasFlags ? (" " + this.getFlagsFen()) : "") + (V.HasEnpassant ? (" " + this.getEnpassantFen()) : ""); } @@ -400,12 +406,12 @@ class ChessRules // INITIALIZATION // Fen string fully describes the game state - constructor(fen, moves) + constructor(fen) { - this.moves = moves; const fenParsed = V.ParseFen(fen); this.board = V.GetBoard(fenParsed.position); this.turn = fenParsed.turn[0]; //[0] to work with MarseilleRules + this.movesCount = parseInt(fenParsed.movesCount); this.setOtherVariables(fen); } @@ -497,12 +503,6 @@ class ChessRules return (color=="w" ? "b" : "w"); } - get lastMove() - { - const L = this.moves.length; - return (L>0 ? this.moves[L-1] : null); - } - // Pieces codes (for a clearer code) static get PAWN() { return 'p'; } static get ROOK() { return 'r'; } @@ -628,7 +628,8 @@ class ChessRules const lastRank = (color == "w" ? 0 : sizeX-1); const pawnColor = this.getColor(x,y); //can be different for checkered - if (x+shiftX >= 0 && x+shiftX < sizeX) //TODO: always true + // NOTE: next condition is generally true (no pawn on last rank) + if (x+shiftX >= 0 && x+shiftX < sizeX) { const finalPieces = x + shiftX == lastRank ? [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN] @@ -1001,22 +1002,27 @@ class ChessRules { this.kingPos[c][0] = move.appear[0].x; this.kingPos[c][1] = move.appear[0].y; - this.castleFlags[c] = [false,false]; + if (V.HasFlags) + this.castleFlags[c] = [false,false]; return; } - const oppCol = this.getOppCol(c); - const oppFirstRank = (V.size.x-1) - firstRank; - if (move.start.x == firstRank //our rook moves? - && this.INIT_COL_ROOK[c].includes(move.start.y)) - { - const flagIdx = (move.start.y == this.INIT_COL_ROOK[c][0] ? 0 : 1); - this.castleFlags[c][flagIdx] = false; - } - else if (move.end.x == oppFirstRank //we took opponent rook? - && this.INIT_COL_ROOK[oppCol].includes(move.end.y)) + if (V.HasFlags) { - const flagIdx = (move.end.y == this.INIT_COL_ROOK[oppCol][0] ? 0 : 1); - this.castleFlags[oppCol][flagIdx] = false; + // Update castling flags if rooks are moved + const oppCol = this.getOppCol(c); + const oppFirstRank = (V.size.x-1) - firstRank; + if (move.start.x == firstRank //our rook moves? + && this.INIT_COL_ROOK[c].includes(move.start.y)) + { + const flagIdx = (move.start.y == this.INIT_COL_ROOK[c][0] ? 0 : 1); + this.castleFlags[c][flagIdx] = false; + } + else if (move.end.x == oppFirstRank //we took opponent rook? + && this.INIT_COL_ROOK[oppCol].includes(move.end.y)) + { + const flagIdx = (move.end.y == this.INIT_COL_ROOK[oppCol][0] ? 0 : 1); + this.castleFlags[oppCol][flagIdx] = false; + } } } @@ -1037,7 +1043,7 @@ class ChessRules // if (!ingame) this.states.push(this.getFen()); if (!!ingame) - move.notation = [this.getNotation(move), this.getLongNotation(move)]; + move.notation = this.getNotation(move); if (V.HasFlags) move.flags = JSON.stringify(this.aggregateFlags()); //save flags (for undo) @@ -1045,7 +1051,7 @@ class ChessRules this.epSquares.push( this.getEpSquare(move) ); V.PlayOnBoard(this.board, move); this.turn = this.getOppCol(this.turn); - this.moves.push(move); + this.movesCount++; this.updateVariables(move); if (!!ingame) @@ -1063,7 +1069,7 @@ class ChessRules this.disaggregateFlags(JSON.parse(move.flags)); V.UndoOnBoard(this.board, move); this.turn = this.getOppCol(this.turn); - this.moves.pop(); + this.movesCount--; this.unupdateVariables(move); // DEBUG: @@ -1075,32 +1081,9 @@ class ChessRules /////////////// // END OF GAME - // Check for 3 repetitions (position + flags + turn) - checkRepetition() - { - if (!this.hashStates) - this.hashStates = {}; - const startIndex = - Object.values(this.hashStates).reduce((a,b) => { return a+b; }, 0) - // Update this.hashStates with last move (or all moves if continuation) - // NOTE: redundant storage, but faster and moderate size - for (let i=startIndex; i { return (elt >= 3); }); - } - // Is game over ? And if yes, what is the score ? checkGameOver() { - if (this.checkRepetition()) - return "1/2"; - if (this.atLeastOneMove()) // game not over return "*"; @@ -1244,7 +1227,7 @@ class ChessRules } else return currentBest; - //console.log(moves1.map(m => { return [this.getNotation(m), m.eval]; })); +// console.log(moves1.map(m => { return [this.getNotation(m), m.eval]; })); candidates = [0]; for (let j=1; j'; - pgn += '[Date "' + getDate(new Date()) + '"]
'; - pgn += '[White "' + (mycolor=='w'?'Myself':opponent) + '"]
'; - pgn += '[Black "' + (mycolor=='b'?'Myself':opponent) + '"]
'; - pgn += '[FenStart "' + fenStart + '"]
'; - pgn += '[Fen "' + this.getFen() + '"]
'; - pgn += '[Result "' + score + '"]

'; - - // Standard PGN - for (let i=0; i