X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fbase_rules.js;h=d1348e71927b6bdf410659395bd5e3715f1f5372;hb=2c5d7b20742b802d9c47916915c1114bcfc9a9c3;hp=f9574004f5973f2e6cef6911a392b04754c9085d;hpb=6f2f94374f1e73c375edf732d9425e575e81fff7;p=vchess.git diff --git a/client/src/base_rules.js b/client/src/base_rules.js index f9574004..d1348e71 100644 --- a/client/src/base_rules.js +++ b/client/src/base_rules.js @@ -27,7 +27,8 @@ export const Move = class Move { } }; -// NOTE: x coords = top to bottom; y = left to right (from white player perspective) +// NOTE: x coords = top to bottom; y = left to right +// (from white player perspective) export const ChessRules = class ChessRules { ////////////// // MISC UTILS @@ -191,14 +192,14 @@ export const ChessRules = class ChessRules { return V.CoordToColumn(coords.y) + (V.size.x - coords.x); } - // Path to pieces + // Path to pieces (standard ones in pieces/ folder) getPpath(b) { - return b; //usual pieces in pieces/ folder + return b; } // Path to promotion pieces (usually the same) - getPPpath(b) { - return this.getPpath(b); + getPPpath(m) { + return this.getPpath(m.appear[0].c + m.appear[0].p); } // Aggregates flags into one object @@ -224,9 +225,11 @@ export const ChessRules = class ChessRules { const s = move.start, e = move.end; if ( - Math.abs(s.x - e.x) == 2 && s.y == e.y && - move.appear[0].p == V.PAWN + Math.abs(s.x - e.x) == 2 && + // Next conditions for variants like Atomic or Rifle, Recycle... + (move.appear.length > 0 && move.appear[0].p == V.PAWN) && + (move.vanish.length > 0 && move.vanish[0].p == V.PAWN) ) { return { x: (s.x + e.x) / 2, @@ -255,7 +258,8 @@ export const ChessRules = class ChessRules { getCheckSquares(color) { return ( this.underCheck(color) - ? [JSON.parse(JSON.stringify(this.kingPos[color]))] //need to duplicate! + // kingPos must be duplicated, because it may change: + ? [JSON.parse(JSON.stringify(this.kingPos[color]))] : [] ); } @@ -464,7 +468,8 @@ export const ChessRules = class ChessRules { // Scan board for kings positions scanKings(fen) { this.INIT_COL_KING = { w: -1, b: -1 }; - this.kingPos = { w: [-1, -1], b: [-1, -1] }; //squares of white and black king + // Squares of white and black king: + this.kingPos = { w: [-1, -1], b: [-1, -1] }; const fenRows = V.ParseFen(fen).position.split("/"); const startRow = { 'w': V.size.x - 1, 'b': 0 }; for (let i = 0; i < fenRows.length; i++) { @@ -679,6 +684,7 @@ export const ChessRules = class ChessRules { enpassantMove.vanish.push({ x: x, y: epSquare.y, + // Captured piece is usually a pawn, but next line seems harmless p: this.getPiece(x, epSquare.y), c: this.getColor(x, epSquare.y) }); @@ -838,7 +844,7 @@ export const ChessRules = class ChessRules { if (this.castleFlags[c][castleSide] >= V.size.y) continue; // If this code is reached, rook and king are on initial position - // NOTE: in some variants this is not a rook, but let's keep variable name + // NOTE: in some variants this is not a rook const rookPos = this.castleFlags[c][castleSide]; const castlingPiece = this.getPiece(x, rookPos); if (this.getColor(x, rookPos) != c) @@ -883,8 +889,18 @@ export const ChessRules = class ChessRules { moves.push( new Move({ appear: [ - new PiPo({ x: x, y: finalSquares[castleSide][0], p: V.KING, c: c }), - new PiPo({ x: x, y: finalSquares[castleSide][1], p: castlingPiece, c: c }) + new PiPo({ + x: x, + y: finalSquares[castleSide][0], + p: V.KING, + c: c + }), + new PiPo({ + x: x, + y: finalSquares[castleSide][1], + p: castlingPiece, + c: c + }) ], vanish: [ new PiPo({ x: x, y: y, p: V.KING, c: c }), @@ -940,6 +956,7 @@ export const ChessRules = class ChessRules { } // Stop at the first move found + // TODO: not really, it explores all moves from a square (one is enough). atLeastOneMove() { const color = this.turn; for (let i = 0; i < V.size.x; i++) { @@ -1078,7 +1095,8 @@ export const ChessRules = class ChessRules { // this.states.push(stateFen); this.prePlay(move); - if (V.HasFlags) move.flags = JSON.stringify(this.aggregateFlags()); //save flags (for undo) + // Save flags (for undo) + if (V.HasFlags) move.flags = JSON.stringify(this.aggregateFlags()); if (V.HasEnpassant) this.epSquares.push(this.getEpSquare(move)); V.PlayOnBoard(this.board, move); this.turn = V.GetOppCol(this.turn); @@ -1090,7 +1108,7 @@ export const ChessRules = class ChessRules { const c = V.GetOppCol(this.turn); const firstRank = (c == "w" ? V.size.x - 1 : 0); // Update castling flags if rooks are moved - const oppCol = V.GetOppCol(c); + const oppCol = this.turn; const oppFirstRank = V.size.x - 1 - firstRank; if (piece == V.KING && move.appear.length > 0) this.castleFlags[c] = [V.size.y, V.size.y]; @@ -1100,7 +1118,9 @@ export const ChessRules = class ChessRules { ) { const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1); this.castleFlags[c][flagIdx] = V.size.y; - } else if ( + } + // NOTE: not "else if" because a rook could take an opposing rook + if ( move.end.x == oppFirstRank && //we took opponent rook? this.castleFlags[oppCol].includes(move.end.y) ) { @@ -1194,7 +1214,7 @@ export const ChessRules = class ChessRules { return V.INFINITY; } - // Search depth: 1,2 for high branching factor, 4 for small (Loser chess, eg.) + // Search depth: 1,2 for e.g. higher branching factor, 4 for smaller static get SEARCH_DEPTH() { return 3; } @@ -1281,8 +1301,8 @@ export const ChessRules = class ChessRules { } let candidates = [0]; - for (let j = 1; j < moves1.length && moves1[j].eval == moves1[0].eval; j++) - candidates.push(j); + for (let i = 1; i < moves1.length && moves1[i].eval == moves1[0].eval; i++) + candidates.push(i); return moves1[candidates[randInt(candidates.length)]]; } @@ -1367,4 +1387,28 @@ export const ChessRules = class ChessRules { finalSquare ); } + + static GetUnambiguousNotation(move) { + // Machine-readable format with all the informations about the move + return ( + (!!move.start && V.OnBoard(move.start.x, move.start.y) + ? V.CoordsToSquare(move.start) + : "-" + ) + "." + + (!!move.end && V.OnBoard(move.end.x, move.end.y) + ? V.CoordsToSquare(move.end) + : "-" + ) + " " + + (!!move.appear && move.appear.length > 0 + ? move.appear.map(a => + a.c + a.p + V.CoordsToSquare({ x: a.x, y: a.y })).join(".") + : "-" + ) + "/" + + (!!move.vanish && move.vanish.length > 0 + ? move.vanish.map(a => + a.c + a.p + V.CoordsToSquare({ x: a.x, y: a.y })).join(".") + : "-" + ) + ); + } };