Home > Software design >  Why aren't all my letters showing up in my hangman javascript game?
Why aren't all my letters showing up in my hangman javascript game?

Time:05-18

This is my first post here so excuse my formatting if it's incorrect. I am building a hangman game and I am getting the letters to replace my underscores UNLESS its a double letter.

example: cheese returns only c h e _ s _

I have attached my code below:

const inputButton = document.querySelector("#wordInput")
const startButton = document.querySelector(".startButton")
const guessHere = document.querySelector(".guess")
const letters = document.querySelector(".letters")
let empty = ""
const letterA = document.querySelector("#A")
const alphabet = document.querySelectorAll(".letter")
let inputVal = ''
console.log(inputVal)
const wrongLetters = document.querySelector(".wrongLetters")
let wrongCounter = [];
let winCount = 0;
console.log(`win count is ${winCount}` )
let loseCount = 0;
console.log(`lose count is ${loseCount}`)


//-------------START BUTTON----------------------------------------------//

startButton.addEventListener("click", ()=>{
    inputVal = inputButton.value
    let chars = inputVal.split("")
    for(let i=0; i<chars.length;i  ){
        const hiddenLetter = document.createElement("span")
        hiddenLetter.classList.add("input-letters")
        hiddenLetter.id = i
        hiddenLetter.innerText = "_"
        hiddenLetter.style.marginRight = "15px"
        // const hiddenChar = document.createElement("p")
        // hiddenLetter.appendChild(hiddenChar)
        // console.log(hiddenLetter)
        // hiddenLetter.innerText = "_ "
        letters.appendChild(hiddenLetter)
        // hiddenLetter.style.height = "5px";

        hiddenLetter.style.fontSize = "50px";
       
    }
    const startingMinutes = 2;
let time = startingMinutes * 60;
const countdownEl = document.querySelector("#countdown")
let refreshIntervalid=setInterval(updateCountdown, 1000);
let once = false;
 function updateCountdown() {
    const minutes = Math.floor(time / 60);
    let seconds = time % 60;
    seconds = seconds < 10? "0"   seconds : seconds;
    countdownEl.innerHTML = `${minutes}: ${seconds}`;
    time--;
    if (time < 0) { //stop the setInterval whe time = 0 for avoid negative time
        alert("Game Over")
        clearInterval(refreshIntervalid);
    }
    once = true;


}
})
const hiddenChar = document.createElement("span")
const revealLetter = (e) =>{
    // inputVal = inputButton.value
    // console.log(inputVal);
    let chars = inputVal.split("")
    // console.log(chars)
    let guessedLetter = e.target.id.toLowerCase()
    console.log(guessedLetter);
    let index = chars.indexOf(guessedLetter)
    if (chars.includes(guessedLetter)){
        // console.log("Letter exists", guessedLetter);
        // console.log(chars.indexOf(guessedLetter));
        let underlines = document.querySelectorAll(".input-letters")
        underlines.forEach(span =>{
            // console.log("span id: ", typeof span.id);
            // console.log("index: ", typeof index);
            if(parseInt(span.id) === index){
                console.log("Match!");
                span.innerText = guessedLetter
                winCount  
                console.log(winCount)
                e.target.remove()
                if(winCount===chars.length){
                    alert("You won the Game!")

                }
                

            }
            
        })
    }else{
        wrongCounter.push(guessedLetter)
        wrongLetters.innerText = wrongCounter
        loseCount =1
        console.log(loseCount)
        e.target.remove()
        if(loseCount>=5){
            alert("Game Over!")
        }
        

    }
    // for(let i = 0; i < chars.length; i  ){
    //         const hiddenChar = document.createElement("span")
    //         console.log(hiddenChar)
    //         hiddenChar.innerText = chars[i]   " "
    //         letters.appendChild(hiddenChar)
    //         hiddenChar.style.fontSize = "50px"
    //         hiddenChar.style.visibility = "hidden"
    //         // "visible"
    //         // "hidden"
    //         if (chars[i]==("")){
    //             hiddenChar.style.visibility = "visible"
    //         }
    // }
}

