From 04b975eb1c6ea0cff7ceb800c948d524385efe35 Mon Sep 17 00:00:00 2001 From: Nikhildhasmana89 Date: Thu, 2 Apr 2026 20:08:43 +0530 Subject: [PATCH] Develop a JavaScript Tic-Tac-Toe app --- Tic Tac Toe/index.html | 41 ++++++++ Tic Tac Toe/script.js | 234 +++++++++++++++++++++++++++++++++++++++++ Tic Tac Toe/style.css | 163 ++++++++++++++++++++++++++++ 3 files changed, 438 insertions(+) create mode 100644 Tic Tac Toe/index.html create mode 100644 Tic Tac Toe/script.js create mode 100644 Tic Tac Toe/style.css diff --git a/Tic Tac Toe/index.html b/Tic Tac Toe/index.html new file mode 100644 index 0000000..042c791 --- /dev/null +++ b/Tic Tac Toe/index.html @@ -0,0 +1,41 @@ + + + + + Tic Tac Toe Pro + + + +
+

🎮 Tic Tac Toe

+ +
+ + + + + +
+ + +
+ + + + diff --git a/Tic Tac Toe/script.js b/Tic Tac Toe/script.js new file mode 100644 index 0000000..ce5bbae --- /dev/null +++ b/Tic Tac Toe/script.js @@ -0,0 +1,234 @@ +const board = document.getElementById("board"); +const statusText = document.getElementById("status"); + +let cells = []; +let currentPlayer = "X"; +let isGameRunning = true; +let gameMode = "2"; + +let scoreX = 0; +let scoreO = 0; +let totalGames = 1; + +let playerXName = "Player X"; +let playerOName = "Player O"; + +// Start game +function startGame(mode) { + gameMode = mode; + + // Get player names + playerXName = document.getElementById("playerX").value || "Player X"; + + if (gameMode === "1") { + playerOName = "Computer 🤖"; + } else { + playerOName = document.getElementById("playerO").value || "Player O"; + } + + // Show name on screen + document.getElementById("nameX").textContent = playerXName; + document.getElementById("nameO").textContent = playerOName; + + // Hide setup and show game + + document.getElementById("setup").style.display = "none"; + document.getElementById("game").style.display = "block"; + + resetGame(true); +} + +// Create board +function createBoard() { + board.innerHTML = ""; + cells = []; + + for (let i = 0; i < 9; i++) { + let cell = document.createElement("div"); + cell.classList.add("cell"); + + cell.addEventListener("click", function () { + handleMove(i); + }); + + board.appendChild(cell); + cells.push(cell); + } +} + +// Handle player move + +function handleMove(index) { + if (!isGameRunning || cells[index].textContent !== "") return; + + // Put X or O + cells[index].textContent = currentPlayer; + cells[index].classList.add(currentPlayer); + + // Check win + if (checkWinner()) { + let winnerName = currentPlayer === "X" ? playerXName : playerOName; + + statusText.textContent = winnerName + " Wins! 🎉"; + + updateScore(currentPlayer); + endRound(); + return; + } + + // Check draw + if (isBoardFull()) { + statusText.textContent = "Draw!"; + endRound(); + return; + } + + // Switch player + if (currentPlayer === "X") { + currentPlayer = "O"; + } else { + currentPlayer = "X"; + } + + // AI move + if (gameMode === "1" && currentPlayer === "O") { + setTimeout(makeAIMove, 500); + } +} + +// AI Section + +function makeAIMove() { + let emptyCells = []; + + // find empty cells + for (let i = 0; i < cells.length; i++) { + if (cells[i].textContent === "") { + emptyCells.push(i); + } + } + + let randomIndex = emptyCells[Math.floor(Math.random() * emptyCells.length)]; + + handleMove(randomIndex); +} + +// check winner section +function checkWinner() { + const patterns = [ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + [0, 3, 6], + [1, 4, 7], + [2, 5, 8], + [0, 4, 8], + [2, 4, 6], + ]; + + for (let pattern of patterns) { + let a = pattern[0]; + let b = pattern[1]; + let c = pattern[2]; + + if ( + cells[a].textContent !== "" && + cells[a].textContent === cells[b].textContent && + cells[a].textContent === cells[c].textContent + ) { + // Highlight winning cells + cells[a].classList.add("win"); + cells[b].classList.add("win"); + cells[c].classList.add("win"); + + return true; + } + } + + return false; +} + +// Draw section + +function isBoardFull() { + for (let cell of cells) { + if (cell.textContent === "") { + return false; + } + } + return true; +} + +// Update score section + +function updateScore(player) { + if (player === "X") { + scoreX++; + document.getElementById("scoreX").textContent = scoreX; + } else { + scoreO++; + document.getElementById("scoreO").textContent = scoreO; + } +} + +// End round + +function endRound() { + isGameRunning = false; + + //If someone win 3 times or 5 games will end the game + if (scoreX === 3 || scoreO === 3 || totalGames === 5) { + setTimeout(showFinalResult, 500); + return; + } + + setTimeout(() => { + totalGames++; + document.getElementById("gameCount").textContent = totalGames; + resetBoard(); + }, 1000); +} + +// Final result + +function showFinalResult() { + if (scoreX > scoreO) { + statusText.textContent = "🏆 " + playerXName + " Wins Series!"; + } else if (scoreO > scoreX) { + statusText.textContent = "🏆 " + playerOName + " Wins Series!"; + } else { + statusText.textContent = "Series Draw!"; + } +} + +// Reset Board + +function resetBoard() { + for (let cell of cells) { + cell.textContent = ""; + cell.classList.remove("X", "O", "win"); + } + + currentPlayer = "X"; + isGameRunning = true; + statusText.textContent = ""; +} + +// Reset Game + +function resetGame(fullReset = false) { + if (fullReset) { + scoreX = 0; + scoreO = 0; + totalGames = 1; + + document.getElementById("scoreX").textContent = 0; + document.getElementById("scoreO").textContent = 0; + document.getElementById("gameCount").textContent = 1; + } + + createBoard(); + resetBoard(); +} + +createBoard(); diff --git a/Tic Tac Toe/style.css b/Tic Tac Toe/style.css new file mode 100644 index 0000000..0acc293 --- /dev/null +++ b/Tic Tac Toe/style.css @@ -0,0 +1,163 @@ +body { + margin: 0; + font-family: "Poppins", sans-serif; + background: linear-gradient(135deg, #1e1e2f, #3a3a5a); + color: white; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.container { + background: rgba(255, 255, 255, 0.08); + padding: 30px; + border-radius: 20px; + backdrop-filter: blur(10px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); + text-align: center; + width: 350px; +} + +h1 { + margin-bottom: 20px; + font-size: 28px; + letter-spacing: 1px; +} + +input { + width: 100%; + padding: 12px; + margin: 8px 0; + border-radius: 10px; + border: none; + outline: none; + font-size: 14px; + background: #f1f1f1; +} + +button { + padding: 12px; + margin: 10px 5px; + border: none; + border-radius: 10px; + cursor: pointer; + font-size: 14px; + transition: 0.3s; +} + +button:hover { + transform: scale(1.05); +} + +.start-btn { + background: #4caf50; + color: white; +} + +.ai-btn { + background: #ff9800; + color: white; +} + +.board { + display: grid; + grid-template-columns: repeat(3, 80px); + gap: 10px; + justify-content: center; + margin: 20px auto; +} + +.cell { + width: 80px; + height: 80px; + background: white; + color: black; + font-size: 30px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + border-radius: 12px; + transition: 0.2s; +} + +.cell:hover { + background: #e0e0e0; +} + +.scoreboard { + margin-top: 10px; + font-size: 14px; +} + +#status { + margin-top: 10px; + font-weight: bold; +} + +.container { + border: 1px solid rgba(255, 255, 255, 0.1); +} + +button { + font-weight: 600; + letter-spacing: 0.5px; +} + +.start-btn { + background: linear-gradient(135deg, #4caf50, #2e7d32); +} + +.ai-btn { + background: linear-gradient(135deg, #ff9800, #ef6c00); +} + +button:hover { + transform: scale(1.07); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4); +} + +.cell { + font-weight: bold; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); +} + +.cell.X { + color: #4caf50; +} + +.cell.O { + color: #ff9800; +} + +.cell:active { + transform: scale(0.9); +} + +#status { + margin-top: 15px; + font-size: 16px; + letter-spacing: 1px; +} + +.series-result { + margin-top: 8px; + font-size: 13px; + opacity: 0.8; +} + +.win { + background: #4caf50 !important; + color: white !important; + animation: glow 0.8s infinite alternate; +} + +@keyframes glow { + from { + box-shadow: 0 0 5px #4caf50; + } + to { + box-shadow: 0 0 20px #4caf50; + } +}