Skip to content

Commit

Permalink
Merge pull request #5 from RiteshS1/final
Browse files Browse the repository at this point in the history
some final tweaks
  • Loading branch information
RiteshS1 authored Nov 13, 2024
2 parents aacfcda + 738278d commit 32f9d54
Show file tree
Hide file tree
Showing 3 changed files with 269 additions and 0 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chessical</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css">
</head>
<body>
Expand Down
180 changes: 180 additions & 0 deletions scripts/board.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ let whiteKingsideRookMoved = false;
let whiteQueensideRookMoved = false;
let blackKingsideRookMoved = false;
let blackQueensideRookMoved = false;
let selectedPiece = null;
let selectedSquare = null;

function initBoard() {
const initialBoard = [
Expand Down Expand Up @@ -64,6 +66,8 @@ function initBoard() {
document.querySelectorAll('.piece').forEach(piece => {
piece.addEventListener('dragstart', handleDragStart);
});

initializeTouchAndClickEvents();
}

function handleDragStart(event) {
Expand Down Expand Up @@ -160,6 +164,7 @@ function handleDrop(event) {
}

targetSquare.appendChild(draggedPiece);
handlePawnPromotion(targetSquare, draggedPiece);

const currentPosition = getCurrentPosition();

Expand All @@ -174,6 +179,16 @@ function handleDrop(event) {

updateTurn();
updateEvaluationBar();

// Add checkmate detection here
const pieceColor = draggedPiece.getAttribute('data-piece').split('_')[0];
const opponentIsWhite = pieceColor === 'black';

if (isCheckmate(opponentIsWhite)) {
setTimeout(() => {
showGameEndModal(`${pieceColor.charAt(0).toUpperCase() + pieceColor.slice(1)} wins by checkmate!`);
}, 100); // Small delay to ensure the UI updates first
}
}

draggedPiece.classList.remove('dragging');
Expand Down Expand Up @@ -560,3 +575,168 @@ function doesMoveResolveCheck(piece, sourceIndex, targetIndex) {

// Initialize the board with pieces and listeners
initBoard();

// Add this function after handleDrop
function handlePawnPromotion(square, piece) {
const row = Math.floor(parseInt(square.getAttribute('data-index')) / 8);
const pieceColor = piece.getAttribute('data-piece').split('_')[0];

// Check if pawn reached the opposite end
if (piece.getAttribute('data-piece').includes('pawn') &&
((pieceColor === 'white' && row === 0) || (pieceColor === 'black' && row === 7))) {

// Create and show promotion modal
const modal = document.createElement('div');
modal.className = 'promotion-modal';

// Add promotion piece options
const pieces = ['queen', 'rook', 'bishop', 'knight'];
pieces.forEach(pieceType => {
const option = document.createElement('img');
option.src = `${piecesFolder}${pieceColor}_${pieceType}.png`;
option.className = 'promotion-option';
option.addEventListener('click', () => {
// Update the piece
piece.src = option.src;
piece.setAttribute('data-piece', `${pieceColor}_${pieceType}`);
modal.remove();
updateBoardState();
updateEvaluationBar();
});
modal.appendChild(option);
});

document.body.appendChild(modal);
}
}

// Add these functions after your existing isKingInCheck function
function isCheckmate(isWhiteKing) {
// First verify the king is in check
const kingPos = findKingPosition(isWhiteKing);
if (!kingPos || !isKingInCheck(kingPos.row, kingPos.col, isWhiteKing)) {
return false;
}

// Generate all possible moves
const allMoves = generateAllPossibleMoves(isWhiteKing);

// Try each move to see if it gets out of check
for (const move of allMoves) {
const sourceSquare = document.querySelector(`[data-index="${move.from}"]`);
const piece = sourceSquare.querySelector('.piece');
if (doesMoveResolveCheck(piece, move.from, move.to)) {
return false;
}
}

return true;
}

function showGameEndModal(message) {
const modal = document.createElement('div');
modal.className = 'promotion-modal'; // Reuse the promotion modal styling

const messageElement = document.createElement('p');
messageElement.textContent = message;
messageElement.style.textAlign = 'center';
messageElement.style.marginBottom = '10px';

const newGameButton = document.createElement('button');
newGameButton.textContent = 'New Game';
newGameButton.style.padding = '5px 10px';
newGameButton.onclick = () => {
location.reload();
};

modal.appendChild(messageElement);
modal.appendChild(newGameButton);
document.body.appendChild(modal);
}

function initializeTouchAndClickEvents() {
// Add click handlers to all squares
document.querySelectorAll('.square').forEach(square => {
square.addEventListener('click', handleSquareClick);
});
}

function handleSquareClick(event) {
const square = event.currentTarget;
const piece = square.querySelector('.piece');

// If no piece is selected
if (!selectedPiece) {
if (piece) {
// Select the piece
selectedPiece = piece;
selectedSquare = square;
square.classList.add('selected-square');
}
return;
}

// If a piece is already selected
if (selectedPiece) {
const sourceIndex = parseInt(selectedSquare.getAttribute('data-index'));
const targetIndex = parseInt(square.getAttribute('data-index'));

// Clear previous selection
selectedSquare.classList.remove('selected-square');

// If clicking the same square, deselect the piece
if (square === selectedSquare) {
selectedPiece = null;
selectedSquare = null;
return;
}

// Try to make the move
if (isValidMove(selectedPiece, sourceIndex, targetIndex)) {
const targetPiece = square.querySelector('.piece');

// Handle capture
if (targetPiece) {
const capturedPieceColor = targetPiece.getAttribute('data-piece').split('_')[0];
if (capturedPieceColor === selectedPiece.getAttribute('data-piece').split('_')[0]) {
selectedPiece = null;
selectedSquare = null;
return;
}
targetPiece.remove();

if (capturedPieceColor === 'white') {
capturedWhitePieces.push(targetPiece);
} else {
capturedBlackPieces.push(targetPiece);
}

displayCapturedPieces();
}

// Move the piece
square.appendChild(selectedPiece);
handlePawnPromotion(square, selectedPiece);

const currentPosition = getCurrentPosition();
positionHistory.push(currentPosition);

updateTurn();
updateEvaluationBar();

// Check for checkmate
const pieceColor = selectedPiece.getAttribute('data-piece').split('_')[0];
const opponentIsWhite = pieceColor === 'black';

if (isCheckmate(opponentIsWhite)) {
setTimeout(() => {
showGameEndModal(`${pieceColor.charAt(0).toUpperCase() + pieceColor.slice(1)} wins by checkmate!`);
}, 100);
}
}

// Reset selection
selectedPiece = null;
selectedSquare = null;
}
}
88 changes: 88 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,92 @@ h1{
background: rgba(255, 255, 255, 0.8);
padding: 2px 4px;
border-radius: 3px;
}

.promotion-modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border: 2px solid #333;
border-radius: 8px;
display: flex;
gap: 10px;
z-index: 1000;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
}

.promotion-option {
width: 60px;
height: 60px;
cursor: pointer;
transition: transform 0.2s;
}

.promotion-option:hover {
transform: scale(1.1);
}

/* Add responsive design */
@media (max-width: 768px) {
#board {
width: 100vw;
height: 100vw;
max-width: 640px;
max-height: 640px;
}

.square {
width: 12.5vw;
height: 12.5vw;
max-width: 80px;
max-height: 80px;
}

.piece {
width: 100%;
height: 100%;
}

#evaluation-bar {
right: 10px;
height: 300px;
}

.captured-pieces {
padding: 2px;
}

.captured-pieces .piece {
width: 30px;
height: 30px;
}
}

/* Add touch support */
@media (hover: none) {
.square:hover {
background-color: inherit;
}

.square.touch-selected {
background-color: #c8e6c9;
}
}

.selected-square {
background-color: rgba(255, 255, 0, 0.4) !important;
}

/* Improve touch targets */
@media (hover: none) {
.square:hover {
background-color: inherit;
}

.piece {
-webkit-tap-highlight-color: transparent;
}
}

0 comments on commit 32f9d54

Please sign in to comment.