alphabet.forEach(letter=>{
    letter.addEventListener("click", revealLetter)
})
body{
    background-color: #ffe4c4;
    display:flex;
    flex-direction: column;
    flex-wrap: wrap;
}
.playerOne{
    border-style: double;
    border-width: 1em;
    text-align: center;
     height: 200px;
}
.wrongLettersBox{
    border-style: double;
    border-width: 1em;
    width: 200px;
    height: 300px;
   
    text-align: center;
    
    
}
.container{
    display: flex;
}
#wordInput{
    /* transform: translate(574px, 43px); */
    color: black;
    text-transform: uppercase
}


.startButton{
    /* transform: translate(572px, 43px); */
}
.enterWordHere{
    /* transform: translate(588px, 31px); */
}
.guess{
    text-align: center;
    border-style: double;
    border-width: 1em;
    width: 828px;
    height: 300px;
}
.image{
    border-style: double;
    border-width: 1em;
    height: 300px;
    width: 300px;
}
.alphabet{
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
}
.letter{
    height: 50px;
    width: 50px;
    border-style: dashed;
    text-align: center;
    background-color: rgb(200, 149, 60);
    color: rgb(242, 242, 242);
}
#countdown{
    font-size: 20px;
    color:red;
}
<!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">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<div >
    <h1 >Snowman</h1>
    <h3 >Enter your word here:</h3>
    <input type="text" id="wordInput" name="wordInput">
    <button >Start</button>
    <p id="countdown"></p>
</div>
<div >
    <div >
        <h3>Image goes here!</h3>
    </div>
<div >
    <h3>Guess Here!</h3>
    <div ></div>
    
</div>

<body>
    <div >
        Wrong Letters
        <div ></div>
    </div>
</div>
<div >
<div  id="A">A</div>
<div  id="B">B</div>
<div  id="C">C</div>
<div  id="D">D</div>
<div  id="E">E</div>
<div  id="F">F</div>
<div  id="G">G</div>
<div  id="H">H</div>
<div  id="I">I</div>
<div  id="J">J</div>
<div  id="K">K</div>
<div  id="L">L</div>
<div  id="M">M</div>
<div  id="N">N</div>
<div  id="O">O</div>
<div  id="P">P</div>
<div  id="Q">Q</div>
<div  id="R">R</div>
<div  id="S">S</div>
<div  id="T">T</div>
<div  id="U">U</div>
<div  id="V">V</div>
<div  id="W">W</div>
<div  id="X">X</div>
<div  id="Y">Y</div>
<div  id="Z">Z</div>
</div>

<script src="script.js"></script>    
</body>
</html>

Basically I think what is happening is that the computer is getting the ids and comparing them. But once its a duplicate letter like double "A" its getting the first letter A and skipping the rest.

CodePudding user response:

let index = chars.indexOf(guessedLetter)

The indexOf method only gets the first match it finds.

Since you're already looping, you don't need to use indexOf. Instead check if chars[parseInt(span.id)] === guessedLetter

if (chars.includes(guessedLetter)){
    let underlines = document.querySelectorAll(".input-letters")
    underlines.forEach(span => {
        if (chars[parseInt(span.id)] === guessedLetter) {
            console.log("Match!");
            span.innerText = guessedLetter
            winCount  
            console.log(winCount)
            e.target.remove()
            if(winCount===chars.length){
                alert("You won the Game!")
            }
        }
         
    })
}

CodePudding user response:

This may not be entirely helpful, but in reverse engineering I took a slightly different track. I use an array to contain the original word, along with an array that gets spliced along the way when you get correct letters. Also I show how you can use simple buttons for the letters without having to code in ID or other attributes.

let word = "abba".split("")
let chars = [...word]
let underlines = document.querySelectorAll(".input-letters")
const revealLetter = (e) => {
  let guessedLetter = e.target.innerText.toLowerCase()
  let index = chars.indexOf(guessedLetter)
  if (index > -1) {
    chars.splice(index, 1);
    let found = false
    word.forEach((e, i) => {
      if (e === guessedLetter && underlines[i].innerText == "_" && !found) {
        found = true;
        underlines[i].innerText = e;
      }
    })
    if (chars.length == 0) console.log("You won the Game!")
  } else {
    console.log('wrong');
  }
}

document.querySelectorAll('.alphabet button').forEach(letter => {
  letter.addEventListener("click", revealLetter)
})
<div class='alphabet'>
  <button>a</button><button>b</button><button>c</button>
</div>

<div>
  <span class='input-letters'>_</span>
  <span class='input-letters'>_</span>
  <span class='input-letters'>_</span>
  <span class='input-letters'>_</span>
</div>

  • Related