Why does my program skip the game part? - javascript

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

Related

Limit incorrect guess attempts in Hangman Javascript

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;
}
}

Hangman game same letter validation javascript only

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")
}
}

- I am trying to write a code where input should be abbbcc and output should be a1b3c2

I am new to js.
I am trying to write a code where input should be abbbcc and output should be a1b3c2.
not sure how to get it
providing code below
var word = "abbbcc";
var countword = [];
for (i=0; i < word.length; i++) {
if (word[i] === charAt && word[i] != word[i+1]) {
countword.push(word[i]);
countword.push(i++);
}
else (word[i] === charAt && word[i] != word[i+1]) {
countword.push(word[i]);
for (i=0; i < word.length; i++) {
if (word[i+1] === word[i+2]) {
countword.push(i++);
}
else{
break;
}
}
}
}
console.log("result----->" + countword);
It can be done using a for loop and a counter like this.
var word = "abbbcc";
var countword = "";
var counter = 1;
for (i=0; i < word.length; i++) {
if ( word[i] != word[i+1]) {
// Save the letter and the counter
countword += word[i]+counter;
// Reset the counter
counter=1;
}else{
// Increment counter
counter++;
}
}
console.log("result-----> " + countword );
Alternative solution using Array#reduce. I've described each step, I hope you will get my point and understand how does it works.
var word = "abbbcc".split(''),
res = '',
counter = 1;
word.reduce(function(s, a, i, r) {
if (s !== a) { //if the succeeding element doesn't match the previous one
res += s + counter; //concat it to the string + the amount of appearances (counter)
counter = 1; //reset the counter
} else {
counter++; //the succeeding element matches the previous one, increment the counter
}
if (i === r.length - 1 && counter > 0) { //if the loop is over
res += s + counter; //add the last element
}
return a;
})
console.log(res);

number of chances in hangman game in javascript

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";

Battleship game: Allowing hits to be registered on ships with lengths other than 4

I'm making Battleship in JavaScript for a school project and I'm stuck.
The computer randomly generates boats and the user has to try to sink all the computer's boats by entering in coordinates. The hits on a boat are saved in an array. The array contains zeros to signify the boat's length (so boat with length 4 has an array with 4 zeros). When a boat is hit, the 0 changes to 1. If all the elements are 1, the boat sinks. Problem is my code registers the hits, but only puts it in an array when you hit the boat with length 4.
Can anyone help me? Below is the code of the "game" itself:
function game() {
inputArray = [4, 3, 2];
var boats = randomBoats(inputArray);
var currentBoat = 0;
var sunkenBoat = 0;
var numberOfTurns = 0;
while (sunkenBoat !== inputArray.length) {
var hit = false;
var target = "(" + prompt("Enter targetcoordinate (x,y)") + ")";
var targetString = target.replace(/\s+/g, '');
for (var i = 0; i !== inputArray.length; i++) {
for (var j = 0; j !== boats[i].usedPositions().length; j++) {
console.log(targetString)
if (targetString === boats[i].usedPositions()[j].toString()) {
raak = true;
boats[i].hits[j] = 1;
console.log(boats[i].hits);
currentBoat = boats[i];
} else {
currentBoat = boats[i];
}
}
}
console.log(currentBoat.hits);
console.log(allEquals(currentBoat.hits, 1));
if (hit)
alert("Hit!");
else
alert("Miss!");
if (allEquals(currentBoat.hits, 1)) {
alert("Boat with length " + currentBoat.hits.length + " has sunken!");
sunkenBoat++;
}
numberOfTurns++
}
alert("You've won! You did it in " + numberOfTurns + " turns.")
}
The issue is with the else in the inner loop, as you processed each ship (outer loop) and all positions (inner loop) your
else {
currentBoat = boats[i];
}
would always set the current boat to be the last [i];
You also don't need to process any other positions or boats when you've found a hit, so break early when you detect the hit like this:
raak = false;
for(var i = 0; i < inputArray.length && !raak; i++) {
for(var j = 0; j !== boats[i].usedPositions().length; j++) {
console.log(targetString)
if(targetString === boats[i].usedPositions()[j].toString()) {
raak = true;
boats[i].hits[j] = 1;
console.log(boats[i].hits);
currentBoat = boats[i];
break;
}
}
}

Categories

Resources