From ed35a2e86fc0a3eb61bb3f30068603a9fc64fb05 Mon Sep 17 00:00:00 2001 From: jheaps Date: Fri, 28 Mar 2025 10:41:29 -0600 Subject: [PATCH] Add pawn promotion --- JoshHeaps.Net/Pages/Chess.cshtml | 18 ++++++ JoshHeaps.Net/Pages/_Layout.cshtml | 2 +- JoshHeaps.Net/wwwroot/css/chess/game.css | 61 ++++++++++++++++++- .../wwwroot/js/ChessScripts/chessLogic.js | 48 ++++++++++++++- 4 files changed, 124 insertions(+), 5 deletions(-) diff --git a/JoshHeaps.Net/Pages/Chess.cshtml b/JoshHeaps.Net/Pages/Chess.cshtml index bf7653a..079416f 100644 --- a/JoshHeaps.Net/Pages/Chess.cshtml +++ b/JoshHeaps.Net/Pages/Chess.cshtml @@ -26,6 +26,24 @@ + + @section Scripts { diff --git a/JoshHeaps.Net/Pages/_Layout.cshtml b/JoshHeaps.Net/Pages/_Layout.cshtml index 9ba0d4c..207e85a 100644 --- a/JoshHeaps.Net/Pages/_Layout.cshtml +++ b/JoshHeaps.Net/Pages/_Layout.cshtml @@ -1,6 +1,6 @@ @{ Layout = null; - ViewData["cssVersion"] = "1.0.1"; // <--- change this once to bust cache + ViewData["cssVersion"] = "1.0.2"; // <--- change this once to bust cache } diff --git a/JoshHeaps.Net/wwwroot/css/chess/game.css b/JoshHeaps.Net/wwwroot/css/chess/game.css index f285207..5668292 100644 --- a/JoshHeaps.Net/wwwroot/css/chess/game.css +++ b/JoshHeaps.Net/wwwroot/css/chess/game.css @@ -33,10 +33,16 @@ box-sizing: border-box; } -.chessSquare.legal { - border: 4px dashed red; +.legalOverlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; /* Let clicks go through */ box-sizing: border-box; - cursor: pointer; + border: 4px dashed red; + z-index: 10; } #chessBoard.flipped { @@ -46,9 +52,58 @@ .chessSquare.previous-start { box-sizing: border-box; border: 4px solid #ffd700; /* gold or whatever you like */ + z-index: 1; } .chessSquare.previous-end { box-sizing: border-box; border: 4px solid #ff8c00; /* orange */ + z-index: 1; +} + +#promotionModal { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #1e1e1e; + padding: 20px; + border-radius: 10px; + box-shadow: 0 0 20px rgba(0,0,0,0.6); + color: white; + z-index: 1000; + text-align: center; +} + +#promotionModal p { + margin-bottom: 15px; + font-size: 18px; + font-weight: bold; +} + +#promotionBtnContainer { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 10px; + justify-content: center; +} + +#promotionBtnContainer button { + background-color: #2c2c2c; + border: none; + padding: 10px; + border-radius: 8px; + cursor: pointer; + transition: transform 0.2s ease; +} + +#promotionBtnContainer button:hover { + transform: scale(1.1); + background-color: #3a3a3a; +} + +#promotionBtnContainer img { + width: 50px; + height: 50px; + pointer-events: none; /* ensures img doesn't steal the click */ } \ No newline at end of file diff --git a/JoshHeaps.Net/wwwroot/js/ChessScripts/chessLogic.js b/JoshHeaps.Net/wwwroot/js/ChessScripts/chessLogic.js index 9350141..260c1c3 100644 --- a/JoshHeaps.Net/wwwroot/js/ChessScripts/chessLogic.js +++ b/JoshHeaps.Net/wwwroot/js/ChessScripts/chessLogic.js @@ -137,6 +137,10 @@ function highlightLegalMoves(moves) { const img = square.querySelector("img"); if (img) img.onclick = null; + let overlay = document.createElement("div"); + overlay.className = "legalOverlay"; + square.appendChild(overlay); + // Let the square itself handle the move square.onclick = () => handleMove(r, c); }); @@ -145,6 +149,18 @@ function highlightLegalMoves(moves) { async function handleMove(targetRow, targetCol) { if (!selectedPiece) return; + const isPawn = selectedPiece.type === 0; // Assuming 0 = pawn + const reachedEnd = (Number(selectedPiece.color) === 0 && Number(targetRow) === 0) || + (Number(selectedPiece.color) === 1 && Number(targetRow) === 0); + + let choice = null; + + if (isPawn && reachedEnd) { + // Show promotion UI + choice = await promptPromotion(); // function you’ll define + if (!choice) return; // user cancelled? + } + [targetRow, targetCol] = flipCoordinates(targetRow, targetCol); const moveDto = { @@ -155,7 +171,7 @@ async function handleMove(targetRow, targetCol) { SourceCol: selectedPiece.col, TargetRow: targetRow, TargetCol: targetCol, - PromotionChoice: null // optional + PromotionChoice: choice }; previousMoveStart = [selectedPiece.row, selectedPiece.col]; @@ -190,6 +206,10 @@ function clearHighlights() { for (let i = 0; i < 64; i++) { const square = document.getElementById(`square-${i}`); + // Remove legal overlays + const overlay = square.querySelector(".legalOverlay"); + if (overlay) square.removeChild(overlay); + // Remove legal move markers and their onclicks if (square.classList.contains("legal")) { square.classList.remove("legal"); @@ -273,6 +293,32 @@ async function setupSignalRConnection() { } } +function promptPromotion() { + return new Promise(resolve => { + + let color = 1; + if (currentPlayerIsWhite) + color = 0; + + updatePromotionModalImages(color); + + document.getElementById("promotionModal").style.display = "block"; + window.selectPromotion = (piece) => { + document.getElementById("promotionModal").style.display = "none"; + resolve(piece); + }; + }); +} + +function updatePromotionModalImages(color) { + const pieceNames = ["Queen", "Rook", "Bishop", "Knight"]; + const buttons = document.querySelectorAll("#promotionModal button img"); + + buttons.forEach((img, index) => { + img.src = `/images/Chess Images/${color === 0 ? "White" : "Black"}${pieceNames[index]}.svg`; + }); +} + console.log("chessLogic.js loaded"); window.startNewGame = startNewGame;