X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fbase_rules.js;h=ba77d7187538a7d98749c257c5ff10a39ab416c2;hb=6e62b1c7d177585003e923d423025dff280a7525;hp=0bf5114aca6f5d3dd1ae6e51879abab428ca9930;hpb=f6dbe8e31a3260487664f1e0b50710b3f3efaf5f;p=vchess.git diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js index 0bf5114a..ba77d718 100644 --- a/public/javascripts/base_rules.js +++ b/public/javascripts/base_rules.js @@ -64,22 +64,16 @@ class ChessRules if (!V.IsGoodPosition(fenParsed.position)) return false; // 2) Check turn - if (!fenParsed.turn || !["w","b"].includes(fenParsed.turn)) + if (!fenParsed.turn || !V.IsGoodTurn(fenParsed.turn)) return false; // 3) Check flags if (V.HasFlags && (!fenParsed.flags || !V.IsGoodFlags(fenParsed.flags))) return false; // 4) Check enpassant - if (V.HasEnpassant) + if (V.HasEnpassant && + (!fenParsed.enpassant || !V.IsGoodEnpassant(fenParsed.enpassant))) { - if (!fenParsed.enpassant) - return false; - if (fenParsed.enpassant != "-") - { - const ep = V.SquareToCoords(fenParsed.enpassant); - if (ep.y < 0 || ep.y > V.size.y || isNaN(ep.x) || ep.x < 0 || ep.x > V.size.x) - return false; - } + return false; } return true; } @@ -113,14 +107,37 @@ class ChessRules return true; } + // For FEN checking + static IsGoodTurn(turn) + { + return ["w","b"].includes(turn); + } + // For FEN checking static IsGoodFlags(flags) { return !!flags.match(/^[01]{4,4}$/); } - // 3 --> d (column letter from number) - static GetColumn(colnum) + static IsGoodEnpassant(enpassant) + { + if (enpassant != "-") + { + const ep = V.SquareToCoords(fenParsed.enpassant); + if (isNaN(ep.x) || !V.OnBoard(ep)) + return false; + } + return true; + } + + // 3 --> d (column number to letter) + static CoordToColumn(colnum) + { + return String.fromCharCode(97 + colnum); + } + + // d --> 3 (column letter to number) + static ColumnToCoord(colnum) { return String.fromCharCode(97 + colnum); } @@ -129,6 +146,8 @@ class ChessRules static SquareToCoords(sq) { return { + // NOTE: column is always one char => max 26 columns + // row is counted from black side => subtraction x: V.size.x - parseInt(sq.substr(1)), y: sq[0].charCodeAt() - 97 }; @@ -137,7 +156,7 @@ class ChessRules // {x:0,y:4} --> e8 static CoordsToSquare(coords) { - return V.GetColumn(coords.y) + (V.size.x - coords.x); + return V.CoordToColumn(coords.y) + (V.size.x - coords.x); } // Aggregates flags into one object @@ -217,31 +236,32 @@ class ChessRules // Get random squares for bishops let randIndex = 2 * _.random(3); - let bishop1Pos = positions[randIndex]; + const bishop1Pos = positions[randIndex]; // The second bishop must be on a square of different color let randIndex_tmp = 2 * _.random(3) + 1; - let bishop2Pos = positions[randIndex_tmp]; + const bishop2Pos = positions[randIndex_tmp]; // Remove chosen squares positions.splice(Math.max(randIndex,randIndex_tmp), 1); positions.splice(Math.min(randIndex,randIndex_tmp), 1); // Get random squares for knights randIndex = _.random(5); - let knight1Pos = positions[randIndex]; + const knight1Pos = positions[randIndex]; positions.splice(randIndex, 1); randIndex = _.random(4); - let knight2Pos = positions[randIndex]; + const knight2Pos = positions[randIndex]; positions.splice(randIndex, 1); // Get random square for queen randIndex = _.random(3); - let queenPos = positions[randIndex]; + const queenPos = positions[randIndex]; positions.splice(randIndex, 1); - // Rooks and king positions are now fixed, because of the ordering rook-king-rook - let rook1Pos = positions[0]; - let kingPos = positions[1]; - let rook2Pos = positions[2]; + // Rooks and king positions are now fixed, + // because of the ordering rook-king-rook + const rook1Pos = positions[0]; + const kingPos = positions[1]; + const rook2Pos = positions[2]; // Finally put the shuffled pieces in the board array pieces[c][rook1Pos] = 'r'; @@ -279,7 +299,7 @@ class ChessRules // Return current fen (game state) getFen() { - return this.getBaseFen() + " " + this.turn + + return this.getBaseFen() + " " + this.getTurnFen() + (V.HasFlags ? (" " + this.getFlagsFen()) : "") + (V.HasEnpassant ? (" " + this.getEnpassantFen()) : ""); } @@ -317,6 +337,11 @@ class ChessRules return position; } + getTurnFen() + { + return this.turn; + } + // Flags part of the FEN string getFlagsFen() { @@ -380,7 +405,7 @@ class ChessRules this.moves = moves; const fenParsed = V.ParseFen(fen); this.board = V.GetBoard(fenParsed.position); - this.turn = (fenParsed.turn || "w"); + this.turn = fenParsed.turn[0]; //[0] to work with MarseilleRules this.setOtherVariables(fen); } @@ -528,7 +553,8 @@ class ChessRules } } - // Build a regular move from its initial and destination squares; tr: transformation + // Build a regular move from its initial and destination squares. + // tr: transformation getBasicMove([sx,sy], [ex,ey], tr) { let mv = new Move({ @@ -565,7 +591,8 @@ class ChessRules return mv; } - // Generic method to find possible moves of non-pawn pieces ("sliding or jumping") + // Generic method to find possible moves of non-pawn pieces: + // "sliding or jumping" getSlideNJumpMoves([x,y], steps, oneStep) { const color = this.getColor(x,y); @@ -680,7 +707,8 @@ class ChessRules // What are the queen moves from square x,y ? getPotentialQueenMoves(sq) { - return this.getSlideNJumpMoves(sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP])); + return this.getSlideNJumpMoves(sq, + V.steps[V.ROOK].concat(V.steps[V.BISHOP])); } // What are the king moves from square x,y ? @@ -710,13 +738,15 @@ class ChessRules continue; // If this code is reached, rooks and king are on initial position - // Nothing on the path of the king (and no checks; OK also if y==finalSquare)? + // Nothing on the path of the king ? + // (And no checks; OK also if y==finalSquare) 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 && // NOTE: next check is enough, because of chessboard constraints - (this.getColor(x,i) != c || ![V.KING,V.ROOK].includes(this.getPiece(x,i))))) + (this.getColor(x,i) != c + || ![V.KING,V.ROOK].includes(this.getPiece(x,i))))) { continue castlingCheck; } @@ -782,7 +812,8 @@ class ChessRules }); } - // Search for all valid moves considering current turn (for engine and game end) + // Search for all valid moves considering current turn + // (for engine and game end) getAllValidMoves() { const color = this.turn; @@ -792,13 +823,14 @@ class ChessRules { for (let j=0; j eval2)) + if ((color == "w" && evalPos < eval2) + || (color=="b" && evalPos > eval2)) + { eval2 = evalPos; + } this.undo(moves2[j]); } } @@ -1187,7 +1227,8 @@ class ChessRules this.alphabeta(V.SEARCH_DEPTH-1, -maxeval, maxeval); this.undo(moves1[i]); } - moves1.sort( (a,b) => { return (color=="w" ? 1 : -1) * (b.eval - a.eval); }); + moves1.sort( (a,b) => { + return (color=="w" ? 1 : -1) * (b.eval - a.eval); }); } else return currentBest; @@ -1284,12 +1325,12 @@ class ChessRules if (move.vanish.length > move.appear.length) { // Capture - const startColumn = String.fromCharCode(97 + move.start.y); + const startColumn = V.CoordToColumn(move.start.y); notation = startColumn + "x" + finalSquare; } else //no capture notation = finalSquare; - if (move.appear.length > 0 && piece != move.appear[0].p) //promotion + if (move.appear.length > 0 && move.appear[0].p != V.PAWN) //promotion notation += "=" + move.appear[0].p.toUpperCase(); return notation; }