diff --git a/app.js b/app.js index 14a5587..443bca5 100644 --- a/app.js +++ b/app.js @@ -1,424 +1,316 @@ -let play_board = ["", "", "", "", "", "", "", "", ""]; -let player = "O"; -let computer = "X"; -let gameMode = 1; // 1 is for single Player; 2 is for 2 Players -let board_full = false; -let ai_level; -let lastMove = null; // Variable to store the last move - -const render_board = () => { - const board_container = document.querySelector(".play-area"); +document.addEventListener("DOMContentLoaded", () => { + let play_board = ["", "", "", "", "", "", "", "", ""]; + let player_symbol = "X"; // The human player is always X + let computer_symbol = "O"; // The computer is always O + let currentPlayer = "X"; // Track whose turn it is + let gameMode = 1; // 1: Single Player, 2: Two Players + let board_full = false; + let lastMove = null; + let scores = { player1: 0, player2: 0, draw: 0 }; + + const board_container = document.querySelector(".play-area"); + const winner_statement = document.getElementById("winner"); + const ai_select = document.getElementById("ai_level"); + const instructionsPopup = document.getElementById("instructions-popup"); + const mainContent = document.querySelector(".main-content"); + const player1_label = document.getElementById("Player1"); + const player2_label = document.getElementById("Player2"); + const move_indicator = document.getElementById("move"); + const audioPlayer = document.getElementById("myAudio"); + + const render_board = () => { board_container.innerHTML = ""; - play_board.forEach((e, i) => { - board_container.innerHTML += `
${play_board[i]}
`; - if (e == player || e == computer) { - document.querySelector(`#block_${i}`).classList.add("occupied"); - } - }); -}; - -const configure_ai = () => { - let ai_select = document.querySelector("#ai_level"); - ai_level = Array.from(ai_select.options).filter(option => option.defaultSelected == true)[0].value; - ai_select.addEventListener("change", event => { - ai_level = event.target.options[event.target.selectedIndex].value; + play_board.forEach((value, i) => { + const block = document.createElement("div"); + block.id = `block_${i}`; + block.classList.add("block"); + block.textContent = value; + if (value) { + block.classList.add("occupied"); + } + block.addEventListener("click", () => addPlayerMove(i)); + board_container.appendChild(block); }); -}; - -FBInstant.initializeAsync() - .then(function () { - var progress = 0; - var interval = setInterval(function () { - if (progress >= 95) { - clearInterval(interval); - FBInstant.startGameAsync().then( - function () { - console.log("Game Loaded"); - } - ) - }; - FBInstant.setLoadingProgress(progress); - progress += 5; - }, 100); - } - ); - -// RESET GAME TO TWO PLAYER MODE -const twoPlayer = () => { - document.getElementById("Player1").innerHTML = " Player 1(O)"; - document.getElementById("Player2").innerHTML = " Player 2(X)"; - gameMode = 2; - reset_board(); -} -//RESET GAME TO SINGLE PLAYER MODE -const singlePlayer = () => { - document.getElementById("Player1").innerHTML = " Player"; - document.getElementById("Player2").innerHTML = " Computer"; - gameMode = 1; - player = "O"; //DEFAULT PLAYER SETTINGS FOR SINGLE PLAYER - computer = "X"; - reset_board(); -} - -render_board(); -configure_ai(); - -//setTimeout(render_board(), 3000); - -const checkBoardComplete = () => { - let flag = true; - play_board.forEach(element => { - if (element == "") { - flag = false; - } - }); - board_full = flag; -}; + }; -const game_loop = () => { + const game_loop = () => { render_board(); checkBoardComplete(); checkWinner(); -} -//FUNCTION TO DISPLAY WHOSE MOVE IT IS (Player/Computer/Player 1/2) -const showPlayer = (mode, player) => { - if (mode == 1) { // mode 1 is single Player - if (player == 1) document.getElementById("move").innerHTML = "Player Move!"; - } - else { // Mode == 2 for 2 Players - if (player == 1) document.getElementById("move").innerHTML = "Player 1 Move!"; - else document.getElementById("move").innerHTML = "Player 2 Move"; - } + }; -} -const randomizeStart = () => { - if (play_board.every(item => item === "")) { - // const PLAYER = 0; - const COMPUTER = 1; - const start = Math.round(Math.random()); - if (start === COMPUTER) { - if (gameMode == 1) { addComputerMove(ai_level); } - else { showPlayer(2, 2) } - console.log("COMPUTER STARTED") - } else { - if (gameMode == 1) showPlayer(1, 1); - else showPlayer(2, 1); - console.log("PLAYER STARTS") - } - } -} -const addPlayerMove = e => { - if (play_board[e] == "" && !board_full) { - document.querySelector("#ai_level").disabled = true; - // Store the current state in the move history - lastMove = [...play_board]; - play_board[e] = player; - game_loop(); - if (gameMode == 1) { - addComputerMove(ai_level); - showPlayer(1, 1); - } else { - // Toggle player - player changer - if (player == "X") { - player = "O"; - showPlayer(2, 1); - } else { - player = "X"; - showPlayer(2, 2); - } - } + const checkBoardComplete = () => { + board_full = play_board.every((element) => element !== ""); + }; + + const addPlayerMove = (i) => { + if (play_board[i] !== "" || board_full) { + return; // Can't move here } -}; -// Function to undo the last move -const undoLastMove = () => { - if (lastMove !== null) { - play_board = [...lastMove]; - lastMove = null; - game_loop(); + ai_select.disabled = true; + lastMove = [...play_board]; + play_board[i] = currentPlayer; + + if (gameMode === 1) { + // Single Player + game_loop(); + if (!board_full) { + currentPlayer = computer_symbol; + showPlayer(); + setTimeout(() => addComputerMove(), 500); + } + } else { + // Two Players + currentPlayer = + currentPlayer === player_symbol ? computer_symbol : player_symbol; + game_loop(); + showPlayer(); } -}; - -const addComputerMove = (ai_level) => { - if (!board_full) { - let score; - let compare; - switch (ai_level) { - case "hard": - score = -Infinity; - compare = (a, b) => a > b; - break; - case "easy": - score = Infinity; - compare = (a, b) => a < b; - break; - case "normal": - let guess = Math.random() * 100; - if (guess <= 40) { - score = Infinity; - compare = (a, b) => a < b; - } - else { - score = -Infinity; - compare = (a, b) => a > b; - } - break; - } - let nextMove; - for (let i = 0; i < play_board.length; i++) { - if (play_board[i] == "") { - play_board[i] = computer; - let endScore = minimax(play_board, 0, false); - play_board[i] = ""; - if (compare(endScore, score)) { - score = endScore; - nextMove = i; - } - } + }; + + const addComputerMove = () => { + if (board_full) return; + + let bestMove = getBestMove(); + play_board[bestMove] = computer_symbol; + currentPlayer = player_symbol; + game_loop(); + showPlayer(); + }; + + const getBestMove = () => { + // AI logic here (minimax) + let bestScore = -Infinity; + let move; + for (let i = 0; i < 9; i++) { + if (play_board[i] === "") { + play_board[i] = computer_symbol; + let score = minimax(play_board, 0, false); + play_board[i] = ""; + if (score > bestScore) { + bestScore = score; + move = i; } - play_board[nextMove] = computer; - game_loop(); + } } -} - -let scores = { X: 1, O: -1, tie: 0 }; + return move; + }; -const minimax = (board, isMaximizing) => { - let res = check_match(); - if (res != "") { - return scores[res]; + const minimaxScores = { [computer_symbol]: 1, [player_symbol]: -1, tie: 0 }; + const minimax = (board, depth, isMaximizing) => { + let result = check_match(); + if (result !== null) { + return minimaxScores[result]; } + if (isMaximizing) { - let bestScore = -Infinity; - for (let i = 0; i < board.length; i++) { - if (board[i] == "") { - board[i] = computer; - let score = minimax(board, false); - board[i] = ""; - bestScore = Math.max(score, bestScore); - } + let bestScore = -Infinity; + for (let i = 0; i < 9; i++) { + if (board[i] === "") { + board[i] = computer_symbol; + let score = minimax(board, depth + 1, false); + board[i] = ""; + bestScore = Math.max(score, bestScore); } - return bestScore; + } + return bestScore; } else { - let bestScore = Infinity; - for (let i = 0; i < board.length; i++) { - if (board[i] == "") { - board[i] = player; - let score = minimax(board, true); - board[i] = ""; - bestScore = Math.min(score, bestScore); - } - } - return bestScore; - } -} - -var temp1 = 0; -var temp2 = 0; -var temp3 = 0; -var temp4 = 0; -var temp5 = 0; -var temp6 = 0; - -var endMusic = null; //the Audio object for the music at the end of the game - -const checkWinner = () => { - let res = check_match(); - var playerstat1 = 0; - var computerstat1 = 0; - var loss1 = 0; - var loss2 = 0; - var draw1 = 0; - var draw2 = 0; - - const winner_statement = document.getElementById("winner"); - const audio = document.querySelector("audio"); - - if (res == "O") { - if (gameMode == 1) winner_statement.innerText = "Player Won"; // Single player mode - else winner_statement.innerText = "Player 1 Won"; // 2 player mode - winner_statement.classList.add("playerWin"); - board_full = true; - playerstat1++; - loss2++; - temp1 += playerstat1; - temp3 += loss2; - console.log("player win"); - audio.pause(); - if (!x.muted) { - endMusic = new Audio("audio/win.wav"); - endMusic.play(); - } - } - else if (res == "X") { - if (gameMode == 1) winner_statement.innerText = "Computer Won"; // Single player mode - else winner_statement.innerText = "Player 2 Won"; // 2 player mode - winner_statement.classList.add("computerWin"); - board_full = true; - computerstat1++; - loss1++; - temp2 += computerstat1; - temp4 += loss1; - console.log("computer win"); - audio.pause(); - if (!x.muted) { - endMusic = new Audio("audio/gameover.wav"); - endMusic.play(); - } - } - else if (board_full) { - winner_statement.innerText = "Draw..."; - winner_statement.classList.add("draw"); - draw1++; - draw2++; - temp5 += draw1; - temp6 += draw2; - console.log("draw"); - audio.pause(); - if (!x.muted) { - endMusic = new Audio("audio/gameover.wav"); - endMusic.play(); + let bestScore = Infinity; + for (let i = 0; i < 9; i++) { + if (board[i] === "") { + board[i] = player_symbol; + let score = minimax(board, depth + 1, true); + board[i] = ""; + bestScore = Math.min(score, bestScore); } + } + return bestScore; } + }; - // Update the scoreboard - document.getElementById("playerstat1").innerText = temp1; - document.getElementById("computerstat1").innerText = temp2; - document.getElementById("loss1").innerText = temp4; - document.getElementById("loss2").innerText = temp3; - document.getElementById("draw1").innerText = temp5; - document.getElementById("draw2").innerText = temp6; - - // Play end music only if not muted - if (endMusic && !x.muted) { - audio.play(); + const showPlayer = () => { + if (board_full) return; + if (gameMode === 1) { + move_indicator.innerHTML = + currentPlayer === player_symbol ? "Your Move!" : "Computer's Move..."; + } else { + move_indicator.innerHTML = `Player ${ + currentPlayer === player_symbol ? 1 : 2 + }'s Move!`; } -}; + }; + const checkWinner = () => { + let result = check_match(); + if (result === null) return; -var x = document.getElementById("myAudio"); + board_full = true; + audioPlayer.pause(); -const muteAudio = () => { - const btn = document.getElementById("btn-sound"); - - if (!x) { - console.error("Audio element 'x' not found."); - return; - } - - // Toggle mute state - const isMuted = !x.muted; - x.muted = isMuted; - - // Check if endMusic is defined before muting/unmuting - if (endMusic) { - endMusic.muted = isMuted; + if (result === "tie") { + winner_statement.innerText = "It's a Draw!"; + winner_statement.classList.add("draw"); + scores.draw++; + } else { + const winnerName = + result === player_symbol + ? gameMode === 1 + ? "Player" + : "Player 1" + : gameMode === 1 + ? "Computer" + : "Player 2"; + + winner_statement.innerText = `${winnerName} Won!`; + winner_statement.classList.add( + result === player_symbol ? "playerWin" : "computerWin" + ); + + if (result === player_symbol) scores.player1++; + else scores.player2++; } - - // Update the button icon dynamically - btn.innerHTML = isMuted - ? `` - : ``; + updateScoreboard(); }; - - -const check_line = (a, b, c) => { - let status = - play_board[a] == play_board[b] && - play_board[b] == play_board[c] && - (play_board[a] == player || play_board[a] == computer); - if (status) { - document.getElementById(`block_${a}`).classList.add("won"); - document.getElementById(`block_${b}`).classList.add("won"); - document.getElementById(`block_${c}`).classList.add("won"); - } - return status; -}; -const check_match = () => { - for (let i = 0; i < 9; i += 3) { - if (check_line(i, i + 1, i + 2)) { - return play_board[i]; - } - } - for (let i = 0; i < 3; i++) { - if (check_line(i, i + 3, i + 6)) { - return play_board[i]; - } + const check_match = () => { + const winConditions = [ + [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 combo of winConditions) { + const [a, b, c] = combo; + if ( + play_board[a] && + play_board[a] === play_board[b] && + play_board[a] === play_board[c] + ) { + return play_board[a]; + } } - if (check_line(0, 4, 8)) { - return play_board[0]; - } - if (check_line(2, 4, 6)) { - return play_board[2]; - } - checkBoardComplete(); - if (board_full) return "tie"; - return ""; -} + return play_board.includes("") ? null : "tie"; + }; -const reset_board = () => { - const winner_statement = document.getElementById("winner"); + const updateScoreboard = () => { + document.getElementById("playerstat1").innerText = scores.player1; // Player 1/Player Wins + document.getElementById("computerstat1").innerText = scores.player2; // Player 2/Computer Wins + document.getElementById("loss1").innerText = scores.player2; // Player 1/Player Losses + document.getElementById("loss2").innerText = scores.player1; // Player 2/Computer Losses + document.getElementById("draw1").innerText = scores.draw; + document.getElementById("draw2").innerText = scores.draw; + }; + + const reset_board = () => { play_board = ["", "", "", "", "", "", "", "", ""]; board_full = false; - winner_statement.classList.remove("playerWin"); - winner_statement.classList.remove("computerWin"); - winner_statement.classList.remove("draw"); + currentPlayer = player_symbol; + winner_statement.innerText = ""; - document.querySelector("#ai_level").disabled = false; - const audio = document.querySelector("audio"); - render_board(); - randomizeStart(); + winner_statement.className = ""; + ai_select.disabled = false; - var mute_sound_btn = document.getElementsByClassName("btn-sound")[0]; - if (mute_sound_btn != undefined) - mute_sound_btn.parentNode.removeChild(mute_sound_btn); //delete the button when reseting the board -} + if (gameMode === 1 && currentPlayer === computer_symbol) { + setTimeout(() => addComputerMove(), 500); + } -/Reset board according to player choice/ + game_loop(); + showPlayer(); + }; -const selectFirstPlayer = (symbol) => { - reset_board1(symbol); -} + const selectFirstPlayer = (symbol) => { + currentPlayer = symbol; + reset_board(); + }; -const reset_board1 = (firstPlayer) => { - const winner_statement = document.getElementById("winner"); - play_board = ["", "", "", "", "", "", "", "", ""]; - board_full = false; - winner_statement.classList.remove("playerWin"); - winner_statement.classList.remove("computerWin"); - winner_statement.classList.remove("draw"); - winner_statement.innerText = ""; - document.querySelector("#ai_level").disabled = false; - render_board(); - setStartingPlayer(firstPlayer); - - var mute_sound_btn = document.getElementsByClassName("btn-sound")[0]; - if (mute_sound_btn != undefined) - mute_sound_btn.parentNode.removeChild(mute_sound_btn); //delete the button when resetting the board -} - -const setStartingPlayer = (firstPlayer) => { - if (play_board.every(item => item === "")) { - if (firstPlayer === 'X') { - if (gameMode == 1) { - showPlayer(1, 1); // Assuming showPlayer function takes parameters for player and symbol - } else { - showPlayer(2, 1); // Assuming showPlayer function takes parameters for player and symbol - } - console.log("PLAYER STARTS"); - } else if (firstPlayer === 'O') { - if (gameMode == 1) { - addComputerMove(ai_level); - } else { - showPlayer(2, 2); // Assuming showPlayer function takes parameters for player and symbol - } - console.log("COMPUTER STARTS"); - } + const undoLastMove = () => { + if (lastMove !== null) { + play_board = [...lastMove]; + lastMove = null; + board_full = false; + winner_statement.innerText = ""; + winner_statement.className = ""; + // In a 2-player game, you might need to toggle the currentPlayer back. + if (gameMode === 2) { + currentPlayer = + currentPlayer === player_symbol ? computer_symbol : player_symbol; + } + game_loop(); + showPlayer(); } -} + }; -render_board(); -configure_ai(); -randomizeStart(); + mainContent.style.display = "none"; + document.getElementById("singlePlayerBtn").addEventListener("click", () => { + instructionsPopup.style.display = "none"; + mainContent.style.display = "block"; + gameMode = 1; + player1_label.innerText = "Player (X)"; + player2_label.innerText = "Computer (O)"; + reset_board(); + }); + + document.getElementById("twoPlayerBtn").addEventListener("click", () => { + instructionsPopup.style.display = "none"; + mainContent.style.display = "block"; + gameMode = 2; + player1_label.innerText = "Player 1 (X)"; + player2_label.innerText = "Player 2 (O)"; + reset_board(); + }); + + // Game Control Buttons + document.getElementById("undoBtn").addEventListener("click", undoLastMove); + document + .getElementById("selectOBtn") + .addEventListener("click", () => selectFirstPlayer(computer_symbol)); // O starts + document + .getElementById("selectXBtn") + .addEventListener("click", () => selectFirstPlayer(player_symbol)); // X starts + ai_select.addEventListener("change", (e) => (ai_level = e.target.value)); + + // UI Control Buttons + document.getElementById("darkModeBtn").addEventListener("click", () => { + document.body.classList.toggle("dark-main"); + const btn = document.getElementById("darkModeBtn"); + btn.textContent = document.body.classList.contains("dark-main") + ? "Light Mode" + : "Dark Mode"; + }); + + document.getElementById("playAudioBtn").addEventListener("click", (e) => { + const btn = e.currentTarget; + if (audioPlayer.paused) { + audioPlayer.play(); + btn.innerHTML = ' Pause'; + } else { + audioPlayer.pause(); + btn.innerHTML = ' Play'; + } + }); + + document.getElementById("volume-slider").addEventListener("input", (e) => { + audioPlayer.volume = e.currentTarget.value / 100; + }); + + document.getElementById("muteAudioBtn").addEventListener("click", (e) => { + const btn = e.currentTarget; + audioPlayer.muted = !audioPlayer.muted; + btn.innerHTML = audioPlayer.muted + ? `` + : ``; + }); + + if (typeof FBInstant !== "undefined") { + FBInstant.initializeAsync().then(() => { + FBInstant.setLoadingProgress(100); + FBInstant.startGameAsync(); + }); + } +}); diff --git a/index.html b/index.html index a577f27..d1a3ec7 100644 --- a/index.html +++ b/index.html @@ -1,257 +1,119 @@ - + TTC - - - - - - + + + + - - - + - - - -
- - - - - - + + - - + + + \ No newline at end of file diff --git a/style.css b/style.css index 57fe44f..a3864b3 100644 --- a/style.css +++ b/style.css @@ -1,464 +1,342 @@ +:root { + --primary-color: #4a90e2; + --secondary-color: #50e3c2; + --background-color: #f7f9fb; + --text-color: #333; + --container-bg-color: #ffffff; + --border-color: #e0e0e0; + --shadow-color: rgba(0, 0, 0, 0.1); + --dark-bg-color: #121212; + --dark-container-bg: #1e1e1e; + --dark-text-color: #e0e0e0; + --dark-border-color: #444; +} + * { margin: 0; padding: 0; box-sizing: border-box; - font-family: Arial, Helvetica, sans-serif; } -.popup-container{ - position: absolute; - width: 50%; - display: block; + +html { + scroll-behavior: smooth; +} + +body { + font-family: "Poppins", sans-serif; + background-color: var(--background-color); + color: var(--text-color); + transition: background-color 0.3s, color 0.3s; + font-size: 16px; +} + +/* --- Dark Mode Styles --- */ +body.dark-main { + --background-color: var(--dark-bg-color); + --text-color: var(--dark-text-color); + --container-bg-color: var(--dark-container-bg); + --border-color: var(--dark-border-color); + --shadow-color: rgba(255, 255, 255, 0.1); +} + +/* --- Instructions Modal --- */ +.popup-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.6); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.instructions { + background-color: var(--container-bg-color); + padding: 2rem 3rem; + border-radius: 10px; + box-shadow: 0 4px 20px var(--shadow-color); + max-width: 600px; + text-align: center; +} + +.instructions h1 { + color: var(--primary-color); + margin-bottom: 1rem; +} + +.instructions h2 { + color: var(--text-color); + margin-top: 1.5rem; + margin-bottom: 0.5rem; + border-bottom: 1px solid var(--border-color); + padding-bottom: 0.5rem; +} + +.instructions p, +.instructions ol { + line-height: 1.6; + text-align: left; +} + +.instructions ol { + padding-left: 20px; + margin-top: 1rem; +} + +.modal-buttons { + margin-top: 2rem; + display: flex; + justify-content: center; + gap: 1rem; +} + +.start-btn { + background-color: var(--primary-color); + color: white; + border: none; + padding: 12px 30px; + border-radius: 5px; font-size: 1rem; - background-color: green; - margin:2% 20%; - line-height: 2.5rem; - padding: 1%; - color: #ffff; + cursor: pointer; + transition: background-color 0.3s, transform 0.2s; +} + +.start-btn:hover { + background-color: #357abd; + transform: translateY(-2px); +} + +/* --- Navigation Bar --- */ +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 2rem; + background-color: var(--container-bg-color); + box-shadow: 0 2px 4px var(--shadow-color); } -.instructions{ - background-color: #fff; - color: #000; - padding: 4%; + +.nav-left, +.nav-right { + display: flex; + align-items: center; + gap: 1.5rem; } -.instructions h1{ - color: green; + +.nav-link { + text-decoration: none; + color: var(--text-color); + font-weight: 600; + transition: color 0.3s; } -.start-btn{ - margin: 2% 20%; - border: 2px solid green; - background-color: #fff; - color: green; - border-radius: 15px; - padding: 25px 90px; + +.nav-link:hover { + color: var(--primary-color); } -.start-btn:hover{ - background-color: green; - color: #fff; + +.volume-slider { + cursor: pointer; } +/* --- Main Content Layout --- */ .container-custom { - /* border: 5px solid black; */ - padding-top: 10px; - min-height: 100vh; - display: none; + padding: 2rem; + display: flex; flex-direction: column; align-items: center; - justify-content: center; - background: none; } -.container > div { - border: 4px solid black; - border-radius: 2px; - font-family: Helvetica; - font-weight: bold; - font-size: 4em; - /* display: flex; +.game-and-scoreboard { + display: flex; + gap: 3rem; + align-items: flex-start; + width: 100%; + max-width: 900px; + flex-wrap: wrap; justify-content: center; - align-items: center;*/ } -a { - font-family: Helvetica; - font-weight:bold; - margin: auto; +.game-area-wrapper { text-align: center; } -nav { - border-color: black; - border-radius: 10px 100px / 120px; - border-style: groove; - border-width: 7px; - background: whitesmoke; - margin: auto; - padding: 3px; - text-align: center; -} - -button { - outline: none; - border: 4px solid green; - padding: 10px 20px; - font-size: 1rem; - font-weight: bold; - background: none; - transition: all 0.2s ease-in-out; - color: #f80606; -} -button:hover { - cursor: pointer; - background: green; - color: white; +#move, +#winner { + font-size: 1.5rem; + color: var(--primary-color); + margin-bottom: 1rem; + min-height: 2.2rem; } +/* --- Game Board --- */ .play-area { display: grid; + grid-template-columns: repeat(3, 1fr); width: 300px; height: 300px; - grid-template-columns: auto auto auto; - background-color: white; - margin: 0.5% 0; + background-color: var(--background-color); + border-radius: 10px; + box-shadow: 0 4px 15px var(--shadow-color); + overflow: hidden; } .block { display: flex; - width: 100px; - height: 100px; - align-items: center; justify-content: center; - font-size: 3rem; + align-items: center; + font-size: 4rem; font-weight: bold; - border: 3px solid rgb(35, 137, 253); - transition: background 0.2s ease-in-out; -} - -.block:hover { + color: var(--text-color); + border: 4px solid var(--border-color); cursor: pointer; - background: #0ff30f; + transition: background-color 0.3s; } -.occupied:hover { - background: #ff3a3a; +.block:hover { + background-color: var(--secondary-color); + opacity: 0.8; } +/* Removing redundant borders for a clean grid */ #block_0, #block_1, #block_2 { border-top: none; } - #block_0, #block_3, #block_6 { border-left: none; } - -#block_6, -#block_7, -#block_8 { - border-bottom: none; -} - #block_2, #block_5, #block_8 { border-right: none; } - -.playerWin { - font-weight: bold; - font-size: 26px; - color: green; -} - -.computerWin { - font-weight: bold; - font-size: 26px; - color: red; +#block_6, +#block_7, +#block_8 { + border-bottom: none; } -.draw { - font-weight: bold; - font-size: 26px; - color: orange; +.occupied:hover { + background: #ff3a3a; } .won { - background-color: green; -} - -#ai_level { - margin-bottom: 0.5%; + background-color: var(--secondary-color); + color: white !important; } -.navbar { - background-color: white; +/* --- Scoreboard & Controls --- */ +.scoreboard-wrapper { + background-color: var(--container-bg-color); + padding: 1.5rem; + border-radius: 10px; + box-shadow: 0 4px 15px var(--shadow-color); + min-width: 300px; } -.navbar > a { - color: black; +.scoreboard-wrapper h4 { + text-align: center; + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--primary-color); } -.wrapper { - color: rgb(36, 41, 46); - font-size: 16px; - margin-top: 5%; +.table { width: 100%; + border-collapse: collapse; + margin-bottom: 1.5rem; } -.wrapper nav { - top: 0px; - width: 100%; -} -.wrapper nav ol { - padding: 0px; - list-style-type: none; -} -.wrapper nav ol li { - display: inline-block; - margin-bottom: 5%; - text-align: center; - width: 30%; -} -.wrapper nav ol li a { - text-decoration: none; -} -.wrapper nav ol li a:hover { - color: #0056b3; - text-decoration: underline; -} -.wrapper a { - color: rgb(3, 102, 214); - font-size: 16px; -} -.wrapper h1 { - color: rgb(3, 102, 214); - text-align: center; -} -.shortDescr { - margin-top: 5%; + +.table th, +.table td { + padding: 0.75rem; text-align: center; -} -.shortDescr a { - font-weight: 600; -} -.shortDescr p { - margin-top: 2%; - padding: 10px; - line-height: 25px; -} -.aboutContent { - margin: 0 auto; - margin-bottom: 10%; - width: 90%; -} -.aboutContent h2, -h3 { - margin: 7% 0; -} -.aboutContent ul, -ol { - padding-left: 11%; - padding-bottom: 1%; - width: 100%; -} -.aboutContent ol { - margin-bottom: 10px; -} -.aboutContent ul li { - margin: 4% 0; -} -.aboutContent ul li a { - text-decoration: none; -} -.aboutContent ul li a:hover { - text-decoration: underline; -} -.aboutContent img { - margin-top: 5%; - width: 100%; -} -.aboutContent p { - line-height: 25px; -} -.code { - width: 100%; -} -.code { - margin-bottom: 5%; - width: 100%; -} -pre { - background-color: rgb(246, 248, 250); - line-height: 1.45; - overflow: auto; - padding: 16px; + border-bottom: 1px solid var(--border-color); } - -@media screen and (max-width: 400px) { - .block { - width: 67px; - height: 67px; +.table thead { + background-color: var(--primary-color); + color: white; } - - .play-area { - width: 201px; - height: 201px; +.game-controls { + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +/* --- General Button Styles --- */ +button, +select { + font-family: "Poppins", sans-serif; + padding: 10px 15px; + border: 1px solid var(--primary-color); + background-color: transparent; + color: var(--primary-color); + border-radius: 5px; + font-weight: 600; + cursor: pointer; + transition: background-color 0.3s, color 0.3s, transform 0.2s; } - .wrapper nav { - margin-bottom: 2%; - } - .wrapper nav ol li a { - font-size: 20px; - } - - - .container-custom { - width: 100%; - margin-top: 30%; - padding-left: 5%; - padding-right: 5%; - +button:hover, +select:hover { + background-color: var(--primary-color); + color: white; + transform: translateY(-2px); } - - .table{ - font-size: 10px; - visibility: initial; -} +#btn-sound { + font-size: 1rem; } - -@media screen and (max-width: 768px) { - - .shortDescr { - margin-top: 2%; +/* --- Responsive Design --- */ +@media (max-width: 768px) { + .game-and-scoreboard { + flex-direction: column; + align-items: center; + gap: 2rem; } - .shortDescr p { - margin-top: 0%; - } - .aboutContent h2, - h3 { - margin: 4% 0; - } - .aboutContent ul li { - margin: 2% 0; - } - .aboutContent ul, - ol { - padding-left: 4%; - } - .aboutContent img { - margin-top: 0%; - } -} -@media screen and (max-width: 1024px) { - .wrapper { - margin-left: 10%; - width: 80%; - } - .wrapper nav ol li { - margin-bottom: 3%; - } -} -@media screen and (max-width: 1440px) { - .wrapper nav ol li a { - font-size: 26px; - } - .wrapper h1 { - font-size: 36px; - } - .shortDescr a, - .shortDescr p { - font-size: 20px; - } - .aboutContent h2 { - font-size: 30px; - } - .aboutContent h3 { - font-size: 26px; - } - .aboutContent h2, - h3 { - margin: 3% 0; - } - .aboutContent ul, - ol { - padding-left: 3%; - } - .wrapper a { - font-size: 20px; - } - .aboutContent p { - font-size: 20px; - line-height: 30px; - } - .aboutContent ul li, - .aboutContent ol { - font-size: 20px; - } - pre { - font-size: 20px; - } - .aboutContent img { - margin-left: 10%; - width: 80%; - } - .code { - margin-bottom: 2.5%; - } -} -@media screen and (max-width: 1792px) { - .wrapper { - margin-top: 2%; - margin-left: 15%; - width: 70%; - } - .aboutContent h2, - h3 { - margin-bottom: 2%; - } - .aboutContent ul li { - margin: 1% 0; + .navbar { + flex-direction: column; + gap: 1rem; } - .aboutContent img { - margin-left: 15%; - margin-top: 1%; - width: 70%; - } -} - -/* light and dark more style */ -body { - padding: 25px; - background:gray; - color: black; - font-size: 25px; -} - -thead{ - background-color: lightblue -} - -.dark-main { - background-color: #121212; - color: white; -} - -.dark-hero{ - background-color: #2a2a2a; - color: white; -} -.dark-play { - background-color: #2a2a2a; - color: white; - border: white; -} + .nav-left, + .nav-right { + gap: 1rem; + flex-wrap: wrap; + justify-content: center; + } -.dark-text { - color: white !important; -} + .play-area { + width: 270px; + height: 270px; + } -.table{ - width: 100px; - visibility: initial; + .block { + font-size: 3rem; + } } -.btn-sound { - background-color: DodgerBlue; /* Blue background */ - border: none; /* Remove borders */ - color: white; /* White text */ - padding: 12px 16px; /* Some padding */ - font-size: 16px; /* Set a font size */ - cursor: pointer; /* Mouse pointer on hover */ +@media (max-width: 480px) { + body { + font-size: 14px; + } -} + .instructions { + padding: 1.5rem; + margin: 1rem; + } -.btn-sound:hover { - background-color: rgb(94, 143, 206); + .container-custom { + padding: 1rem; + } }