I just developed the hangman game in javascript. I want to add the number of chances the player is left with after giving a wrong answer. Let's say I want to give him a maximum of 7 chances. I also want it to be displayed in the prompt.
var words = ["THE GRAND BUDAPEST HOTEL","MATRIX RELOADED","GLADIATOR","BEN HUR","SAVING PRIVATE RYAN"];
var word = words[Math.floor(Math.random() * words.length)];
var answerArray = [];
for (var i = 0; i < word.length; i++)
{
answerArray[i] = "_";
if (word[i] === " ")
{
answerArray[i] = " ";
}
}
var remainingLetters = word.length;
while( remainingLetters > 0)
{
alert(answerArray.join(" "));
var guess = prompt("Guess a letter or click cancel to stop playing.");
guess = guess.toUpperCase();
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 (word[j] === guess)
{
answerArray[j] = guess;
remainingLetters--;
}
}
}
}
alert(answerArray.join(" "));
alert("Good job! The answer was " + word);
Add a tries variable at the beginning, initialized with max chances.
Add a condition to your while loop, tries must be > 0
Add it to the prompt :
"Guess a letter or click cancel to stop playing." + tries + " remaining"
If user don't guess a letter (figure this out yourself), decrement tries
At the end, check if user has succeeded (for example check if tries == 0)
If not, print that : (from http://www.berkeleyinternet.com/perl/node30.html)
var hangString = "";
hangString += " ________ \n";
hangString += "| | \n";
hangString += "| 0 \n";
hangString += "| /|\\ \n";
hangString += "| / \\ \n";
hangString += "| \n";
Related
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);
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()
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;
}
}
I need to prompt the user to enter a series of numbers, or the word "quit".
Then, If the user enters a number, add the new number to a running total.
And, If the user enters the word "quit" the loop should stop execution.
I cant figure what should I do here. Im a beginner. i don't know how to make it work when user enter a word quit
let total = 0;
let number = 0;
do {
total += number;
number = parseInt(prompt('Enter a number: '));
if (number >= 0) {
document.writeln("<p>You entered " + number + "!</p>");
} else {
if (isNaN(number)) {
number = parseInt(prompt('Enter a number: '));
document.writeln("<p>Try again. We are looking for a number!</p>");
}
}
} while (number >= 0)
document.writeln("<p>The total is " + total + "</p>")
Use break to stop the javascript loop:
let total = 0;
let number = 0;
do {
total += number;
text = prompt('Enter a number: ');
if (text == "quit") {
break;
}
number = parseInt(text);
if (number >= 0) {
document.writeln("<p>You entered " + number + "!</p>");
} else {
if (isNaN(number)) {
number = parseInt(prompt('Enter a number: '));
document.writeln("<p>Try again. We are looking for a number!</p>");
}
}
} while(number >= 0)
document.writeln("<p>The total is " + total + "</p>")
I need help with my hangman game, how do I stop lives going down if players guess repeated letter before, as for now if I run it and player guesses the same letter, it will output that he have already made this guess but the lives is dropping too. Also if players keep input the same correct letter, it will output that he have already made this guesses but it will say he won after inputting the same letter 4-5 times.
1st error: lives dropping even if players use letter that is guessed before
2nd error: players input the same correct letter guessed and game will say he won after inputting 4-5 times
Code
guesses = [];
// Show player their progress | .join returned answer as a string
while (remainingLetters > 0 && lives > 0) {
(answerArray.join(""));
guess = readline.question(name+"'s guess (Enter 9 for lifelines or 0 to pass): ");
guess = guess.toUpperCase();
//if guess is more than 1 letter or no letter, alert player to guess 1 letter only
if (guess.length !== 1) {
console.log("Please enter 1 letter only.");
}
//if valid guess
else {
correctGuess = 0;
for (var j = 0; j < Word.length; j++) {
if (Word[j] == guess) {
answerArray[j] = guess;
remainingLetters--;
correctGuess = 1;
}
}
if (correctGuess == 1) {
console.log("\nGood job! "+guess+" is one of the letters!\n");
console.log(JSON.stringify(answerArray)+"\n");
console.log(JSON.stringify(alphabets)+"\n");
} else {
lives -= 1;
console.log("\nSorry. "+guess+" is not a part of the word.\n");
console.log(JSON.stringify(answerArray)+"\n");
console.log(JSON.stringify(alphabets)+"\n");
console.log("You have "+lives+" lives remaining.\n");
}
if (guesses.includes(guess)) {
console.log("You have already made this guess, please try another letter!\n");
} else {
guesses.push(guess)
}
}
if (remainingLetters == 0) {
console.log("Congratulation! You managed to guess the word!\n");
break;
}
if (lives == 0) {
console.log("Game Over... You failed to guess the word. The word is "+Word+".\n")
}
}
Inside else for valid guess move your entire code inside else of if (guesses.includes(guess)) {. It will solve both of your issues.
// Show player their progress | .join returned answer as a string
while (remainingLetters > 0 && lives > 0) {
(answerArray.join(""));
guess = readline.question(name + "'s guess (Enter 9 for lifelines or 0 to pass): ");
guess = guess.toUpperCase();
//if guess is more than 1 letter or no letter, alert player to guess 1 letter only
if (guess.length !== 1) {
console.log("Please enter 1 letter only.");
}
//if valid guess
else {
if (guesses.includes(guess)) {
console.log("You have already made this guess, please try another letter!\n");
} else {
guesses.push(guess);
correctGuess = 0;
for (var j = 0; j < Word.length; j++) {
if (Word[j] == guess) {
answerArray[j] = guess;
remainingLetters--;
correctGuess = 1;
}
}
if (correctGuess == 1) {
console.log("\nGood job! " + guess + " is one of the letters!\n");
console.log(JSON.stringify(answerArray) + "\n");
console.log(JSON.stringify(alphabets) + "\n");
} else {
lives -= 1;
console.log("\nSorry. " + guess + " is not a part of the word.\n");
console.log(JSON.stringify(answerArray) + "\n");
console.log(JSON.stringify(alphabets) + "\n");
console.log("You have " + lives + " lives remaining.\n");
}
}
}
if (remainingLetters == 0) {
console.log("Congratulation! You managed to guess the word!\n");
break;
}
if (lives == 0) {
console.log("Game Over... You failed to guess the word. The word is " + Word + ".\n")
}
}
This code should show an alert box if there are no double spaces but it's not doing that.
var str = prompt("Enter Some Text");
var numChars = str.length;
for (var i = 0; i < numChars; i++) {
if (str.slice(i, i + 2) === " ") {
alert("No double spaces!");
break;
}
}
alert will pop out if no double spaces
You could make this a little simpler with an indexOf check:
var str = prompt("Enter Some Text");
if (str.indexOf(" ") === -1) {
alert("No double spaces!");
}
a simple regular expression can do it :
const str = prompt("Enter Some Text");
!/\s\s/.test(str) && alert('No double spaces found !');
If you want to keep that with the for approach, you should invert the logic and check whether the double whitespace occurs:
var str = prompt("Enter Some Text");
var numChars = str.length;
var doubleWhitespace = false;
for (var i = 0; i < numChars; i++) {
// get the current and next character.
var [curr, next] = [str[i], str[i + 1]];
// if both exists and current is the same as next and both the characters are spaces
if (curr && next && curr === next && curr === ' ') {
// double white space.
doubleWhitespace = true;
break;
}
}
if (doubleWhitespace) alert('There is a double space!');
else alert('NO double space');
However, there is a slightly easier solution by just using indexOf:
var str = prompt("Enter Some Text");
if (str.indexOf(' ') > -1) alert("There are double spaces!");
else alert("There are no double spaces!");
you need change this line
if (str.slice(i, i + 2) === " ") {
with
if (str.slice(i, i + 2) === " ") {
i wrote a very basic hangman game but it skips the actual hangman part. It will show the alert for how long the word is you press ok then it show the finish message no game part and i can't find out why
please tell me what is wrong
Hangman
<body>
<h1>Hangman!</h1>
<script>
var words = [
"javascript",
"monkey",
"amazing",
"pancake",
];
var word = words[Math.floor(Math.random() * words.length)];
var answerArray = [];
for (var i = 0; i < word.length; i++) {
answerArray[i] = "_"
}
var remainingLetters = word.length
while (remainingLetters < 0) {
alert(answerArray.join(" "));
var guess = prompt("Guess a letter, or click Cancel to stop playing>");
if (guess === null) {
break;
} else if (guess.length !== 1) {
alert("Please enter a single letter.");
} else {
//update the game state with a guess
for (var j = 0; j < word.length; j++) {
if (word[j] === guess) {
answerArray[j] = guess;
remainingLetters--;
}
}
}
}
alert(answerArray.join(" "));
alert("Good Job! The answer was " + word);
</script>
</body>
</html>
while (remainingLetters < 0) { should be while (remainingLetters > 0) {.
Also, as Pluto mentioned it (good catch!), you can cheat by entering the same letter over and over. To solve that, you could store the guessed letters in a string and check if it was guessed before (and not increment the score).
Another adjustment, if the user hits cancel (wants to quit), I added an if statement at the end so that no more alerts are displayed.
var words = ["javascript", "monkey", "amazing", "pancake"];
var word = words[Math.floor(Math.random() * words.length)];
var answerArray = [];
// Storing the letters already guessed
var guessedLetters = "";
for (var i = 0; i < word.length; i++) {
answerArray[i] = "_"
}
var remainingLetters = word.length;
while (remainingLetters > 0) {
alert(answerArray.join(" "));
var guess = prompt("Guess a letter, or click Cancel to stop playing>");
if (guess === null) {
break;
} else if (guess.length !== 1) {
alert("Please enter a single letter.");
} else {
// if the letter was already guessed
if (guessedLetters.indexOf(guess) > -1) {
// skip
continue;
}
//update the game state with a guess
for (var j = 0; j < word.length; j++) {
if (word[j] === guess) {
answerArray[j] = guess;
// add the letter to the guessed letters
guessedLetters += guess;
remainingLetters--;
}
}
}
}
// if there are no remaining letters (if the user cancelled,
// no need to show these).
if( !remainingLetters) {
alert(answerArray.join(" "));
alert("Good Job! The answer was " + word);
}
JS Fiddle Demo