| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>2-Player Tic Tac Toe</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .cell { |
| transition: all 0.3s ease; |
| } |
| .cell:hover:not(.occupied) { |
| transform: scale(1.05); |
| box-shadow: 0 0 15px rgba(255, 255, 255, 0.3); |
| } |
| .winning-cell { |
| animation: pulse 1.5s infinite; |
| } |
| @keyframes pulse { |
| 0% { background-color: rgba(134, 239, 172, 0.3); } |
| 50% { background-color: rgba(134, 239, 172, 0.7); } |
| 100% { background-color: rgba(134, 239, 172, 0.3); } |
| } |
| .modal { |
| transition: opacity 0.3s ease, transform 0.3s ease; |
| } |
| .modal.hidden { |
| opacity: 0; |
| transform: scale(0.9); |
| pointer-events: none; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4"> |
| <div class="max-w-md w-full"> |
| <h1 class="text-4xl font-bold text-center mb-2 text-transparent bg-clip-text bg-gradient-to-r from-green-400 to-blue-500"> |
| Tic Tac Toe |
| </h1> |
| <p class="text-center text-gray-400 mb-6">A classic game for two players</p> |
| |
| <div class="bg-gray-800 rounded-xl p-6 shadow-2xl"> |
| |
| <div class="flex justify-between mb-6"> |
| <div id="player1" class="flex items-center space-x-2 bg-gray-700 px-4 py-2 rounded-lg transition-all duration-300"> |
| <div class="w-8 h-8 rounded-full bg-green-500 flex items-center justify-center"> |
| <i class="fas fa-times text-white"></i> |
| </div> |
| <span class="font-medium">Player X</span> |
| <div id="p1-score" class="ml-2 bg-gray-600 px-2 py-1 rounded text-sm">0</div> |
| </div> |
| |
| <div id="player2" class="flex items-center space-x-2 px-4 py-2 rounded-lg transition-all duration-300"> |
| <div class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center"> |
| <i class="far fa-circle text-white"></i> |
| </div> |
| <span class="font-medium">Player O</span> |
| <div id="p2-score" class="ml-2 bg-gray-600 px-2 py-1 rounded text-sm">0</div> |
| </div> |
| </div> |
| |
| |
| <div class="grid grid-cols-3 gap-3 mb-6"> |
| |
| </div> |
| |
| |
| <div class="flex justify-between"> |
| <button id="reset-btn" class="bg-gray-700 hover:bg-gray-600 px-4 py-2 rounded-lg transition"> |
| <i class="fas fa-redo mr-2"></i>Reset Game |
| </button> |
| <button id="new-game-btn" class="bg-blue-600 hover:bg-blue-500 px-4 py-2 rounded-lg transition"> |
| <i class="fas fa-plus-circle mr-2"></i>New Game |
| </button> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div id="winner-modal" class="modal fixed inset-0 flex items-center justify-center bg-black bg-opacity-70 z-50 hidden"> |
| <div class="bg-gray-800 rounded-xl p-8 max-w-sm w-full mx-4 shadow-2xl text-center"> |
| <h2 id="winner-text" class="text-3xl font-bold mb-4"></h2> |
| <p id="winner-message" class="text-gray-300 mb-6"></p> |
| <button id="close-modal-btn" class="bg-green-600 hover:bg-green-500 px-6 py-2 rounded-lg transition w-full"> |
| Continue Playing |
| </button> |
| </div> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', () => { |
| |
| let board = ['', '', '', '', '', '', '', '', '']; |
| let currentPlayer = 'X'; |
| let gameActive = true; |
| let scores = { X: 0, O: 0 }; |
| let moveCount = 0; |
| |
| |
| const boardElement = document.querySelector('.grid'); |
| const player1Element = document.getElementById('player1'); |
| const player2Element = document.getElementById('player2'); |
| const p1ScoreElement = document.getElementById('p1-score'); |
| const p2ScoreElement = document.getElementById('p2-score'); |
| const resetBtn = document.getElementById('reset-btn'); |
| const newGameBtn = document.getElementById('new-game-btn'); |
| const winnerModal = document.getElementById('winner-modal'); |
| const winnerText = document.getElementById('winner-text'); |
| const winnerMessage = document.getElementById('winner-message'); |
| const closeModalBtn = document.getElementById('close-modal-btn'); |
| |
| |
| function initializeBoard() { |
| boardElement.innerHTML = ''; |
| for (let i = 0; i < 9; i++) { |
| const cell = document.createElement('div'); |
| cell.className = 'cell bg-gray-700 h-24 md:h-32 flex items-center justify-center text-5xl font-bold rounded-lg cursor-pointer'; |
| cell.dataset.index = i; |
| cell.addEventListener('click', () => handleCellClick(i)); |
| boardElement.appendChild(cell); |
| } |
| } |
| |
| |
| function handleCellClick(index) { |
| if (!gameActive || board[index] !== '') return; |
| |
| board[index] = currentPlayer; |
| moveCount++; |
| |
| const cell = document.querySelector(`[data-index="${index}"]`); |
| cell.innerHTML = currentPlayer === 'X' ? |
| '<i class="fas fa-times text-green-500"></i>' : |
| '<i class="far fa-circle text-blue-500"></i>'; |
| cell.classList.add('occupied'); |
| |
| if (checkWin()) { |
| handleWin(); |
| return; |
| } |
| |
| if (moveCount === 9) { |
| handleDraw(); |
| return; |
| } |
| |
| switchPlayer(); |
| } |
| |
| |
| function checkWin() { |
| const winPatterns = [ |
| [0, 1, 2], [3, 4, 5], [6, 7, 8], |
| [0, 3, 6], [1, 4, 7], [2, 5, 8], |
| [0, 4, 8], [2, 4, 6] |
| ]; |
| |
| return winPatterns.some(pattern => { |
| const [a, b, c] = pattern; |
| if (board[a] && board[a] === board[b] && board[a] === board[c]) { |
| |
| pattern.forEach(index => { |
| document.querySelector(`[data-index="${index}"]`).classList.add('winning-cell'); |
| }); |
| return true; |
| } |
| return false; |
| }); |
| } |
| |
| |
| function handleWin() { |
| gameActive = false; |
| scores[currentPlayer]++; |
| updateScores(); |
| |
| winnerText.textContent = `Player ${currentPlayer} Wins!`; |
| winnerMessage.textContent = `Congratulations! Player ${currentPlayer} has won this round.`; |
| winnerText.className = currentPlayer === 'X' ? 'text-3xl font-bold mb-4 text-green-500' : 'text-3xl font-bold mb-4 text-blue-500'; |
| winnerModal.classList.remove('hidden'); |
| } |
| |
| |
| function handleDraw() { |
| gameActive = false; |
| winnerText.textContent = "It's a Draw!"; |
| winnerMessage.textContent = "The game ended in a tie. Try again!"; |
| winnerText.className = 'text-3xl font-bold mb-4 text-yellow-500'; |
| winnerModal.classList.remove('hidden'); |
| } |
| |
| |
| function switchPlayer() { |
| currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; |
| updatePlayerUI(); |
| } |
| |
| |
| function updatePlayerUI() { |
| if (currentPlayer === 'X') { |
| player1Element.classList.add('bg-gray-700'); |
| player2Element.classList.remove('bg-gray-700'); |
| } else { |
| player1Element.classList.remove('bg-gray-700'); |
| player2Element.classList.add('bg-gray-700'); |
| } |
| } |
| |
| |
| function updateScores() { |
| p1ScoreElement.textContent = scores.X; |
| p2ScoreElement.textContent = scores.O; |
| } |
| |
| |
| function resetGame() { |
| board = ['', '', '', '', '', '', '', '', '']; |
| currentPlayer = 'X'; |
| gameActive = true; |
| moveCount = 0; |
| |
| initializeBoard(); |
| updatePlayerUI(); |
| |
| |
| document.querySelectorAll('.cell').forEach(cell => { |
| cell.classList.remove('winning-cell'); |
| }); |
| } |
| |
| |
| function newGame() { |
| scores = { X: 0, O: 0 }; |
| updateScores(); |
| resetGame(); |
| } |
| |
| |
| resetBtn.addEventListener('click', resetGame); |
| newGameBtn.addEventListener('click', newGame); |
| closeModalBtn.addEventListener('click', () => { |
| winnerModal.classList.add('hidden'); |
| resetGame(); |
| }); |
| |
| |
| initializeBoard(); |
| updatePlayerUI(); |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=hiinikhil/tic" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |