| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Hangman Game</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> |
| .hangman-container { |
| position: relative; |
| width: 300px; |
| height: 350px; |
| margin: 0 auto; |
| } |
| |
| .hangman-part { |
| position: absolute; |
| display: none; |
| } |
| |
| |
| #gallows-base { |
| width: 150px; |
| height: 15px; |
| bottom: 0; |
| left: 75px; |
| background-color: #8B4513; |
| display: block; |
| border-radius: 3px; |
| } |
| |
| #gallows-pole { |
| width: 15px; |
| height: 250px; |
| bottom: 15px; |
| left: 75px; |
| background-color: #8B4513; |
| display: block; |
| border-radius: 3px; |
| } |
| |
| #gallows-top { |
| width: 120px; |
| height: 15px; |
| top: 0; |
| left: 90px; |
| background-color: #8B4513; |
| display: block; |
| border-radius: 3px; |
| } |
| |
| #gallows-rope { |
| width: 8px; |
| height: 40px; |
| top: 15px; |
| left: 210px; |
| background-color: #654321; |
| display: block; |
| border-radius: 3px; |
| } |
| |
| |
| #head { |
| width: 50px; |
| height: 50px; |
| border-radius: 50%; |
| top: 55px; |
| left: 185px; |
| background-color: #FFD700; |
| border: 3px solid #DAA520; |
| box-sizing: border-box; |
| } |
| |
| #face { |
| width: 50px; |
| height: 50px; |
| border-radius: 50%; |
| top: 55px; |
| left: 185px; |
| display: none; |
| } |
| |
| #eye-left { |
| width: 8px; |
| height: 8px; |
| background-color: #333; |
| border-radius: 50%; |
| top: 70px; |
| left: 195px; |
| } |
| |
| #eye-right { |
| width: 8px; |
| height: 8px; |
| background-color: #333; |
| border-radius: 50%; |
| top: 70px; |
| left: 217px; |
| } |
| |
| #mouth { |
| width: 20px; |
| height: 5px; |
| background-color: #333; |
| border-radius: 5px; |
| top: 85px; |
| left: 195px; |
| } |
| |
| #body { |
| width: 15px; |
| height: 100px; |
| top: 105px; |
| left: 202px; |
| background-color: #FFD700; |
| border: 3px solid #DAA520; |
| box-sizing: border-box; |
| } |
| |
| #left-arm { |
| width: 60px; |
| height: 15px; |
| top: 130px; |
| left: 142px; |
| background-color: #FFD700; |
| border: 3px solid #DAA520; |
| box-sizing: border-box; |
| transform: rotate(30deg); |
| transform-origin: right; |
| } |
| |
| #right-arm { |
| width: 60px; |
| height: 15px; |
| top: 130px; |
| left: 217px; |
| background-color: #FFD700; |
| border: 3px solid #DAA520; |
| box-sizing: border-box; |
| transform: rotate(-30deg); |
| transform-origin: left; |
| } |
| |
| #left-leg { |
| width: 60px; |
| height: 15px; |
| top: 205px; |
| left: 152px; |
| background-color: #FFD700; |
| border: 3px solid #DAA520; |
| box-sizing: border-box; |
| transform: rotate(20deg); |
| transform-origin: right; |
| } |
| |
| #right-leg { |
| width: 60px; |
| height: 15px; |
| top: 205px; |
| left: 202px; |
| background-color: #FFD700; |
| border: 3px solid #DAA520; |
| box-sizing: border-box; |
| transform: rotate(-20deg); |
| transform-origin: left; |
| } |
| |
| .letter-tile { |
| width: 40px; |
| height: 50px; |
| border-bottom: 3px solid #333; |
| font-size: 24px; |
| font-weight: bold; |
| display: flex; |
| align-items: flex-end; |
| justify-content: center; |
| margin: 0 5px; |
| } |
| |
| .keyboard-key { |
| width: 40px; |
| height: 40px; |
| font-size: 18px; |
| font-weight: bold; |
| cursor: pointer; |
| transition: all 0.2s; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| border-radius: 8px; |
| } |
| |
| .keyboard-key:hover { |
| transform: scale(1.1); |
| } |
| |
| .keyboard-key.used { |
| opacity: 0.5; |
| cursor: not-allowed; |
| } |
| |
| .keyboard-key.correct { |
| background-color: #4CAF50; |
| color: white; |
| } |
| |
| .keyboard-key.wrong { |
| background-color: #F44336; |
| color: white; |
| } |
| |
| .modal { |
| transition: opacity 0.3s ease; |
| } |
| |
| .word-input-container { |
| display: flex; |
| align-items: center; |
| margin-bottom: 10px; |
| } |
| |
| .word-input-container input { |
| flex-grow: 1; |
| margin-right: 10px; |
| } |
| |
| |
| @keyframes walk { |
| 0% { transform: translateX(0) rotate(0deg); } |
| 25% { transform: translateX(20px) rotate(5deg); } |
| 50% { transform: translateX(40px) rotate(0deg); } |
| 75% { transform: translateX(60px) rotate(-5deg); } |
| 100% { transform: translateX(80px) rotate(0deg); } |
| } |
| |
| .walking { |
| animation: walk 2s infinite linear; |
| } |
| |
| |
| .speech-bubble { |
| position: absolute; |
| background: #fff; |
| border-radius: 10px; |
| padding: 10px; |
| box-shadow: 0 2px 5px rgba(0,0,0,0.2); |
| max-width: 200px; |
| font-size: 14px; |
| z-index: 10; |
| } |
| |
| .speech-bubble:after { |
| content: ''; |
| position: absolute; |
| bottom: -10px; |
| left: 20px; |
| border-width: 10px 10px 0; |
| border-style: solid; |
| border-color: #fff transparent; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4"> |
| <div class="bg-white rounded-lg shadow-xl p-8 w-full max-w-4xl"> |
| <h1 class="text-4xl font-bold text-center mb-8 text-indigo-700"> |
| <i class="fas fa-ghost mr-2"></i> Hangman Game <i class="fas fa-ghost ml-2"></i> |
| </h1> |
| |
| |
| <div id="initial-setup" class="mb-8"> |
| <h2 class="text-2xl font-semibold mb-4 text-gray-800">Game Setup</h2> |
| <div class="flex flex-col space-y-4"> |
| <div> |
| <label for="word-count" class="block text-sm font-medium text-gray-700 mb-1">How many words do you want to play with?</label> |
| <input type="number" id="word-count" min="1" max="10" value="1" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> |
| </div> |
| <button id="proceed-to-words" class="bg-indigo-600 text-white px-6 py-3 rounded-md font-medium hover:bg-indigo-700 transition duration-200"> |
| Proceed to Add Words <i class="fas fa-arrow-right ml-2"></i> |
| </button> |
| </div> |
| </div> |
| |
| |
| <div id="word-input-section" class="mb-8 hidden"> |
| <h2 class="text-2xl font-semibold mb-4 text-gray-800">Enter Your Words</h2> |
| <div id="word-inputs" class="mb-4"> |
| |
| </div> |
| <div> |
| <label for="hint" class="block text-sm font-medium text-gray-700 mb-1">Optional hint (category):</label> |
| <input type="text" id="hint" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="e.g. Animals, Countries, etc."> |
| </div> |
| <button id="start-game" class="mt-4 bg-indigo-600 text-white px-6 py-3 rounded-md font-medium hover:bg-indigo-700 transition duration-200"> |
| Start Game <i class="fas fa-play ml-2"></i> |
| </button> |
| </div> |
| |
| |
| <div id="game-section" class="hidden"> |
| <div class="flex flex-col md:flex-row gap-8"> |
| |
| <div class="w-full md:w-1/2"> |
| <div class="bg-gray-50 p-6 rounded-lg shadow-inner relative"> |
| <h2 class="text-xl font-semibold mb-4 text-center">Hangman</h2> |
| <div class="hangman-container"> |
| |
| <div id="gallows-base" class="hangman-part"></div> |
| <div id="gallows-pole" class="hangman-part"></div> |
| <div id="gallows-top" class="hangman-part"></div> |
| <div id="gallows-rope" class="hangman-part"></div> |
| |
| |
| <div id="head" class="hangman-part"></div> |
| <div id="face" class="hangman-part"> |
| <div id="eye-left" class="hangman-part"></div> |
| <div id="eye-right" class="hangman-part"></div> |
| <div id="mouth" class="hangman-part"></div> |
| </div> |
| <div id="body" class="hangman-part"></div> |
| <div id="left-arm" class="hangman-part"></div> |
| <div id="right-arm" class="hangman-part"></div> |
| <div id="left-leg" class="hangman-part"></div> |
| <div id="right-leg" class="hangman-part"></div> |
| </div> |
| |
| <div id="hangman-speech" class="speech-bubble hidden" style="bottom: -60px; left: 50px;"></div> |
| |
| <div class="mt-6 text-center"> |
| <p id="hint-display" class="text-gray-600 italic"></p> |
| <p id="remaining-guesses" class="text-lg font-medium mt-2">Remaining wrong guesses: <span class="text-indigo-600">5</span></p> |
| <p id="current-word" class="text-sm text-gray-500 mt-1">Word 1 of 1</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="w-full md:w-1/2"> |
| <div class="bg-gray-50 p-6 rounded-lg shadow-inner"> |
| <h2 class="text-xl font-semibold mb-4 text-center">Guess the Word</h2> |
| |
| |
| <div id="word-display" class="flex justify-center gap-2 mb-8 flex-wrap"></div> |
| |
| |
| <div id="keyboard" class="grid grid-cols-7 gap-2"> |
| |
| </div> |
| |
| <div class="mt-6 flex justify-center gap-4"> |
| <button id="new-game" class="bg-gray-600 text-white px-4 py-2 rounded-md font-medium hover:bg-gray-700 transition duration-200"> |
| <i class="fas fa-redo mr-2"></i> New Game |
| </button> |
| <button id="next-word" class="bg-indigo-600 text-white px-4 py-2 rounded-md font-medium hover:bg-indigo-700 transition duration-200 hidden"> |
| Next Word <i class="fas fa-arrow-right ml-2"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden modal"> |
| <div class="bg-white rounded-lg shadow-xl p-8 w-full max-w-md"> |
| <h2 id="game-result-title" class="text-3xl font-bold mb-4 text-center"></h2> |
| <p id="game-result-message" class="text-lg mb-6 text-center"></p> |
| <div class="flex justify-center"> |
| <button id="play-again" class="bg-indigo-600 text-white px-6 py-2 rounded-md font-medium hover:bg-indigo-700 transition duration-200"> |
| <i class="fas fa-play mr-2"></i> Play Again |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', function() { |
| |
| let words = []; |
| let hint = ''; |
| let currentWordIndex = 0; |
| let secretWord = ''; |
| let guessedLetters = []; |
| let wrongGuesses = 0; |
| const maxWrongGuesses = 5; |
| const hangmanParts = ['head', 'face', 'body', 'left-arm', 'right-arm', 'left-leg', 'right-leg']; |
| |
| |
| const initialSetup = document.getElementById('initial-setup'); |
| const wordInputSection = document.getElementById('word-input-section'); |
| const wordInputsContainer = document.getElementById('word-inputs'); |
| const gameSection = document.getElementById('game-section'); |
| const wordCountInput = document.getElementById('word-count'); |
| const proceedToWordsBtn = document.getElementById('proceed-to-words'); |
| const startGameBtn = document.getElementById('start-game'); |
| const newGameBtn = document.getElementById('new-game'); |
| const nextWordBtn = document.getElementById('next-word'); |
| const playAgainBtn = document.getElementById('play-again'); |
| const wordDisplay = document.getElementById('word-display'); |
| const keyboard = document.getElementById('keyboard'); |
| const hintDisplay = document.getElementById('hint-display'); |
| const remainingGuesses = document.getElementById('remaining-guesses'); |
| const currentWordDisplay = document.getElementById('current-word'); |
| const gameOverModal = document.getElementById('game-over-modal'); |
| const gameResultTitle = document.getElementById('game-result-title'); |
| const gameResultMessage = document.getElementById('game-result-message'); |
| const hangmanSpeech = document.getElementById('hangman-speech'); |
| |
| |
| function initKeyboard() { |
| keyboard.innerHTML = ''; |
| const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); |
| |
| alphabet.forEach(letter => { |
| const key = document.createElement('div'); |
| key.className = 'keyboard-key flex items-center justify-center bg-gray-200 rounded-md'; |
| key.textContent = letter; |
| key.dataset.letter = letter; |
| key.addEventListener('click', () => handleGuess(letter)); |
| keyboard.appendChild(key); |
| }); |
| } |
| |
| |
| function createWordInputs() { |
| const wordCount = parseInt(wordCountInput.value); |
| wordInputsContainer.innerHTML = ''; |
| |
| for (let i = 0; i < wordCount; i++) { |
| const container = document.createElement('div'); |
| container.className = 'word-input-container'; |
| |
| const input = document.createElement('input'); |
| input.type = 'text'; |
| input.className = 'w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500'; |
| input.placeholder = `Word ${i + 1}`; |
| input.dataset.index = i; |
| |
| container.appendChild(input); |
| wordInputsContainer.appendChild(container); |
| } |
| |
| initialSetup.classList.add('hidden'); |
| wordInputSection.classList.remove('hidden'); |
| document.querySelector('.word-input-container input').focus(); |
| } |
| |
| |
| function startGame() { |
| |
| words = []; |
| const inputs = wordInputsContainer.querySelectorAll('input'); |
| inputs.forEach(input => { |
| if (input.value.trim()) { |
| words.push(input.value.trim().toUpperCase()); |
| } |
| }); |
| |
| if (words.length === 0) { |
| alert('Please enter at least one word to start the game!'); |
| return; |
| } |
| |
| hint = document.getElementById('hint').value.trim(); |
| |
| |
| currentWordIndex = 0; |
| setupWord(); |
| |
| |
| wordInputSection.classList.add('hidden'); |
| gameSection.classList.remove('hidden'); |
| |
| |
| initKeyboard(); |
| |
| |
| hangmanParts.forEach(part => { |
| document.getElementById(part).style.display = 'none'; |
| }); |
| |
| |
| document.getElementById('gallows-base').style.display = 'block'; |
| document.getElementById('gallows-pole').style.display = 'block'; |
| document.getElementById('gallows-top').style.display = 'block'; |
| document.getElementById('gallows-rope').style.display = 'block'; |
| |
| |
| hintDisplay.textContent = hint ? `Hint: ${hint}` : 'No hint provided'; |
| currentWordDisplay.textContent = `Word ${currentWordIndex + 1} of ${words.length}`; |
| |
| |
| if (words.length === 1) { |
| nextWordBtn.classList.add('hidden'); |
| } else { |
| nextWordBtn.classList.remove('hidden'); |
| } |
| } |
| |
| |
| function setupWord() { |
| secretWord = words[currentWordIndex]; |
| guessedLetters = []; |
| wrongGuesses = 0; |
| |
| |
| remainingGuesses.innerHTML = `Remaining wrong guesses: <span class="text-indigo-600">${maxWrongGuesses - wrongGuesses}</span>`; |
| currentWordDisplay.textContent = `Word ${currentWordIndex + 1} of ${words.length}`; |
| |
| |
| updateWordDisplay(); |
| |
| |
| initKeyboard(); |
| |
| |
| hangmanParts.forEach(part => { |
| document.getElementById(part).style.display = 'none'; |
| }); |
| |
| |
| document.getElementById('face').style.display = 'block'; |
| document.getElementById('eye-left').style.display = 'block'; |
| document.getElementById('eye-right').style.display = 'block'; |
| document.getElementById('mouth').style.display = 'block'; |
| |
| |
| showSpeech("Help me! Guess the word to save me!"); |
| } |
| |
| |
| function updateWordDisplay() { |
| wordDisplay.innerHTML = ''; |
| |
| secretWord.split('').forEach(letter => { |
| const tile = document.createElement('div'); |
| tile.className = 'letter-tile'; |
| |
| if (guessedLetters.includes(letter) || letter === ' ') { |
| tile.textContent = letter; |
| } else if (letter === '-') { |
| tile.textContent = '-'; |
| } else { |
| tile.textContent = ''; |
| } |
| |
| wordDisplay.appendChild(tile); |
| }); |
| |
| |
| if (isWordGuessed()) { |
| wordCompleted(); |
| } |
| } |
| |
| |
| function handleGuess(letter) { |
| const keyElement = document.querySelector(`.keyboard-key[data-letter="${letter}"]`); |
| |
| |
| if (keyElement.classList.contains('used')) { |
| return; |
| } |
| |
| |
| keyElement.classList.add('used'); |
| |
| |
| if (secretWord.includes(letter)) { |
| keyElement.classList.add('correct'); |
| guessedLetters.push(letter); |
| updateWordDisplay(); |
| |
| |
| const correctCount = secretWord.split('').filter(l => l === letter).length; |
| showSpeech(`Thank you! ${correctCount} ${letter}'s found! You're one step closer to saving me!`); |
| } else { |
| keyElement.classList.add('wrong'); |
| wrongGuesses++; |
| updateHangman(); |
| remainingGuesses.innerHTML = `Remaining wrong guesses: <span class="text-indigo-600">${maxWrongGuesses - wrongGuesses}</span>`; |
| |
| |
| showSpeech("Ouch! That's wrong! I'm dying here!"); |
| |
| |
| if (wrongGuesses >= maxWrongGuesses) { |
| endGame(false); |
| } |
| } |
| } |
| |
| |
| function updateHangman() { |
| if (wrongGuesses > 0 && wrongGuesses <= hangmanParts.length) { |
| const partToShow = hangmanParts[wrongGuesses - 1]; |
| document.getElementById(partToShow).style.display = 'block'; |
| |
| |
| if (wrongGuesses >= 3) { |
| document.getElementById('mouth').style.borderRadius = '0'; |
| document.getElementById('mouth').style.height = '3px'; |
| document.getElementById('mouth').style.width = '15px'; |
| document.getElementById('mouth').style.top = '88px'; |
| } |
| } |
| } |
| |
| |
| function showSpeech(text) { |
| hangmanSpeech.textContent = text; |
| hangmanSpeech.classList.remove('hidden'); |
| |
| |
| setTimeout(() => { |
| hangmanSpeech.classList.add('hidden'); |
| }, 3000); |
| } |
| |
| |
| function isWordGuessed() { |
| return secretWord.split('').every(letter => |
| guessedLetters.includes(letter) || letter === ' ' || letter === '-' |
| ); |
| } |
| |
| |
| function wordCompleted() { |
| |
| document.getElementById('gallows-rope').style.display = 'none'; |
| |
| |
| const hangman = document.querySelector('.hangman-container'); |
| hangman.classList.add('walking'); |
| |
| |
| showSpeech("You saved me! Thank you!"); |
| |
| |
| if (currentWordIndex < words.length - 1) { |
| |
| nextWordBtn.classList.remove('hidden'); |
| } else { |
| |
| endGame(true); |
| } |
| } |
| |
| |
| function nextWord() { |
| |
| const hangman = document.querySelector('.hangman-container'); |
| hangman.classList.remove('walking'); |
| |
| |
| document.getElementById('gallows-rope').style.display = 'block'; |
| |
| |
| currentWordIndex++; |
| setupWord(); |
| |
| |
| if (currentWordIndex === words.length - 1) { |
| nextWordBtn.classList.add('hidden'); |
| } |
| } |
| |
| |
| function endGame(isWin) { |
| |
| const hangman = document.querySelector('.hangman-container'); |
| hangman.classList.remove('walking'); |
| |
| if (isWin) { |
| gameResultTitle.textContent = 'You Win!'; |
| gameResultTitle.className = 'text-3xl font-bold mb-4 text-center text-green-600'; |
| gameResultMessage.textContent = `Congratulations! You guessed all ${words.length} words!`; |
| } else { |
| gameResultTitle.textContent = 'Game Over'; |
| gameResultTitle.className = 'text-3xl font-bold mb-4 text-center text-red-600'; |
| gameResultMessage.textContent = `The word was "${secretWord}". Better luck next time!`; |
| |
| |
| secretWord.split('').forEach(letter => { |
| if (!guessed |
| </html> |