commit 2fe89aebd31aeeed1f7b4d4d58b2dff0ff7e0b7e
Author: root <root@hub.scroll.pub> Date: 2024-12-24 00:37:15 +0000 Subject: Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..61b80f9 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# tictactic.scroll.pub +Website generated from prompt: build me a website with a tic tac toe game \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..c1679af --- /dev/null +++ b/index.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="Play a beautiful game of Tic Tac Toe online. Free, responsive, and fun!"> + <meta name="keywords" content="tic tac toe, game, online game, strategy game"> + <title>Elegant Tic Tac Toe | Play Online</title> + <link rel="stylesheet" href="style.css"> +</head> +<body> + <header> + <h1>Elegant Tic Tac Toe</h1> + </header> + + <main> + <div class="game-status" aria-live="polite"> + <p id="status">Player X's Turn</p> + </div> + + <div class="game-board" role="grid"> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + <button class="cell" data-cell></button> + </div> + + <button class="restart-button" id="restartButton">New Game</button> + </main> + + <footer> + <p>Made with ❤️ for game lovers</p> + </footer> + + <script src="script.js"></script> +</body> +</html> diff --git a/script.js b/script.js new file mode 100644 index 0000000..a97ef76 --- /dev/null +++ b/script.js @@ -0,0 +1,89 @@ +document.addEventListener('DOMContentLoaded', () => { + const board = document.querySelector('.game-board'); + const cells = document.querySelectorAll('[data-cell]'); + const status = document.getElementById('status'); + const restartButton = document.getElementById('restartButton'); + let currentPlayer = 'X'; + let gameState = ['', '', '', '', '', '', '', '', '']; + let gameActive = true; + + const winningCombinations = [ + [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows + [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns + [0, 4, 8], [2, 4, 6] // Diagonals + ]; + + function handleCellClick(e) { + const cell = e.target; + const index = Array.from(cells).indexOf(cell); + + if (gameState[index] !== '' || !gameActive) return; + + gameState[index] = currentPlayer; + cell.textContent = currentPlayer; + cell.classList.add(currentPlayer.toLowerCase()); + cell.setAttribute('aria-label', `${currentPlayer} placed at position ${index + 1}`); + + if (checkWin()) { + gameActive = false; + status.textContent = `Player ${currentPlayer} Wins!`; + highlightWinningCells(); + return; + } + + if (checkDraw()) { + gameActive = false; + status.textContent = "Game Draw!"; + return; + } + + currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; + status.textContent = `Player ${currentPlayer}'s Turn`; + } + + function checkWin() { + return winningCombinations.some(combination => { + return combination.every(index => { + return gameState[index] === currentPlayer; + }); + }); + } + + function checkDraw() { + return gameState.every(cell => cell !== ''); + } + + function highlightWinningCells() { + winningCombinations.forEach(combination => { + if (combination.every(index => gameState[index] === currentPlayer)) { + combination.forEach(index => { + cells[index].classList.add('win'); + }); + } + }); + } + + function restartGame() { + gameState = ['', '', '', '', '', '', '', '', '']; + gameActive = true; + currentPlayer = 'X'; + status.textContent = `Player ${currentPlayer}'s Turn`; + + cells.forEach(cell => { + cell.textContent = ''; + cell.classList.remove('x', 'o', 'win'); + cell.setAttribute('aria-label', 'Empty cell'); + }); + } + + // Event Listeners + cells.forEach(cell => { + cell.addEventListener('click', handleCellClick); + cell.setAttribute('aria-label', 'Empty cell'); + }); + + restartButton.addEventListener('click', restartGame); + + // Initialize game + restartGame(); +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..73cc971 --- /dev/null +++ b/style.css @@ -0,0 +1,129 @@ +:root { + --primary-color: #2c3e50; + --secondary-color: #34495e; + --accent-color: #3498db; + --text-color: #ecf0f1; + --cell-size: 100px; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: var(--text-color); + font-family: 'Segoe UI', system-ui, sans-serif; +} + +header { + padding: 2rem; + text-align: center; +} + +h1 { + font-size: 2.5rem; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); + background: linear-gradient(45deg, #3498db, #2ecc71); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +main { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + gap: 2rem; +} + +.game-status { + font-size: 1.5rem; + height: 2rem; +} + +.game-board { + display: grid; + grid-template-columns: repeat(3, var(--cell-size)); + gap: 0.5rem; + perspective: 1000px; +} + +.cell { + width: var(--cell-size); + height: var(--cell-size); + background: rgba(255, 255, 255, 0.1); + border: 2px solid rgba(255, 255, 255, 0.2); + border-radius: 12px; + cursor: pointer; + font-size: 3rem; + color: var(--text-color); + transition: all 0.3s ease; + backdrop-filter: blur(5px); +} + +.cell:hover { + background: rgba(255, 255, 255, 0.2); + transform: translateZ(10px); +} + +.cell.x { + color: #3498db; +} + +.cell.o { + color: #2ecc71; +} + +.restart-button { + padding: 1rem 2rem; + font-size: 1.2rem; + background: var(--accent-color); + border: none; + border-radius: 25px; + color: var(--text-color); + cursor: pointer; + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.restart-button:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); +} + +footer { + padding: 2rem; + text-align: center; + font-size: 0.9rem; +} + +@media (max-width: 400px) { + :root { + --cell-size: 80px; + } + + h1 { + font-size: 2rem; + } + + .game-status { + font-size: 1.2rem; + } +} + +@keyframes win-animation { + 0% { transform: scale(1); } + 50% { transform: scale(1.1); } + 100% { transform: scale(1); } +} + +.win { + animation: win-animation 0.5s ease; +}