diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..75d93e8
Binary files /dev/null and b/.DS_Store differ
diff --git a/public/css/chess.css b/public/css/chess.css
index 6705394..54e9a6c 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,33 @@
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; }
+
+.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 3e54332..7461444 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 = '
';
const columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];
-
+
for (let col of columns) {
boardHTML += ``;
for (let row = 1; row <= 8; row++) {
@@ -20,27 +23,22 @@ Board.prototype.generateBoardDom = function(config){
}
boardHTML += '
';
}
-
+
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');
}
@@ -48,31 +46,74 @@ Board.prototype.getClickedBlock = function(clickEvent){
console.warn('Clicked element is not within a board square');
}
}
-
-Board.prototype.clearSelection = function(){
- // Remove 'selected' class from all pieces
- const allPieces = document.querySelectorAll('.piece');
- allPieces.forEach(piece => {
+Board.prototype.clearSelection = function() {
+ // Deselect all currently selected pieces
+ const selectedPieces = document.querySelectorAll('.selected');
+ selectedPieces.forEach(piece => {
piece.classList.remove('selected');
});
+
+ this.selectedPiece = null; // Reset the selected piece
};
-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 player clicks on a piece of the same color, allow reselection
+ if (piece.color === this.selectedPiece.color) {
+ console.log(`Reselecting your own piece.`);
+ this.selectPiece(event.target, piece); // Reselect the new piece
+ return;
+ } else {
+ // 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(); // Switch turn after a valid move
+ }
+ } else {
+ // 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(); // Switch turn after a valid move
+ }
+ } 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 +122,100 @@ 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) {
+ // First clear any existing selection
+ this.clearSelection();
+
+ // Highlight the new selected piece only
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/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
diff --git a/public/javascript/chess/pieces/king.js b/public/javascript/chess/pieces/king.js
index 41aed5f..c7af5ee 100644
--- a/public/javascript/chess/pieces/king.js
+++ b/public/javascript/chess/pieces/king.js
@@ -1,11 +1,58 @@
-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({});
-King.prototype.move = function(newPosition){
+ 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)
+ );
-}
\ No newline at end of file
+ // King can move one square in any direction (horizontal, vertical, or diagonal)
+ if (rowDifference <= 1 && colDifference <= 1) {
+ return true; // Valid king move
+ }
+
+ // 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
+ )
+ if (this.isValidMove(targetPosition)) {
+ this.position = targetPosition.col + targetPosition.row;
+ this.render();
+ } else {
+ console.log("Invalid move for king");
+ }
+};
diff --git a/public/javascript/chess/pieces/knight.js b/public/javascript/chess/pieces/knight.js
index 3957e36..3b8027b 100644
--- a/public/javascript/chess/pieces/knight.js
+++ b/public/javascript/chess/pieces/knight.js
@@ -3,9 +3,40 @@ var Knight = function(config){
this.constructor(config);
};
+Knight.prototype = new Piece({});
+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;
+
+ 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;
+ }
+};
+
+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();
+};
-Knight.prototype = new Piece({});
-Knight.prototype.move = function(newPosition){
-}
\ No newline at end of file
diff --git a/public/javascript/chess/pieces/pawn.js b/public/javascript/chess/pieces/pawn.js
index b8b2460..d408dd9 100644
--- a/public/javascript/chess/pieces/pawn.js
+++ b/public/javascript/chess/pieces/pawn.js
@@ -1,14 +1,51 @@
-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)) {
+ 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;
+ 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({});
+// Validate the Pawn's move
+Pawn.prototype.isValidMove = function(targetPosition) {
+ return this.isStraightMove(targetPosition) || this.isDiagonalCapture(targetPosition);
+};
-Pawn.prototype.isValidPosition = function(targetPosition){
- // Convert current position to row and column
+// 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));
@@ -16,33 +53,32 @@ 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
+ // Straight movement (no column change)
if (targetPosition.col === currentCol) {
- // Moving straight
+ // Regular one-square move
if (targetPosition.row === (currentRow + moveDistance).toString()) {
- // Regular one-square move
return true;
- } else if (currentRow === initialRow && targetPosition.row === (currentRow + 2 * moveDistance).toString()) {
- // Initial two-square move
+ }
+ // Initial two-square move
+ else if (currentRow === initialRow && targetPosition.row === (currentRow + 2 * moveDistance).toString()) {
return true;
}
- } 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;
}
- // 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
+};
-Pawn.prototype.moveTo = function(targetPosition){
- if(this.isValidPosition(targetPosition)){
- this.position = targetPosition.col + targetPosition.row;
- this.render();
- }else{
- //NOOP
+// 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));
+
+ // 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
}
-
-}
\ No newline at end of file
+
+ 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