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>