skip to Main Content

I am trying to make a hangman game using JavaScript.

I’ve come at impasse and can’t find any answers online. I’m trying to create a function for when the letter is clicked, it checks to see if its in the word. And if it’s in the word, it will replace the "_" with the letter. I’ve tried looking through other forums but I can’t find anything.

Code:

let category = document.querySelector('.category')
let word = document.querySelector('.word')
let lives = document.querySelector('.lives')
let clue = document.querySelector('.clue')
const hintbutton = document.querySelector('.hint')
const playAgainButton = document.querySelector('.play-again')
let userLives = 10
let guessed = []

// generate random word
const gameWords = ['Doctor', 'MichaelJackson', 'Prince', 'Giraffe', 'LionKing']
let result = gameWords[Math.floor(Math.random() * gameWords.length)]

console.log(result)


// create a _ for each letter that is in the word 
function randomWord() {
  let str = " ";
  for (i = 0; i < result.length; i++) {
    str = str + "_ "
  }
  return str
}
word.innerHTML = randomWord()

// Hint function. returns a clue when hint button is clicked 

function hint() {
  hintbutton.addEventListener('click', function() {
    if (result == 'MichaelJackson' || result == 'Prince') {
      return clue.innerHTML = 'Clue - Music Artist'
    } else if (result == 'Giraffe') {
      return clue.innerHTML = 'Clue - Animal'
    } else if (result == 'Doctor') {
      return clue.innerHTML = 'Clue - Occupation'
    } else {
      return clue.innerHTML = 'Clue - Movie'
    }
  })
}

hint()



// once letter is clicked the letter is greyed out and can no longer be clicked 
function fadeOut() {
  const letters = document.querySelectorAll('.letter')
  letters.forEach(letter => {
    letter.addEventListener('click', function() {
      letter.style.opacity = '0.4'
    })
  })
}


// when user clicks a letter: if letter is in word. letter appends to the place where letter is in the word.
// if letter is not in word the user loses a life
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hangman Game</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="container">
    <div class="title">Hangman</div>
    <div>Use the alphabet below to guess the word, or click hint to get a clue</div>
    <div class="letters">
      <button class="letter">a</button>
      <button class="letter">b</button>
      <button class="letter">c</button>
      <button class="letter">e</button>
      <button class="letter">d</button>
      <button class="letter">f</button>
      <button class="letter">g</button>
      <button class="letter">h</button>
      <button class="letter">i</button>
      <button class="letter">j</button>
      <button class="letter">k</button>
      <button class="letter">l</button>
      <button class="letter">m</button>
      <button class="letter">n</button>
      <button class="letter">o</button>
      <button class="letter">p</button>
      <button class="letter">q</button>
      <button class="letter">r</button>
      <button class="letter">s</button>
      <button class="letter">t</button>
      <button class="letter">u</button>
      <button class="letter">v</button>
      <button class="letter">w</button>
      <button class="letter">x</button>
      <button class="letter">y</button>
      <button class="letter">z</button>
    </div>
    <div class="category">The chosen category is</div>
    <div class="word"> </div>
    <div class="lives">you have 10 lives! </div>
    <div class="clue">Clue - </div>
    <div class="box"></div>

    <div class="buttons">
      <button class="hint">Hint</button>
      <button class="play-again">Play again</button>
    </div>
  </div>
  <script src="script.js"></script>
</body>

</html>

I tried creating an event listener for each button and writing an if statement once the button is clicked.

I’m not sure if that’s the right way to approach it, but I’m not even sure how to start the code for matching the clicked letter with the word.

2

Answers


  1. You can access the element clicked using this. this.innerHTML will give the letter clicked.

    You can check if the letter is in the word using indexOf, if it returns -1 then the letter is not in the word.

    Letter buttons are lowercase but result contains a mixture of upper and lower cases. Suppose result = 'Giraffe'. If g is clicked, it will not match G. Therefore toLowerCase is used to make result lowercase so matching will succeed.

    const category = document.querySelector('.category')
    const word = document.querySelector('.word')
    const lives = document.querySelector('.lives')
    const clue = document.querySelector('.clue')
    const hintbutton = document.querySelector('.hint')
    const playAgainButton = document.querySelector('.play-again')
    let userLives = 10
    const guessed = []
    
    // generate random word
    const gameWords = ['Doctor', 'MichaelJackson', 'Prince', 'Giraffe', 'LionKing']
    const result = gameWords[Math.floor(Math.random() * gameWords.length)]
    
    console.log(result)
    
    
    // create a _ for each letter that is in the word 
    for (i = 0; i < result.length; i++) {
        guessed.push('_')
    }
    
    word.innerHTML = guessed.join('')
    
    hintbutton.addEventListener('click', function () {
        if (result == 'MichaelJackson' || result == 'Prince') {
            return clue.innerHTML = 'Clue - Music Artist'
        }
        else if (result == 'Giraffe') {
            return clue.innerHTML = 'Clue - Animal'
        }
        else if (result == 'Doctor') {
            return clue.innerHTML = 'Clue - Occupation'
        }
        else {
            return clue.innerHTML = 'Clue - Movie'
        }
    })
    
    function letterHandler(){
        const letter = this.innerHTML
        const lowerResult = result.toLowerCase()
        // check if the letter is in the result
        if(lowerResult.indexOf(letter) != -1){
            for(i = 0; i < lowerResult.length; i++){
                // if the guessed letter matches the result, reveal it
                if(lowerResult[i] == letter){
                    guessed[i] = result[i]
                }
            }
            word.innerHTML = guessed.join('')
            if(guessed.join('') == result){
                alert('You win!')
            }
        } else{
            userLives -= 1
            if(userLives == 0){
                alert('You lose!')
            }
            lives.innerHTML = 'You have ' + userLives + ' lives!'
        }
        this.disabled = true
    }
    
    
    // once letter is clicked the letter is greyed out and can no longer be clicked 
    const letters = document.querySelectorAll('.letter')
    letters.forEach(letter => {
        letter.addEventListener('click', letterHandler)
    })
    

    I’ve also replaced some let with const where appropriate and removed functions like hint and randomWord which weren’t really necessary. Using disabled instead of style.opacity has the same visual effect but means the event listener won’t fire on buttons which have already been clicked.

    Login or Signup to reply.
  2. you can use innerHTML for this and takeout the listnner of the fadeout().
    With that you have to deal with how to show the correct letters, the word.includes(letter) should be enough

    const letters = document.querySelectorAll(".letter");
    letters.forEach((letter) => {
      letter.addEventListener("click", function () {
        letter.style.opacity = "0.4";
        console.log(letter.innerHTML);
        word.innerHTML = `<div> ${input.value}</div>`;
      });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search