Home > Back-end >  Limit incorrect guess attempts in Hangman Javascript
Limit incorrect guess attempts in Hangman Javascript

Time:05-07

I'm trying to code a hangman game where a user only has three incorrect guess attempts. i.e. if they guess the correct letter they continue playing. If they guess incorrectly three times then the game ends.

I've seen some other solutions where functions are used but I'm not at that point in my JS journey yet, so I'm hoping someone can use some basic syntax.

I'm guessing it's a general no-no to further nest 'if', 'else if' and 'else' statements in an 'else' statement. I've also tried to add another 'for loop' in the 'while loop' but this just breaks as well.

As the code stands now, when I enter a correct OR incorrect letter, the game terminates and shows me the final alert. Could someone pls explain to me what's happening?

Thanks :)

var words = [
    "javascript",
    "monkey",
    "amazing",
    "pancake",
    "discipline",
    "integrity",
    "enjoy"
]

var word = words[Math.floor(Math.random() * words.length)];

console.log(word);

var answerArray = [];
for (var i = 0; i < word.length; i  ) {
    answerArray[i] = "_";
}
console.log(answerArray);

var remainingLetters = word.length;
console.log(remainingLetters);

var maxTries = 3;
var guessedWrong = [];

while (remainingLetters > 0 && guessedWords.length < maxTries) {
    alert(answerArray.join(" "));
    var guess = prompt("Guess a letter, or click Cancel to stop playing.");
    guess = guess.toLowerCase();
   
    if (guess === null) {
        break;
    } else if (guess.length !== 1) {
            alert("please enter a single letter.");
        } else {
            for (var j = 0; j < word.length; j  ) {
                if (guess === word[j]) {
                    answerArray[j] = guess;
                    remainingLetters--;
                    // if incorrect letter guessed, then push to guessedWrong array;
                    // have tried another 'if', 'else if', and 'else' here but luck;
                } else if (guess !== word[j]) {
                    guessedWrong.push(guess);
                }          
            }
        }

}

alert(answerArray.join(" "));
alert("Good job! The answer was "   word);

CodePudding user response:

  • The problem was that the if clause that was incrementing guessedWrong was being called for each character in the word, and regardless of the input character. That means that at the end of one while iteration, guessedWrong.length would've been close to word.length, ending the game.
  • I've added a check to customize the end game message depending on whether the word was found or not
  • also wrapped everything in a function to demonstrate how to use functions.
  • have added comment blocks to detail the changes, most of them are towards the end of the code
  • I hope this helps

This implementation is great and you're doing a great job. Good luck on your journey!

function startGame() {
  var words = [
      "javascript",
      "monkey",
      "amazing",
      "pancake",
      "discipline",
      "integrity",
      "enjoy"
  ]

  var word = words[Math.floor(Math.random() * words.length)];

  console.log(word);

  var answerArray = [];
  for (var i = 0; i < word.length; i  ) {
      answerArray[i] = "_";
  }
  console.log(answerArray);

  var remainingLetters = word.length;
  console.log(remainingLetters);

  var maxTries = 3;
  var guessedWrong = [];

  while (remainingLetters > 0 && guessedWrong.length < maxTries) {
      alert(answerArray.join(" "));
      var guess = prompt("Guess a letter, or click Cancel to stop playing.");
      guess = guess.toLowerCase();
     
      if (guess === null) {
          break;
      } else if (guess.length !== 1) {
          alert("please enter a single letter.");
      } else {
          for (var j = 0; j < word.length; j  ) {
              if (guess === word[j]) {
                  answerArray[j] = guess;
                  remainingLetters--;
                  // if incorrect letter guessed, then push to guessedWrong array;
                  // have tried another 'if', 'else if', and 'else' here but luck;
              }
              // if we add the if check here inside the for loop, then with each iteration we wrongfully increment
              // the guessedWrong array, and game will be over on next while iteration.
              // so we've moved it outside the for loop
          }
          
          // String.indexOf() returns -1 if a specific character is not found inside that string. otherwise it will return
          // the position at which that character is first found inside the string. we can also use lastIndexOf() which checks
          // for the same thing, except it starts looking from the end of the array.
          if (word.indexOf(guess) === -1) {
              guessedWrong.push(guess);
          }
      }
  }

  // here we've customized the alert depending on whether the game was won or not
  if (guessedWrong.length == maxTries) {
    alert('Sorry, you have exhausted all attempts. The correct answer was '   word);
  } else {
    alert("Good job! The answer was "   word);
  }
  
  // we've wrapped the whole thing in a function so that we can call it and start the game again. 
  if (confirm('Do you want to play again?')) {
    startGame()
  }
}

// since it's a function, we have to call it to start the game
startGame()

CodePudding user response:

I slightly modified your implementation and it seems to work well

take a look

var words = [
  "javascript",
  "monkey",
  "amazing",
  "pancake",
  "discipline",
  "integrity",
  "enjoy"
]

const word = words[Math.floor(Math.random() * words.length)];

console.log(word);

let answerArray = word.split('').map(_ => '_');
const letters = new Set(word.split(''))


console.log(letters);
let errors = 0;
const maxRetry = 3

while (true) {
  alert(answerArray.join(" "));
  let guess = prompt("Guess a letter, or click Cancel to stop playing.");

  if (guess === null) {
    continue;
  } else if (guess.length !== 1) {
    alert("please enter a single letter.");
    continue;
  }
  guess = guess.toLowerCase().trim()
  if (!letters.has(guess)) {
    errors  
    if (errors === maxRetry) {
      alert('you lose the answer was '   word)
      break;
    }
  }

  word.split('').forEach((l, i) => {
    if (l === guess) {
      answerArray[i] = l
      letters.delete(l)
    }
  })
  if (letters.size === 0) {
    alert(answerArray.join(" "));
    alert("Good job! The answer was "   word);
    break;
  }

}

  • Related