From 4c3b39cb6c362c1db1f6d0a1f7aaf0b071d62fa7 Mon Sep 17 00:00:00 2001 From: Rushabh <145254552+Rushhaabhhh@users.noreply.github.com> Date: Mon, 23 Sep 2024 20:14:18 +0530 Subject: [PATCH 01/10] Implemented knight functionalities --- public/javascript/chess/pieces/knight.js | 36 ++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/public/javascript/chess/pieces/knight.js b/public/javascript/chess/pieces/knight.js index 3957e36..1f23ddf 100644 --- a/public/javascript/chess/pieces/knight.js +++ b/public/javascript/chess/pieces/knight.js @@ -3,9 +3,39 @@ var Knight = function(config){ this.constructor(config); }; +Knight.prototype = new Piece({}); +Knight.prototype.moveTo = function(targetPosition){ + var isValidMove = this.isValidMove(targetPosition); + if (!isValidMove) { + console.log("Invalid move for knight"); + return; + } + console.log("move function starts here"); + var newPos = targetPosition.col + targetPosition.row; + this.position = newPos; + this.render(); + console.log("move function successfully ends here"); +}; -Knight.prototype = new Piece({}); -Knight.prototype.move = function(newPosition){ +Knight.prototype.isValidMove = function(targetPosition) { + var currentRow = parseInt(this.position[1], 10); + var targetRow = parseInt(targetPosition.row, 10); + var currentCol = this.position[0].toUpperCase().charCodeAt(0) - 65; + var targetCol = targetPosition.col.toUpperCase().charCodeAt(0) - 65; -} \ No newline at end of file + console.log("currentRow: ", currentRow + " " + typeof currentRow); + console.log("targetRow: ", targetRow + " " + typeof targetRow); + console.log("currentCol: ", currentCol + " " + typeof currentCol); + console.log("targetCol: ", targetCol + " " + typeof targetCol); + + var rowDiff = Math.abs(targetRow - currentRow); + var colDiff = Math.abs(targetCol - currentCol); + + if ((rowDiff === 2 && colDiff === 1) || (rowDiff === 1 && colDiff === 2)) { + return true; + } else { + console.log("Invalid move: Knight must move in an L-shape"); + return false; + } +}; From 6755b8f343e44869c5f1a7df8bb4a1f56604eff5 Mon Sep 17 00:00:00 2001 From: Rushhaabhhh Date: Tue, 24 Sep 2024 23:15:45 +0530 Subject: [PATCH 02/10] Implement knight, toogle moves & kill --- public/css/chess.css | 122 +++++++----------- public/javascript/chess/board.js | 155 ++++++++++++----------- public/javascript/chess/piece.js | 33 ++++- public/javascript/chess/pieces/king.js | 12 +- public/javascript/chess/pieces/knight.js | 9 +- public/javascript/chess/pieces/pawn.js | 99 +++++++++++---- 6 files changed, 254 insertions(+), 176 deletions(-) diff --git a/public/css/chess.css b/public/css/chess.css index 6705394..2a86c74 100644 --- a/public/css/chess.css +++ b/public/css/chess.css @@ -1,106 +1,63 @@ #game-ct { - width: 400px; - height: 400px; + width: 400px; /* Retaining the board size */ + height: 400px; /* Retaining the board size */ margin: 20px auto; border: 2px solid #333; display: grid; grid-template-columns: repeat(8, 1fr); padding: 0; - } - #game-ct > li { + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); /* Add a slight shadow to the board */ +} + +#game-ct > li { list-style-type: none; padding: 0; - } - #game-ct > li > ul { +} + +#game-ct > li > ul { height: 100%; padding: 0; margin: 0; display: contents; - } - #game-ct li > ul > li { - width: 100%; - height: 50px; - list-style-type: none; - } - #game-ct li:nth-child(odd) li:nth-child(even), - #game-ct li:nth-child(even) li:nth-child(odd) { - background-color: #b58863; - } - #game-ct li:nth-child(even) li:nth-child(even), - #game-ct li:nth-child(odd) li:nth-child(odd) { - background-color: #f0d9b5; - } - - - -.piece { - background-image: url('/images/chess_sprite_transparent.png'); - background-repeat: no-repeat; - background-size: 600% 200%; -} - - -.white.king { - background-position: -9px 0; -} - -.black.king { - background-position: -9px -50px; } - -.white.queen { - background-position: -55px 0; -} - -.black.queen { - background-position: -55px -50px; -} - -.white.bishop { - background-position: -103px 0; -} - -.black.bishop { - background-position: -103px -50px; -} - -.white.knight { - background-position: -152px 0; -} - -.black.knight { - background-position: -152px -50px; -} - -.white.rook { - background-position: -198px 0; -} - -.black.rook { - background-position: -198px -50px; +#game-ct li > ul > li { + width: 100%; + height: 50px; /* Keeping the square size at 50px */ + list-style-type: none; } -.white.pawn { - background-position: -247px 0; +/* Checkerboard pattern */ +#game-ct li:nth-child(odd) li:nth-child(even), +#game-ct li:nth-child(even) li:nth-child(odd) { + background-color: #769656; /* Green color for dark squares */ } -.black.pawn { - background-position: -247px -50px; +#game-ct li:nth-child(even) li:nth-child(even), +#game-ct li:nth-child(odd) li:nth-child(odd) { + background-color: #eeeed2; /* Light beige color for light squares */ } +/* Piece styling */ .piece { + background-image: url('../images/chess_sprite_transparent.png'); /* Custom chess piece image */ + background-repeat: no-repeat; + background-size: 600% 200%; /* Adjusting sprite positions */ width: 100%; height: 100%; + transition: all 0.3s ease; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* Add shadow for a more 3D feel */ } +/* Highlight the selected piece with a green shadow */ .piece.selected { - box-shadow: 0 0 10px 3px rgba(0, 255, 0, 0.7); - transform: scale(1.1); + box-shadow: 0 0 10px 3px rgba(0, 255, 0, 0.7); /* Green glow for selection */ + transform: scale(1.1); /* Slightly larger size for selected piece */ transition: all 0.3s ease; z-index: 10; } +/* Highlight square of the selected piece with a green border */ .piece.selected::after { content: ''; position: absolute; @@ -110,7 +67,24 @@ bottom: -5px; border: 2px solid #00ff00; border-radius: 5px; - pointer-events: none; + pointer-events: none; /* This ensures clicks pass through the border */ } +/* Positions for chess pieces using sprite sheet */ +.white.king { background-position: -9px 0; } +.black.king { background-position: -9px -50px; } + +.white.queen { background-position: -55px 0; } +.black.queen { background-position: -55px -50px; } + +.white.bishop { background-position: -103px 0; } +.black.bishop { background-position: -103px -50px; } + +.white.knight { background-position: -152px 0; } +.black.knight { background-position: -152px -50px; } + +.white.rook { background-position: -198px 0; } +.black.rook { background-position: -198px -50px; } +.white.pawn { background-position: -247px 0; } +.black.pawn { background-position: -247px -50px; } diff --git a/public/javascript/chess/board.js b/public/javascript/chess/board.js index 3e54332..445e081 100644 --- a/public/javascript/chess/board.js +++ b/public/javascript/chess/board.js @@ -1,18 +1,21 @@ -var Board = function(config){ +var Board = function(config) { this.root_id = config.root_id; this.$el = document.getElementById(this.root_id); + this.currentTurn = 'white'; + this.selectedPiece = null; // Initialize selectedPiece this.generateBoardDom(); this.addListeners(); + this.initiateGame(); // Start the game } -Board.prototype.addListeners = function(){ +Board.prototype.addListeners = function() { this.$el.addEventListener('click', this.boardClicked.bind(this)); } -Board.prototype.generateBoardDom = function(config){ +Board.prototype.generateBoardDom = function() { let boardHTML = ''; - + this.$el.innerHTML = boardHTML; } -Board.prototype.getClickedBlock = function(clickEvent){ - // Get the clicked block - const clickedCell = clickEvent.target.closest('li'); +Board.prototype.getClickedBlock = function(clickEvent) { + const clickedCell = clickEvent.target.closest('li[data-row]'); if (clickedCell) { - // Extract row and column from data attributes const row = clickedCell.getAttribute('data-row'); const parentLi = clickedCell.closest('li[data-col]'); const col = parentLi ? parentLi.getAttribute('data-col') : null; if (row !== null && col !== null) { - return { - row: row, - col: col - }; + return { row: row, col: col }; } else { console.warn('Unable to determine block coordinates'); } @@ -49,30 +47,51 @@ Board.prototype.getClickedBlock = function(clickEvent){ } } -Board.prototype.clearSelection = function(){ - // Remove 'selected' class from all pieces +Board.prototype.clearSelection = function() { const allPieces = document.querySelectorAll('.piece'); allPieces.forEach(piece => { piece.classList.remove('selected'); }); + this.selectedPiece = null; // Reset selectedPiece }; -Board.prototype.boardClicked = function(event){ - this.clearSelection(); +Board.prototype.boardClicked = function(event) { const clickedCell = this.getClickedBlock(event); - const selectedPiece = this.getPieceAt(clickedCell) - if(selectedPiece){ - //Add 'selected' class to the clicked piece - this.selectPiece(event.target, selectedPiece); - }else{ - //update position of the selected piece to new position - if(this.selectedPiece){ - this.selectedPiece.moveTo(clickedCell); - } - } + if (!clickedCell) return; // Exit if click was not on a valid cell + + const piece = this.getPieceAt(clickedCell); + + if (this.selectedPiece) { // If a piece is already selected + if (piece) { + // If the selected piece is of the same color + if (piece.color === this.selectedPiece.color) { + console.log(`You selected your own piece. You can't select an opponent's piece.`); + return; + } else { + // Move selected piece to the clicked cell if it's a valid move + this.selectedPiece.moveTo(clickedCell); + this.clearSelection(); + this.switchTurn(); + } + } else { + // Move the selected piece to the new position if no piece is clicked + this.selectedPiece.moveTo(clickedCell); + this.clearSelection(); + this.switchTurn(); + } + } else { + if (piece) { + // Select the piece if it's the player's turn + if (piece.color === this.currentTurn) { + this.selectPiece(event.target, piece); + } else { + console.log(`It's ${this.currentTurn}'s turn! You cannot select an opponent's piece.`); + } + } + } } -Board.prototype.getPieceAt = function(cell){ +Board.prototype.getPieceAt = function(cell) { if (!cell || !cell.row || !cell.col) { return false; } @@ -81,103 +100,95 @@ Board.prototype.getPieceAt = function(cell){ // Check white pieces for (let pieceType in this.whitePieces) { - if (Array.isArray(this.whitePieces[pieceType])) { - // For arrays (pawns, bishops, knights, rooks) - for (let piece of this.whitePieces[pieceType]) { - if (piece.position === position) { - return piece; - } - } - } else { - // For single pieces (king, queen) - if (this.whitePieces[pieceType].position === position) { - return this.whitePieces[pieceType]; + const pieceArray = Array.isArray(this.whitePieces[pieceType]) ? this.whitePieces[pieceType] : [this.whitePieces[pieceType]]; + for (let piece of pieceArray) { + if (piece.position === position) { + return piece; } } } // Check black pieces for (let pieceType in this.blackPieces) { - if (Array.isArray(this.blackPieces[pieceType])) { - // For arrays (pawns, bishops, knights, rooks) - for (let piece of this.blackPieces[pieceType]) { - if (piece.position === position) { - return piece; - } - } - } else { - // For single pieces (king, queen) - if (this.blackPieces[pieceType].position === position) { - return this.blackPieces[pieceType]; + const pieceArray = Array.isArray(this.blackPieces[pieceType]) ? this.blackPieces[pieceType] : [this.blackPieces[pieceType]]; + for (let piece of pieceArray) { + if (piece.position === position) { + return piece; } } } return false; } +Board.prototype.switchTurn = function() { + this.currentTurn = this.currentTurn === 'white' ? 'black' : 'white'; + console.log(`It's now ${this.currentTurn}'s turn!`); +} + Board.prototype.selectPiece = function(clickedElement, selectedPiece) { if (clickedElement.classList.contains('piece')) { - // If the clicked element is a piece, add the 'selected' class clickedElement.classList.add('selected'); } else { - // If the clicked element is not a piece, check its parent const parentElement = clickedElement.closest('.piece'); if (parentElement) { parentElement.classList.add('selected'); } } selectedPiece.selected = true; - this.selectedPiece = selectedPiece; + this.selectedPiece = selectedPiece; // Set the selected piece } Board.prototype.initiateGame = function() { // Create white pieces this.whitePieces = { - king: new King({ color: 'white', position: 'E1' }), - queen: new Queen({ color: 'white', position: 'D1' }), + king: new King({ color: 'white', position: 'D1', board: this }), + queen: new Queen({ color: 'white', position: 'E1', board: this }), bishops: [ - new Bishop({ color: 'white', position: 'C1' }), - new Bishop({ color: 'white', position: 'F1' }) + new Bishop({ color: 'white', position: 'C1', board: this }), + new Bishop({ color: 'white', position: 'F1', board: this }) ], knights: [ - new Knight({ color: 'white', position: 'B1' }), - new Knight({ color: 'white', position: 'G1' }) + new Knight({ color: 'white', position: 'B1', board: this }), + new Knight({ color: 'white', position: 'G1', board: this }) ], rooks: [ - new Rook({ color: 'white', position: 'A1' }), - new Rook({ color: 'white', position: 'H1' }) + new Rook({ color: 'white', position: 'A1', board: this }), + new Rook({ color: 'white', position: 'H1', board: this }) ], pawns: [] }; // Create white pawns for (let i = 0; i < 8; i++) { - this.whitePieces.pawns.push(new Pawn({ color: 'white', position: String.fromCharCode(65 + i) + '2' })); + this.whitePieces.pawns.push(new Pawn({ color: 'white', position: String.fromCharCode(65 + i) + '2', board: this })); } // Create black pieces this.blackPieces = { - king: new King({ color: 'black', position: 'E8' }), - queen: new Queen({ color: 'black', position: 'D8' }), + king: new King({ color: 'black', position: 'D8', board: this }), + queen: new Queen({ color: 'black', position: 'E8', board: this }), bishops: [ - new Bishop({ color: 'black', position: 'C8' }), - new Bishop({ color: 'black', position: 'F8' }) + new Bishop({ color: 'black', position: 'C8', board: this }), + new Bishop({ color: 'black', position: 'F8', board: this }) ], knights: [ - new Knight({ color: 'black', position: 'B8' }), - new Knight({ color: 'black', position: 'G8' }) + new Knight({ color: 'black', position: 'B8', board: this }), + new Knight({ color: 'black', position: 'G8', board: this }) ], rooks: [ - new Rook({ color: 'black', position: 'A8' }), - new Rook({ color: 'black', position: 'H8' }) + new Rook({ color: 'black', position: 'A8', board: this }), + new Rook({ color: 'black', position: 'H8', board: this }) ], pawns: [] }; // Create black pawns for (let i = 0; i < 8; i++) { - this.blackPieces.pawns.push(new Pawn({ color: 'black', position: String.fromCharCode(65 + i) + '7' })); + this.blackPieces.pawns.push(new Pawn({ color: 'black', position: String.fromCharCode(65 + i) + '7', board: this })); } + + // Render all pieces after initiating the game + this.renderAllPieces(); }; Board.prototype.renderAllPieces = function() { diff --git a/public/javascript/chess/piece.js b/public/javascript/chess/piece.js index 05aceb0..acb9a2d 100644 --- a/public/javascript/chess/piece.js +++ b/public/javascript/chess/piece.js @@ -1,6 +1,8 @@ var Piece = function(config){ this.position = config.position; this.color = config.color; + this.board = config.board; + this.currentTurn = config.currentTurn; if(this.position){ this.render(); } @@ -42,6 +44,31 @@ Piece.prototype.render = function(){ } } -Piece.prototype.kill = function(targetPiece){ - console.log("Method not implemeted by: " + typeof(this)); -} \ No newline at end of file +Piece.prototype.kill = function(targetPiece) { + if (targetPiece) { + const targetPosition = targetPiece.position; + const targetElement = document.querySelector(`[data-col="${targetPosition[0]}"] [data-row="${targetPosition[1]}"]`); + targetElement.innerHTML = ''; // Remove the target piece from the board + + // Remove the target piece from the appropriate pieces object + if (targetPiece.color === 'white') { + for (let pieceType in this.board.whitePieces) { + const pieceArray = Array.isArray(this.board.whitePieces[pieceType]) ? this.board.whitePieces[pieceType] : [this.board.whitePieces[pieceType]]; + const index = pieceArray.indexOf(targetPiece); + if (index !== -1) { + pieceArray.splice(index, 1); + break; + } + } + } else { + for (let pieceType in this.board.blackPieces) { + const pieceArray = Array.isArray(this.board.blackPieces[pieceType]) ? this.board.blackPieces[pieceType] : [this.board.blackPieces[pieceType]]; + const index = pieceArray.indexOf(targetPiece); + if (index !== -1) { + pieceArray.splice(index, 1); + break; + } + } + } + } +}; \ No newline at end of file diff --git a/public/javascript/chess/pieces/king.js b/public/javascript/chess/pieces/king.js index 41aed5f..276bdb4 100644 --- a/public/javascript/chess/pieces/king.js +++ b/public/javascript/chess/pieces/king.js @@ -6,6 +6,16 @@ var King = function(config){ King.prototype = new Piece({}); -King.prototype.move = function(newPosition){ + +King.prototype.isValidMove = function(targetPosition){ + +} +King.prototype.moveTo = function(targetPosition){ + if(this.isValidMove(targetPosition)){ + this.position = targetPosition.col + targetPosition.row; + this.render(); + }else{ + console.log("Invalid move for king"); + } } \ No newline at end of file diff --git a/public/javascript/chess/pieces/knight.js b/public/javascript/chess/pieces/knight.js index 1f23ddf..1609975 100644 --- a/public/javascript/chess/pieces/knight.js +++ b/public/javascript/chess/pieces/knight.js @@ -5,12 +5,18 @@ var Knight = function(config){ Knight.prototype = new Piece({}); -Knight.prototype.moveTo = function(targetPosition){ +Knight.prototype.moveTo = function(targetPosition) { var isValidMove = this.isValidMove(targetPosition); if (!isValidMove) { console.log("Invalid move for knight"); return; } + + const targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece) { + this.kill(targetPiece); + } + console.log("move function starts here"); var newPos = targetPosition.col + targetPosition.row; this.position = newPos; @@ -23,7 +29,6 @@ Knight.prototype.isValidMove = function(targetPosition) { var targetRow = parseInt(targetPosition.row, 10); var currentCol = this.position[0].toUpperCase().charCodeAt(0) - 65; var targetCol = targetPosition.col.toUpperCase().charCodeAt(0) - 65; - console.log("currentRow: ", currentRow + " " + typeof currentRow); console.log("targetRow: ", targetRow + " " + typeof targetRow); console.log("currentCol: ", currentCol + " " + typeof currentCol); diff --git a/public/javascript/chess/pieces/pawn.js b/public/javascript/chess/pieces/pawn.js index b8b2460..3c83c43 100644 --- a/public/javascript/chess/pieces/pawn.js +++ b/public/javascript/chess/pieces/pawn.js @@ -1,13 +1,63 @@ -var Pawn = function(config){ +var Pawn = function(config) { this.type = 'pawn'; - this.constructor(config); + Piece.call(this, config); + this.color = config.color; + this.position = config.position; + this.board = config.board; }; +// Properly inherit from the Piece class +Pawn.prototype = Object.create(Piece.prototype); +Pawn.prototype.constructor = Pawn; +// Move the Pawn to the target position +Pawn.prototype.moveTo = function(targetPosition) { + if (this.board.currentTurn !== this.color) { + console.log("Invalid move: Not your turn"); + return; + } + + // Check if the move is valid + if (this.isValidMove(targetPosition)) { + // Check if the move is a kill (diagonal capture) + if (this.isDiagonalCapture(targetPosition)) { + const targetPiece = this.board.getPieceAt(targetPosition); + this.kill(targetPiece); // Kill the target piece + } + + this.position = targetPosition.col + targetPosition.row; + this.render(); // Re-render the pawn in the new position + console.log("Pawn moved to " + this.position); + } else { + console.log("Invalid move for pawn"); + } +}; -Pawn.prototype = new Piece({}); +// Kill logic +Pawn.prototype.kill = function(targetPiece) { + // Remove the target piece from the board + const targetPosition = targetPiece.position; + const targetElement = document.querySelector(`[data-col="${targetPosition[0]}"] [data-row="${targetPosition[1]}"]`); + targetElement.innerHTML = ''; // Remove the target piece from the board + + // Remove the target piece from the appropriate pieces object + if (targetPiece.color === 'white') { + const index = this.board.whitePieces.pawns.indexOf(targetPiece); + if (index !== -1) { + this.board.whitePieces.pawns.splice(index, 1); + } + } else { + const index = this.board.blackPieces.pawns.indexOf(targetPiece); + if (index !== -1) { + this.board.blackPieces.pawns.splice(index, 1); + } + } + + console.log("Pawn killed " + targetPiece.type); +}; -Pawn.prototype.isValidPosition = function(targetPosition){ +// Validate the Pawn's move +Pawn.prototype.isValidMove = function(targetPosition) { // Convert current position to row and column let currentCol = this.position.charAt(0); let currentRow = parseInt(this.position.charAt(1)); @@ -16,33 +66,34 @@ Pawn.prototype.isValidPosition = function(targetPosition){ let moveDistance = this.color === 'white' ? 1 : -1; let initialRow = this.color === 'white' ? 2 : 7; - // Check if the move is valid + // Moving straight if (targetPosition.col === currentCol) { - // Moving straight if (targetPosition.row === (currentRow + moveDistance).toString()) { - // Regular one-square move - return true; + return true; // Regular one-square move } else if (currentRow === initialRow && targetPosition.row === (currentRow + 2 * moveDistance).toString()) { - // Initial two-square move - return true; + return true; // Initial two-square move } - } else if (Math.abs(targetPosition.col.charCodeAt(0) - currentCol.charCodeAt(0)) === 1 && - targetPosition.row === (currentRow + moveDistance).toString()) { - // Diagonal capture (assuming there's an enemy piece, which should be checked in the main game logic) - return true; + } + + // Diagonal movement is only valid for capturing an opponent's piece + if (this.isDiagonalCapture(targetPosition)) { + return true; // Diagonal capture } // If none of the above conditions are met, the move is invalid console.warn("Invalid move for pawn"); return false; -} +}; + +// Check if the move is a diagonal capture +Pawn.prototype.isDiagonalCapture = function(targetPosition) { + let currentCol = this.position.charAt(0); + let currentRow = parseInt(this.position.charAt(1)); + + return Math.abs(targetPosition.col.charCodeAt(0) - currentCol.charCodeAt(0)) === 1 && + targetPosition.row === (currentRow + (this.color === 'white' ? 1 : -1)).toString(); +}; + +// Inherit from the Piece class properly +Pawn.prototype.constructor = Pawn; -Pawn.prototype.moveTo = function(targetPosition){ - if(this.isValidPosition(targetPosition)){ - this.position = targetPosition.col + targetPosition.row; - this.render(); - }else{ - //NOOP - } - -} \ No newline at end of file From 484a66289e257cedfebde2c8eda9fdc698ded51f Mon Sep 17 00:00:00 2001 From: Adityajaiswal03 Date: Thu, 26 Sep 2024 19:02:45 +0530 Subject: [PATCH 03/10] added moves for king --- .DS_Store | Bin 0 -> 6148 bytes public/javascript/chess/pieces/king.js | 61 ++++++++++++++++++++----- 2 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..75d93e8febe0d1e5b434b23452ed073ebbfc39f5 GIT binary patch literal 6148 zcmeHK%Sr<=6g|-*^#Lll5LB2Su+SfnQO1P}L8^PTt=7l1Q?vy)!YthBH;8}W7r1rh z#;qUV+N}%GbCXafQ!B1SBo~sCN$$x_PST_SpjNu|GB5?8$Rt=8WA=qfyQDrFvNbbA zC4Iz=@@6e*w);GNg;&5U@D~-3-);dVG;oNH^ZT8ff6lfwlPIdjNtJcQ#kc*(hsyo3 z+g|^+y?u~58|F7i#Ta9@P{$t5ID!Lo&_uizCp8;K4kd|Edekd_ zMo4swZT2puE@DQ^@zlakd5%WattIjX#>i^cI`3)rjsK^HKk;`oy}02}FpV~LQNuCw z2IslR*(UnC1ggby%T-KWl9g3>BGTs~XB&+rD)gYUJ1> zWOvDmh2xG;?}6*g9&mh}^}v(dJx+Ue4X*BbYmoE#)P0bTqqTZr7>uHVRgNygI4XfZXYj}B(~2|z5cS{uu9Z3`!` z7+OpXvW2D$m1wBSJ~5P`vp%qXp~cjop+ninhq95CeW55Fo&5*e9V#^FbFY9`z*S(_ zd``*zzdHE+?~?qNSHLUquM|*)Xfs;jl%Z9qWQz#j{M> a*cM2E7+OpXvWDjW2xu96<`wu=1wH@*BI%m| literal 0 HcmV?d00001 diff --git a/public/javascript/chess/pieces/king.js b/public/javascript/chess/pieces/king.js index 276bdb4..71d3a53 100644 --- a/public/javascript/chess/pieces/king.js +++ b/public/javascript/chess/pieces/king.js @@ -1,21 +1,60 @@ -var King = function(config){ - this.type = 'king'; +var King = function (config) { + this.type = "king"; this.constructor(config); }; +King.prototype = new Piece({}); +King.prototype.kill = function (targetPiece) { + const targetPosition = targetPiece.position; + const targetElement = document.querySelector( + `[data-col="${targetPosition[0]}"] [data-row="${targetPosition[1]}"]` + ); + targetElement.innerHTML = ""; // Remove the target piece from the board -King.prototype = new Piece({}); + console.log("King killed " + targetPiece.type); +}; +King.prototype.isValidMove = function (targetPosition) { + // Convert current position to row and column + let currentCol = this.position.charAt(0); + let currentRow = parseInt(this.position.charAt(1)); + + // Calculate the target position row and column + let targetCol = targetPosition.col; + let targetRow = targetPosition.row; + + // Calculate the difference in rows and columns + let rowDifference = Math.abs(targetRow - currentRow); + let colDifference = Math.abs( + targetCol.charCodeAt(0) - currentCol.charCodeAt(0) + ); + + // King can move one square in any direction (horizontal, vertical, or diagonal) + if (rowDifference <= 1 && colDifference <= 1) { + return true; // Valid king move + } -King.prototype.isValidMove = function(targetPosition){ - -} -King.prototype.moveTo = function(targetPosition){ - if(this.isValidMove(targetPosition)){ + // If none of the conditions are met, the move is invalid + console.warn("Invalid move for king"); + return false; +}; + +King.prototype.moveTo = function (targetPosition) { + if (this.board.currentTurn !== this.color) { + console.log("Invalid move: Not your turn"); + return; + } + if ( + this.isValidMove(targetPosition) && + this.board.getPieceAt(targetPosition) !== null && + this.board.getPieceAt(targetPosition).color !== this.color + ) { + this.kill(this.board.getPieceAt(targetPosition)); + } + if (this.isValidMove(targetPosition)) { this.position = targetPosition.col + targetPosition.row; this.render(); - }else{ + } else { console.log("Invalid move for king"); } - -} \ No newline at end of file +}; From 4df8cd9171a0f71a1cd6ce12498ecd1882afe930 Mon Sep 17 00:00:00 2001 From: Rohith Thirunagari Date: Thu, 26 Sep 2024 22:02:23 +0530 Subject: [PATCH 04/10] implemented Bishop.prototype.moveTo --- public/javascript/chess/pieces/bishop.js | 67 ++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/public/javascript/chess/pieces/bishop.js b/public/javascript/chess/pieces/bishop.js index 75d7392..f8b17cc 100644 --- a/public/javascript/chess/pieces/bishop.js +++ b/public/javascript/chess/pieces/bishop.js @@ -1,11 +1,68 @@ -var Bishop = function(config){ +var Bishop = function(config) { this.type = 'bishop'; - this.constructor(config); + Piece.call(this, config); + this.color = config.color; + this.position = config.position; + this.board = config.board; }; +// Properly inherit from the Piece class +Bishop.prototype = Object.create(Piece.prototype); +Bishop.prototype.constructor = Bishop; +// Move the Bishop to the target position +Bishop.prototype.moveTo = function(targetPosition) { + if (this.board.currentTurn !== this.color) { + console.log("Invalid move: Not your turn"); + return; + } + + // Check if the move is valid + if (this.isValidMove(targetPosition)) { + // Check if there's a piece at the target position + const targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece && targetPiece.color !== this.color) { + this.kill(targetPiece); // Kill the target piece if it's an opponent's + } + + this.position = targetPosition.col + targetPosition.row; + this.render(); // Re-render the bishop in the new position + console.log(this.color + " Bishop moved to " + this.position); + } else { + console.log("Invalid move for " + this.color + " bishop"); + } +}; + +// Validate the Bishop's move +Bishop.prototype.isValidMove = function(targetPosition) { + // Convert current position to row and column + let currentCol = this.position.charCodeAt(0) - 'a'.charCodeAt(0); + let currentRow = parseInt(this.position.charAt(1)) - 1; + let targetCol = targetPosition.col.charCodeAt(0) - 'a'.charCodeAt(0); + let targetRow = parseInt(targetPosition.row) - 1; -Bishop.prototype = new Piece({}); -Bishop.prototype.move = function(newPosition){ + // Check if the move is diagonal + if (Math.abs(targetCol - currentCol) === Math.abs(targetRow - currentRow)) { + // Check if the path is clear + let rowStep = targetRow > currentRow ? 1 : -1; + let colStep = targetCol > currentCol ? 1 : -1; + + for (let i = 1; i < Math.abs(targetCol - currentCol); i++) { + let checkCol = String.fromCharCode(currentCol + i * colStep + 'a'.charCodeAt(0)); + let checkRow = (currentRow + i * rowStep + 1).toString(); + if (this.board.getPieceAt({col: checkCol, row: checkRow})) { + console.warn("Path is not clear for " + this.color + " bishop"); + return false; + } + } + + // Check if the target square is empty or contains an opponent's piece + const targetPiece = this.board.getPieceAt(targetPosition); + if (!targetPiece || targetPiece.color !== this.color) { + return true; + } + } -} \ No newline at end of file + console.warn("Invalid move for " + this.color + " bishop"); + return false; +}; \ No newline at end of file From 9d11793da0f6b4430509aa1b76701ae8260e8dbb Mon Sep 17 00:00:00 2001 From: sachan13harshit Date: Thu, 26 Sep 2024 22:58:26 +0530 Subject: [PATCH 05/10] Implemented Rook.prototype.moveTo --- public/javascript/chess/pieces/rook.js | 76 +++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/public/javascript/chess/pieces/rook.js b/public/javascript/chess/pieces/rook.js index 045c127..049e491 100644 --- a/public/javascript/chess/pieces/rook.js +++ b/public/javascript/chess/pieces/rook.js @@ -1,11 +1,71 @@ -var Rook = function(config){ - this.type = 'rook'; +var Rook = function (config) { + this.type = "rook"; this.constructor(config); }; - - - Rook.prototype = new Piece({}); -Rook.prototype.move = function(newPosition){ - -} \ No newline at end of file +Rook.prototype.kill = function (targetPiece) { + const targetPosition = targetPiece.position; + const targetElement = document.querySelector( + `[data-col="${targetPosition[0]}"] [data-row="${targetPosition[1]}"]` + ); + targetElement.innerHTML = ""; + Piece.prototype.kill.call(this, targetPiece); + console.log("Rook killed " + targetPiece.type); +}; +Rook.prototype.isValidMove = function (targetPosition) { + let currentCol = this.position.charAt(0); + let currentRow = parseInt(this.position.charAt(1)); + let targetCol = targetPosition.col; + let targetRow = parseInt(targetPosition.row); + let colDifference = Math.abs(targetCol.charCodeAt(0) - currentCol.charCodeAt(0)); + let rowDifference = Math.abs(targetRow - currentRow); + if (colDifference !== 0 && rowDifference !== 0) { + console.warn("Invalid move for rook: Rook must move in a straight line."); + return false; + } + if (!this.isPathCheck(currentCol, currentRow, targetCol, targetRow)) { + console.warn("Path is not clear for rook."); + return false; + } + return true; +}; +Rook.prototype.isPathCheck = function (currentCol, currentRow, targetCol, targetRow) { + let colStep = 0; + let rowStep = 0; + if (currentCol === targetCol) { + rowStep = targetRow > currentRow ? 1 : -1; + } else { + colStep = targetCol.charCodeAt(0) > currentCol.charCodeAt(0) ? 1 : -1; + } + let col = currentCol.charCodeAt(0) + colStep; + let row = currentRow + rowStep; + while ((String.fromCharCode(col) !== targetCol) || (row !== targetRow)) { + let checkPosition = { + col: String.fromCharCode(col), + row: row.toString() + }; + if (this.board.getPieceAt(checkPosition)) { + return false; + } + col += colStep; + row += rowStep; + } + return true; +}; +Rook.prototype.moveTo = function (targetPosition) { + if (this.board.currentTurn !== this.color) { + console.log("Invalid move: Not your turn"); + return; + } + if (this.isValidMove(targetPosition)) { + let targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece && targetPiece.color !== this.color) { + this.kill(targetPiece); + } + this.position = targetPosition.col + targetPosition.row; + this.render(); + console.log(`Rook moved to ${this.position}`); + } else { + console.log("Invalid move for rook"); + } +}; \ No newline at end of file From 14928d00d01e539e9e7f6c10dfc4ba4f7549be24 Mon Sep 17 00:00:00 2001 From: Rushhaabhhh Date: Thu, 26 Sep 2024 23:14:16 +0530 Subject: [PATCH 06/10] Updated moves logic --- public/css/chess.css | 9 ++++ public/javascript/chess/board.js | 35 ++++++++++++---- public/javascript/chess/pieces/king.js | 4 +- public/javascript/chess/pieces/pawn.js | 1 - public/javascript/chess/pieces/rook.js | 57 +++++++++++++++++++++++++- 5 files changed, 94 insertions(+), 12 deletions(-) diff --git a/public/css/chess.css b/public/css/chess.css index 2a86c74..54e9a6c 100644 --- a/public/css/chess.css +++ b/public/css/chess.css @@ -88,3 +88,12 @@ .white.pawn { background-position: -247px 0; } .black.pawn { background-position: -247px -50px; } + +.highlight { + background-color: rgba(255, 255, 0, 0.5); /* Yellow translucent background */ + border-radius: 50%; /* Make it circular */ + width: 100%; + height: 100%; + position: relative; + z-index: 1; +} diff --git a/public/javascript/chess/board.js b/public/javascript/chess/board.js index 445e081..5816bce 100644 --- a/public/javascript/chess/board.js +++ b/public/javascript/chess/board.js @@ -60,24 +60,43 @@ Board.prototype.boardClicked = function(event) { if (!clickedCell) return; // Exit if click was not on a valid cell const piece = this.getPieceAt(clickedCell); - + if (this.selectedPiece) { // If a piece is already selected if (piece) { - // If the selected piece is of the same color + // If the player clicks on a piece of the same color, allow reselection if (piece.color === this.selectedPiece.color) { - console.log(`You selected your own piece. You can't select an opponent's piece.`); + console.log(`Reselecting your own piece.`); + this.selectPiece(event.target, piece); // Reselect the new piece return; } else { - // Move selected piece to the clicked cell if it's a valid move + // If clicked on an opponent's piece, validate move before capturing + const targetPosition = { row: clickedCell.row, col: clickedCell.col }; + const isValidMove = this.selectedPiece.isValidMove(targetPosition); + + if (!isValidMove) { + console.log('Invalid move, try again.'); + return; // Do not switch turns or move the piece if invalid move + } + + // Valid move, so capture the opponent's piece this.selectedPiece.moveTo(clickedCell); this.clearSelection(); - this.switchTurn(); + this.switchTurn(); // Switch turn after a valid move } } else { - // Move the selected piece to the new position if no piece is clicked + // Empty cell clicked, validate move and proceed + const targetPosition = { row: clickedCell.row, col: clickedCell.col }; + const isValidMove = this.selectedPiece.isValidMove(targetPosition); + + if (!isValidMove) { + console.log('Invalid move, try again.'); + return; // Do not switch turns or move the piece if invalid move + } + + // Move the selected piece to the new position this.selectedPiece.moveTo(clickedCell); this.clearSelection(); - this.switchTurn(); + this.switchTurn(); // Switch turn after a valid move } } else { if (piece) { @@ -91,6 +110,8 @@ Board.prototype.boardClicked = function(event) { } } + + Board.prototype.getPieceAt = function(cell) { if (!cell || !cell.row || !cell.col) { return false; diff --git a/public/javascript/chess/pieces/king.js b/public/javascript/chess/pieces/king.js index 71d3a53..c7af5ee 100644 --- a/public/javascript/chess/pieces/king.js +++ b/public/javascript/chess/pieces/king.js @@ -48,9 +48,7 @@ King.prototype.moveTo = function (targetPosition) { this.isValidMove(targetPosition) && this.board.getPieceAt(targetPosition) !== null && this.board.getPieceAt(targetPosition).color !== this.color - ) { - this.kill(this.board.getPieceAt(targetPosition)); - } + ) if (this.isValidMove(targetPosition)) { this.position = targetPosition.col + targetPosition.row; this.render(); diff --git a/public/javascript/chess/pieces/pawn.js b/public/javascript/chess/pieces/pawn.js index 3c83c43..025ef2e 100644 --- a/public/javascript/chess/pieces/pawn.js +++ b/public/javascript/chess/pieces/pawn.js @@ -96,4 +96,3 @@ Pawn.prototype.isDiagonalCapture = function(targetPosition) { // Inherit from the Piece class properly Pawn.prototype.constructor = Pawn; - diff --git a/public/javascript/chess/pieces/rook.js b/public/javascript/chess/pieces/rook.js index 045c127..ec2c24d 100644 --- a/public/javascript/chess/pieces/rook.js +++ b/public/javascript/chess/pieces/rook.js @@ -6,6 +6,61 @@ var Rook = function(config){ Rook.prototype = new Piece({}); -Rook.prototype.move = function(newPosition){ +Rook.prototype.isValidPosition = function(newPosition){ + let currentCol = this.position.charAt(0); + let currentRow = parseInt(this.position.charAt(1)); + + let newCol = newPosition.col; + let newRow = parseInt(newPosition.row); + let targetPiece = this.board.getPieceAt(newPosition); + + const isHorizontalMove = (currentRow === newRow && currentCol !== newCol); + const isVerticalMove = (currentCol === newCol && currentRow !== newRow); + + if (isHorizontalMove || isVerticalMove) { + + if (isHorizontalMove) { + let start = Math.min(currentCol.charCodeAt(0), newCol.charCodeAt(0)) - 63; + let end = Math.max(currentCol.charCodeAt(0), newCol.charCodeAt(0)) - 64; + for(let i = start; i < end; i++){ + let targetPosition = {row: currentRow, col: String.fromCharCode(i + 64)}; + let targetPiece = this.board.getPieceAt(targetPosition); + if(targetPiece) { + console.warn("Invalid move for rook"); + return false; + } + } + } + + if (isVerticalMove) { + let start = Math.min(currentRow, newRow) + 1; + let end = Math.max(currentRow, newRow); + for(let i = start; i < end; i++){ + let targetPosition = {row: i, col: newCol}; + let targetPiece = this.board.getPieceAt(targetPosition); + if(targetPiece) { + console.warn("Invalid move for rook"); + return false; + } + } + } + + if (targetPiece && targetPiece.color !== this.color) { + targetPiece.kill(targetPiece); + } + + return true; + } + + // Invalid move + console.warn("Invalid move for rook"); + return false; +} + +Rook.prototype.moveTo = function(newPosition){ + if(this.isValidPosition(newPosition)){ + this.position = newPosition.col + newPosition.row; + this.render(); + } } \ No newline at end of file From 751bd4a31e71bddeecb1890f38feb1a565355511 Mon Sep 17 00:00:00 2001 From: Rushhaabhhh Date: Thu, 26 Sep 2024 23:14:20 +0530 Subject: [PATCH 07/10] Updated moves logic --- public/javascript/chess/pieces/rook.js | 57 +------------------------- 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/public/javascript/chess/pieces/rook.js b/public/javascript/chess/pieces/rook.js index ec2c24d..045c127 100644 --- a/public/javascript/chess/pieces/rook.js +++ b/public/javascript/chess/pieces/rook.js @@ -6,61 +6,6 @@ var Rook = function(config){ Rook.prototype = new Piece({}); +Rook.prototype.move = function(newPosition){ -Rook.prototype.isValidPosition = function(newPosition){ - let currentCol = this.position.charAt(0); - let currentRow = parseInt(this.position.charAt(1)); - - let newCol = newPosition.col; - let newRow = parseInt(newPosition.row); - let targetPiece = this.board.getPieceAt(newPosition); - - const isHorizontalMove = (currentRow === newRow && currentCol !== newCol); - const isVerticalMove = (currentCol === newCol && currentRow !== newRow); - - if (isHorizontalMove || isVerticalMove) { - - if (isHorizontalMove) { - let start = Math.min(currentCol.charCodeAt(0), newCol.charCodeAt(0)) - 63; - let end = Math.max(currentCol.charCodeAt(0), newCol.charCodeAt(0)) - 64; - for(let i = start; i < end; i++){ - let targetPosition = {row: currentRow, col: String.fromCharCode(i + 64)}; - let targetPiece = this.board.getPieceAt(targetPosition); - if(targetPiece) { - console.warn("Invalid move for rook"); - return false; - } - } - } - - if (isVerticalMove) { - let start = Math.min(currentRow, newRow) + 1; - let end = Math.max(currentRow, newRow); - for(let i = start; i < end; i++){ - let targetPosition = {row: i, col: newCol}; - let targetPiece = this.board.getPieceAt(targetPosition); - if(targetPiece) { - console.warn("Invalid move for rook"); - return false; - } - } - } - - if (targetPiece && targetPiece.color !== this.color) { - targetPiece.kill(targetPiece); - } - - return true; - } - - // Invalid move - console.warn("Invalid move for rook"); - return false; -} - -Rook.prototype.moveTo = function(newPosition){ - if(this.isValidPosition(newPosition)){ - this.position = newPosition.col + newPosition.row; - this.render(); - } } \ No newline at end of file From f2c6b4c97096b74b41d70ce6df1494cb59608f80 Mon Sep 17 00:00:00 2001 From: Arnavya Date: Thu, 26 Sep 2024 23:21:02 +0530 Subject: [PATCH 08/10] Queen Implementation --- public/javascript/chess/pieces/queen.js | 72 +++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/public/javascript/chess/pieces/queen.js b/public/javascript/chess/pieces/queen.js index 7b114c2..3d0c896 100644 --- a/public/javascript/chess/pieces/queen.js +++ b/public/javascript/chess/pieces/queen.js @@ -3,9 +3,75 @@ var Queen = function(config){ this.constructor(config); }; +Queen.prototype = new Piece({}); +Queen.prototype.moveTo = function(targetPosition) { + var isValidMove = this.isValidMove(targetPosition); + if (!isValidMove) { + console.log("Invalid move for queen"); + return; + } + + const targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece) { + this.kill(targetPiece); + } -Queen.prototype = new Piece({}); -Queen.prototype.move = function(newPosition){ + console.log("move function starts here"); + var newPos = targetPosition.col + targetPosition.row; + this.position = newPos; + this.render(); + console.log("move function successfully ends here"); +}; + +Queen.prototype.isValidMove = function(targetPosition) { + var currentRow = parseInt(this.position[1], 10); + var targetRow = parseInt(targetPosition.row, 10); + var currentCol = this.position[0].toUpperCase().charCodeAt(0) - 65; + var targetCol = targetPosition.col.toUpperCase().charCodeAt(0) - 65; + + console.log("currentRow: ", currentRow, "targetRow: ", targetRow); + console.log("currentCol: ", currentCol, "targetCol: ", targetCol); + + var rowDiff = Math.abs(targetRow - currentRow); + var colDiff = Math.abs(targetCol - currentCol); + + // The queen can move any number of squares vertically, horizontally, or diagonally. + if ((rowDiff === colDiff) || (currentRow === targetRow) || (currentCol === targetCol)) { + // Check for obstacles + if (this.isPathBlocked(currentRow, currentCol, targetRow, targetCol)) { + console.log("Invalid move: There is an obstacle in the path."); + return false; + } + return true; + } else { + console.log("Invalid move: Queen must move vertically, horizontally, or diagonally."); + return false; + } +}; -} \ No newline at end of file +// Helper method to check if there's any obstacle in the path of the Queen +Queen.prototype.isPathBlocked = function(currentRow, currentCol, targetRow, targetCol) { + var rowStep = (targetRow > currentRow) ? 1 : (targetRow < currentRow) ? -1 : 0;//1-->forward, -1-->backward, 0--> no movement + var colStep = (targetCol > currentCol) ? 1 : (targetCol < currentCol) ? -1 : 0; + + var row = currentRow + rowStep; + var col = currentCol + colStep; + + while (row !== targetRow || col !== targetCol) { + var position = { + row: row.toString(), + col: String.fromCharCode(65 + col) + }; + + // Check if a piece exists at this position + if (this.board.getPieceAt(position)) { + return true; // There is an obstacle + } + + row += rowStep; + col += colStep; + } + + return false; // No obstacles +}; From 1c0199d95b333c760e0e554f8b8d5f1e2014b917 Mon Sep 17 00:00:00 2001 From: Rushabh <145254552+Rushhaabhhh@users.noreply.github.com> Date: Thu, 26 Sep 2024 23:27:15 +0530 Subject: [PATCH 09/10] Updated reselection of pieces --- public/javascript/chess/board.js | 35 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/public/javascript/chess/board.js b/public/javascript/chess/board.js index 445e081..5816bce 100644 --- a/public/javascript/chess/board.js +++ b/public/javascript/chess/board.js @@ -60,24 +60,43 @@ Board.prototype.boardClicked = function(event) { if (!clickedCell) return; // Exit if click was not on a valid cell const piece = this.getPieceAt(clickedCell); - + if (this.selectedPiece) { // If a piece is already selected if (piece) { - // If the selected piece is of the same color + // If the player clicks on a piece of the same color, allow reselection if (piece.color === this.selectedPiece.color) { - console.log(`You selected your own piece. You can't select an opponent's piece.`); + console.log(`Reselecting your own piece.`); + this.selectPiece(event.target, piece); // Reselect the new piece return; } else { - // Move selected piece to the clicked cell if it's a valid move + // If clicked on an opponent's piece, validate move before capturing + const targetPosition = { row: clickedCell.row, col: clickedCell.col }; + const isValidMove = this.selectedPiece.isValidMove(targetPosition); + + if (!isValidMove) { + console.log('Invalid move, try again.'); + return; // Do not switch turns or move the piece if invalid move + } + + // Valid move, so capture the opponent's piece this.selectedPiece.moveTo(clickedCell); this.clearSelection(); - this.switchTurn(); + this.switchTurn(); // Switch turn after a valid move } } else { - // Move the selected piece to the new position if no piece is clicked + // Empty cell clicked, validate move and proceed + const targetPosition = { row: clickedCell.row, col: clickedCell.col }; + const isValidMove = this.selectedPiece.isValidMove(targetPosition); + + if (!isValidMove) { + console.log('Invalid move, try again.'); + return; // Do not switch turns or move the piece if invalid move + } + + // Move the selected piece to the new position this.selectedPiece.moveTo(clickedCell); this.clearSelection(); - this.switchTurn(); + this.switchTurn(); // Switch turn after a valid move } } else { if (piece) { @@ -91,6 +110,8 @@ Board.prototype.boardClicked = function(event) { } } + + Board.prototype.getPieceAt = function(cell) { if (!cell || !cell.row || !cell.col) { return false; From 7c576a82a82252f84d7a00c0b170c57b09625532 Mon Sep 17 00:00:00 2001 From: Rushhaabhhh Date: Tue, 1 Oct 2024 11:48:46 +0530 Subject: [PATCH 10/10] Pawn movement correction --- public/javascript/chess/board.js | 14 +++-- public/javascript/chess/pieces/knight.js | 44 +++++++------- public/javascript/chess/pieces/pawn.js | 76 ++++++++++-------------- public/javascript/chess/pieces/queen.js | 72 +++++++++++++++++++++- public/javascript/chess/pieces/rook.js | 76 +++++++++++++++++++++--- 5 files changed, 198 insertions(+), 84 deletions(-) diff --git a/public/javascript/chess/board.js b/public/javascript/chess/board.js index 5816bce..7461444 100644 --- a/public/javascript/chess/board.js +++ b/public/javascript/chess/board.js @@ -46,13 +46,14 @@ Board.prototype.getClickedBlock = function(clickEvent) { console.warn('Clicked element is not within a board square'); } } - Board.prototype.clearSelection = function() { - const allPieces = document.querySelectorAll('.piece'); - allPieces.forEach(piece => { + // Deselect all currently selected pieces + const selectedPieces = document.querySelectorAll('.selected'); + selectedPieces.forEach(piece => { piece.classList.remove('selected'); }); - this.selectedPiece = null; // Reset selectedPiece + + this.selectedPiece = null; // Reset the selected piece }; Board.prototype.boardClicked = function(event) { @@ -147,6 +148,10 @@ Board.prototype.switchTurn = function() { } Board.prototype.selectPiece = function(clickedElement, selectedPiece) { + // First clear any existing selection + this.clearSelection(); + + // Highlight the new selected piece only if (clickedElement.classList.contains('piece')) { clickedElement.classList.add('selected'); } else { @@ -155,6 +160,7 @@ Board.prototype.selectPiece = function(clickedElement, selectedPiece) { parentElement.classList.add('selected'); } } + selectedPiece.selected = true; this.selectedPiece = selectedPiece; // Set the selected piece } diff --git a/public/javascript/chess/pieces/knight.js b/public/javascript/chess/pieces/knight.js index 1609975..3b8027b 100644 --- a/public/javascript/chess/pieces/knight.js +++ b/public/javascript/chess/pieces/knight.js @@ -5,42 +5,38 @@ var Knight = function(config){ Knight.prototype = new Piece({}); -Knight.prototype.moveTo = function(targetPosition) { - var isValidMove = this.isValidMove(targetPosition); - if (!isValidMove) { - console.log("Invalid move for knight"); - return; - } - - const targetPiece = this.board.getPieceAt(targetPosition); - if (targetPiece) { - this.kill(targetPiece); - } - - console.log("move function starts here"); - var newPos = targetPosition.col + targetPosition.row; - this.position = newPos; - this.render(); - console.log("move function successfully ends here"); -}; - Knight.prototype.isValidMove = function(targetPosition) { + var currentRow = parseInt(this.position[1], 10); var targetRow = parseInt(targetPosition.row, 10); var currentCol = this.position[0].toUpperCase().charCodeAt(0) - 65; var targetCol = targetPosition.col.toUpperCase().charCodeAt(0) - 65; - console.log("currentRow: ", currentRow + " " + typeof currentRow); - console.log("targetRow: ", targetRow + " " + typeof targetRow); - console.log("currentCol: ", currentCol + " " + typeof currentCol); - console.log("targetCol: ", targetCol + " " + typeof targetCol); var rowDiff = Math.abs(targetRow - currentRow); var colDiff = Math.abs(targetCol - currentCol); if ((rowDiff === 2 && colDiff === 1) || (rowDiff === 1 && colDiff === 2)) { return true; - } else { + } + else { console.log("Invalid move: Knight must move in an L-shape"); return false; } }; + +Knight.prototype.moveTo = function(targetPosition) { + var isValidMove = this.isValidMove(targetPosition); + if (!isValidMove) { + console.log("Invalid move for knight"); + return; + } + + const targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece) { + this.kill(targetPiece); + } + this.position = targetPosition.col + targetPosition.row; + this.render(); +}; + + diff --git a/public/javascript/chess/pieces/pawn.js b/public/javascript/chess/pieces/pawn.js index 025ef2e..d408dd9 100644 --- a/public/javascript/chess/pieces/pawn.js +++ b/public/javascript/chess/pieces/pawn.js @@ -19,10 +19,16 @@ Pawn.prototype.moveTo = function(targetPosition) { // Check if the move is valid if (this.isValidMove(targetPosition)) { - // Check if the move is a kill (diagonal capture) - if (this.isDiagonalCapture(targetPosition)) { - const targetPiece = this.board.getPieceAt(targetPosition); - this.kill(targetPiece); // Kill the target piece + const targetPiece = this.board.getPieceAt(targetPosition); + + // Check if it is a capture move + if (this.isDiagonalCapture(targetPosition) && targetPiece && targetPiece.color !== this.color) { + this.kill(targetPiece); // Capture the target piece + } else if (this.isStraightMove(targetPosition) && !targetPiece) { + // Normal straight move, no capture + } else { + console.log("Invalid move: Cannot move there"); + return; } this.position = targetPosition.col + targetPosition.row; @@ -33,32 +39,13 @@ Pawn.prototype.moveTo = function(targetPosition) { } }; -// Kill logic -Pawn.prototype.kill = function(targetPiece) { - // Remove the target piece from the board - const targetPosition = targetPiece.position; - const targetElement = document.querySelector(`[data-col="${targetPosition[0]}"] [data-row="${targetPosition[1]}"]`); - targetElement.innerHTML = ''; // Remove the target piece from the board - - // Remove the target piece from the appropriate pieces object - if (targetPiece.color === 'white') { - const index = this.board.whitePieces.pawns.indexOf(targetPiece); - if (index !== -1) { - this.board.whitePieces.pawns.splice(index, 1); - } - } else { - const index = this.board.blackPieces.pawns.indexOf(targetPiece); - if (index !== -1) { - this.board.blackPieces.pawns.splice(index, 1); - } - } - - console.log("Pawn killed " + targetPiece.type); -}; - // Validate the Pawn's move Pawn.prototype.isValidMove = function(targetPosition) { - // Convert current position to row and column + return this.isStraightMove(targetPosition) || this.isDiagonalCapture(targetPosition); +}; + +// Check if the move is a valid straight move (forward) +Pawn.prototype.isStraightMove = function(targetPosition) { let currentCol = this.position.charAt(0); let currentRow = parseInt(this.position.charAt(1)); @@ -66,23 +53,19 @@ Pawn.prototype.isValidMove = function(targetPosition) { let moveDistance = this.color === 'white' ? 1 : -1; let initialRow = this.color === 'white' ? 2 : 7; - // Moving straight + // Straight movement (no column change) if (targetPosition.col === currentCol) { + // Regular one-square move if (targetPosition.row === (currentRow + moveDistance).toString()) { - return true; // Regular one-square move - } else if (currentRow === initialRow && targetPosition.row === (currentRow + 2 * moveDistance).toString()) { - return true; // Initial two-square move + return true; + } + // Initial two-square move + else if (currentRow === initialRow && targetPosition.row === (currentRow + 2 * moveDistance).toString()) { + return true; } } - // Diagonal movement is only valid for capturing an opponent's piece - if (this.isDiagonalCapture(targetPosition)) { - return true; // Diagonal capture - } - - // If none of the above conditions are met, the move is invalid - console.warn("Invalid move for pawn"); - return false; + return false; // Invalid straight move }; // Check if the move is a diagonal capture @@ -90,9 +73,12 @@ Pawn.prototype.isDiagonalCapture = function(targetPosition) { let currentCol = this.position.charAt(0); let currentRow = parseInt(this.position.charAt(1)); - return Math.abs(targetPosition.col.charCodeAt(0) - currentCol.charCodeAt(0)) === 1 && - targetPosition.row === (currentRow + (this.color === 'white' ? 1 : -1)).toString(); -}; + // Check diagonal move + if (Math.abs(targetPosition.col.charCodeAt(0) - currentCol.charCodeAt(0)) === 1 && + targetPosition.row === (currentRow + (this.color === 'white' ? 1 : -1)).toString()) { + const targetPiece = this.board.getPieceAt(targetPosition); + return targetPiece && targetPiece.color !== this.color; // Only capture if there's an opponent's piece + } -// Inherit from the Piece class properly -Pawn.prototype.constructor = Pawn; + return false; +}; diff --git a/public/javascript/chess/pieces/queen.js b/public/javascript/chess/pieces/queen.js index 7b114c2..8d465b6 100644 --- a/public/javascript/chess/pieces/queen.js +++ b/public/javascript/chess/pieces/queen.js @@ -3,9 +3,75 @@ var Queen = function(config){ this.constructor(config); }; +Queen.prototype = new Piece({}); +Queen.prototype.moveTo = function(targetPosition) { + var isValidMove = this.isValidMove(targetPosition); + if (!isValidMove) { + console.log("Invalid move for queen"); + return; + } + + const targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece) { + this.kill(targetPiece); + } -Queen.prototype = new Piece({}); -Queen.prototype.move = function(newPosition){ + console.log("move function starts here"); + var newPos = targetPosition.col + targetPosition.row; + this.position = newPos; + this.render(); + console.log("move function successfully ends here"); +}; + +Queen.prototype.isValidMove = function(targetPosition) { + var currentRow = parseInt(this.position[1], 10); + var targetRow = parseInt(targetPosition.row, 10); + var currentCol = this.position[0].toUpperCase().charCodeAt(0) - 65; + var targetCol = targetPosition.col.toUpperCase().charCodeAt(0) - 65; + + console.log("currentRow: ", currentRow, "targetRow: ", targetRow); + console.log("currentCol: ", currentCol, "targetCol: ", targetCol); + + var rowDiff = Math.abs(targetRow - currentRow); + var colDiff = Math.abs(targetCol - currentCol); + + // The queen can move any number of squares vertically, horizontally, or diagonally. + if ((rowDiff === colDiff) || (currentRow === targetRow) || (currentCol === targetCol)) { + // Check for obstacles + if (this.isPathBlocked(currentRow, currentCol, targetRow, targetCol)) { + console.log("Invalid move: There is an obstacle in the path."); + return false; + } + return true; + } else { + console.log("Invalid move: Queen must move vertically, horizontally, or diagonally."); + return false; + } +}; + +// Helper method to check if there's any obstacle in the path of the Queen +Queen.prototype.isPathBlocked = function(currentRow, currentCol, targetRow, targetCol) { + var rowStep = (targetRow > currentRow) ? 1 : (targetRow < currentRow) ? -1 : 0;//1-->forward, -1-->backward, 0--> no movement + var colStep = (targetCol > currentCol) ? 1 : (targetCol < currentCol) ? -1 : 0; + + var row = currentRow + rowStep; + var col = currentCol + colStep; + + while (row !== targetRow || col !== targetCol) { + var position = { + row: row.toString(), + col: String.fromCharCode(65 + col) + }; + + // Check if a piece exists at this position + if (this.board.getPieceAt(position)) { + return true; // There is an obstacle + } + + row += rowStep; + col += colStep; + } -} \ No newline at end of file + return false; // No obstacles +}; \ No newline at end of file diff --git a/public/javascript/chess/pieces/rook.js b/public/javascript/chess/pieces/rook.js index 045c127..049e491 100644 --- a/public/javascript/chess/pieces/rook.js +++ b/public/javascript/chess/pieces/rook.js @@ -1,11 +1,71 @@ -var Rook = function(config){ - this.type = 'rook'; +var Rook = function (config) { + this.type = "rook"; this.constructor(config); }; - - - Rook.prototype = new Piece({}); -Rook.prototype.move = function(newPosition){ - -} \ No newline at end of file +Rook.prototype.kill = function (targetPiece) { + const targetPosition = targetPiece.position; + const targetElement = document.querySelector( + `[data-col="${targetPosition[0]}"] [data-row="${targetPosition[1]}"]` + ); + targetElement.innerHTML = ""; + Piece.prototype.kill.call(this, targetPiece); + console.log("Rook killed " + targetPiece.type); +}; +Rook.prototype.isValidMove = function (targetPosition) { + let currentCol = this.position.charAt(0); + let currentRow = parseInt(this.position.charAt(1)); + let targetCol = targetPosition.col; + let targetRow = parseInt(targetPosition.row); + let colDifference = Math.abs(targetCol.charCodeAt(0) - currentCol.charCodeAt(0)); + let rowDifference = Math.abs(targetRow - currentRow); + if (colDifference !== 0 && rowDifference !== 0) { + console.warn("Invalid move for rook: Rook must move in a straight line."); + return false; + } + if (!this.isPathCheck(currentCol, currentRow, targetCol, targetRow)) { + console.warn("Path is not clear for rook."); + return false; + } + return true; +}; +Rook.prototype.isPathCheck = function (currentCol, currentRow, targetCol, targetRow) { + let colStep = 0; + let rowStep = 0; + if (currentCol === targetCol) { + rowStep = targetRow > currentRow ? 1 : -1; + } else { + colStep = targetCol.charCodeAt(0) > currentCol.charCodeAt(0) ? 1 : -1; + } + let col = currentCol.charCodeAt(0) + colStep; + let row = currentRow + rowStep; + while ((String.fromCharCode(col) !== targetCol) || (row !== targetRow)) { + let checkPosition = { + col: String.fromCharCode(col), + row: row.toString() + }; + if (this.board.getPieceAt(checkPosition)) { + return false; + } + col += colStep; + row += rowStep; + } + return true; +}; +Rook.prototype.moveTo = function (targetPosition) { + if (this.board.currentTurn !== this.color) { + console.log("Invalid move: Not your turn"); + return; + } + if (this.isValidMove(targetPosition)) { + let targetPiece = this.board.getPieceAt(targetPosition); + if (targetPiece && targetPiece.color !== this.color) { + this.kill(targetPiece); + } + this.position = targetPosition.col + targetPosition.row; + this.render(); + console.log(`Rook moved to ${this.position}`); + } else { + console.log("Invalid move for rook"); + } +}; \ No newline at end of file