简体   繁体   中英

Replacing underscores with letters of corresponding word in Hangman game in Javascript

I've been searching for the answers to a couple of questions about a Hangman game that I'm working on but I can't seem to come across a solution that works for me. From what I've found it looks like maybe I'd have to use a global regular expression so that way it replaces every instance of the matching letter???

Here are the 3 main problems I'm having:

  1. I'm not sure how to get the letters to show up in place of where they correspond with the underscores. So for example, if the word is 'apple' I have my code pushing out blanks as __ __ __ __ __, then when a user presses the P key, I'd want it to update the word to __ PP __ __, then if they pressed the A key I'd want it to change to A __ PP __ __. Currently I have it set up so if you press any letter that is correct in the word it'll display the full word, I'm not sure how to go about pushing the corresponding letters into the correct index of the word as they are guessed...

  2. It would be nice if the onKeyUp events would only register letters and do nothing when any other character is pressed.

  3. I can't seem to find a way to make sure that you can only guess each letter one time. For example, if the word is 'apple' and I press the Z key, the letter Z will show up in my Letters Already Guessed section of my page, but if I press Z again, it will show up a second time. I'd like it so that after the first time you press a key it doesn't register the duplicate and either does nothing or alerts you that you've already used that letter.

Here's my code below, I know there are some things that I probably could accomplish the same thing with by using fewer lines of code but I'm still learning, basically started with HTML and CSS about 4 weeks ago. And sorry for the long-ish post, I just wanted to make sure I put all the details out there.

  // This is our array of words for the game var words = ['grey', 'school', 'warrior', 'thunder', 'real', 'shark', 'butter', 'tomato', 'potato', 'university', 'popcorn', 'progress', 'elephant', 'phone', 'artist', 'handkerchief', 'chemistry', 'picture', 'camera', 'alternate', 'sandwich', 'water', 'traitor', 'america', 'basketball', 'personal', 'homerun', 'apple', 'banana', 'monster', 'lightning', 'microphone', 'door', 'monitor', 'television', 'prisoner', 'detective', 'breaking', 'solution', 'fantasy', 'ocean', 'president', 'patio', 'titanic', 'candy', 'hamburger', 'currency', 'copper', 'buffalo', 'cowboy']; console var currentWord = words[Math.floor(Math.random() * words.length)].toUpperCase(); // This variable holds the number of guesses left var guessesLeft = 6; document.getElementById("guesses-left").innerHTML = guessesLeft; // This variable will count the number of times we won var wins = 0; document.getElementById("wins").innerHTML = wins; var resetLettersGuessed = "" // This is an empty array that we will push our blanks to var progressWord = []; // This is an array that we will push the letters from the current word to // for comparison of whether the player's guess is correct or not var mysteryWord = []; // This will store our random generated word so we can see the answer in the console // for our reference for (i = 0; i < currentWord.length; i++) {} console.log(currentWord.toUpperCase()); // This is the code that will push out blank spaces for the letters of the current // word so the player can see the word and begin to guess letters for (var i = 0; i < currentWord.length; i++) { progressWord.push("__"); progressWord.toString() document.getElementById("word-guess").innerHTML = progressWord.join(" "); } console.log(progressWord); // This is the code that will push out the letters of the current word // to the new variable fo comparison for (var i = 0; i < currentWord.length; i++) { mysteryWord.push(currentWord.charAt(i)); mysteryWord.toString(i) } console.log(mysteryWord) // These are the key events used to play and to document the letters already used and/or // letters in the answers document.onkeyup = function(onKeyUp) { letter = onKeyUp.keyCode; lettersGuessed = String.fromCharCode(letter); console.log(lettersGuessed); // This will alert correct and compare the letter guessed with the current word if (lettersGuessed === mysteryWord[0] || lettersGuessed === mysteryWord[1] || lettersGuessed === mysteryWord[2] || lettersGuessed === mysteryWord[3] || lettersGuessed === mysteryWord[4] || lettersGuessed === mysteryWord[5] || lettersGuessed === mysteryWord[6] || lettersGuessed === mysteryWord[7] || lettersGuessed === mysteryWord[8] || lettersGuessed === mysteryWord[9] || lettersGuessed === mysteryWord[10] || lettersGuessed === mysteryWord[11] || lettersGuessed === mysteryWord[12] || lettersGuessed === mysteryWord[13] || lettersGuessed === mysteryWord[14] || lettersGuessed === mysteryWord[15] || lettersGuessed === mysteryWord[16] || lettersGuessed === mysteryWord[17] || lettersGuessed === mysteryWord[18] || lettersGuessed === mysteryWord[19] || lettersGuessed === mysteryWord[20]) { // alert("CORRECT!"); // replace progress Word underscore with letter pressed document.getElementById("word-guess").innerHTML = mysteryWord.join(" "); } else { // alert("WRONG!"); document.getElementById("letters-guessed").innerHTML += lettersGuessed + " "; // subtract a point from guesses left guessesLeft--; document.getElementById("guesses-left").innerHTML = guessesLeft; } // This code will tell the user the game is over along with a message about // their win streak, then it will reset the game while quickly showing // what the word was if (guessesLeft === 0) { alert("Game Over! You finished with a streak of " + wins + " wins! The word was " + currentWord); location.reload(); document.getElementById("word-guess").innerHTML = currentWord; } // this is the code that alerts you when you've won the game, then it will reset // the current word to begin another round if (currentWord === progressWord) { var phrases = ['Yup! Onto the next one!', 'Leggo!','You like the Air Jordan of Hangman!', 'Dont hurt em!', 'Turn up!', 'Go and brush ya shoulders off!', 'In the zone!'] var nextRound = phrases[Math.floor(Math.random() * phrases.length)]; alert(nextRound); // reset guesses left guessesLeft = 6; document.getElementById("guesses-left").innerHTML = guessesLeft; // reset letters guessed document.getElementById("letters-guessed").innerHTML = resetLettersGuessed; // This code generates a new word to guess and then pushes out the blanks again currentWord = words[Math.floor(Math.random() * words.length)].toUpperCase(); progressWord = []; for (var i = 0; i < currentWord.length; i++) { progressWord.push("__"); progressWord.toString() document.getElementById("word-guess").innerHTML = progressWord.join(" "); } mysteryWord = [] for (var i = 0; i < currentWord.length; i++) { mysteryWord.push(currentWord.charAt(i)); mysteryWord.toString(i) } console.log(currentWord); console.log(progressWord); console.log(mysteryWord); // Add to the win total wins++; document.getElementById("wins").innerHTML = wins; } } 
 body { padding: 0; background-color: ; } header { margin-bottom: 2.5%; border-bottom: 0px solid black; background-image: url("../images/hangman-header.jpg"); background-size: 100% 125px; height: 125px; } footer { background-image: url("../images/hangman-footer.jpg"); bottom: 0; left: 0; height: 7%; width: 100%; color: black; font-weight: 500; text-align: center; position: fixed; line-height: 3em; border-top: 3px solid lightgray; } hr { width: 90%; margin-bottom: 3%; margin-top: 0%; } h1 { margin-top: -2%; margin-bottom: 0%; text-align: center; font-size: 28px; line-height: 50px; } h2 { margin-bottom: 0%, 0%, 0%, 20%; font-size: 29px; text-align: center; } h3 { padding: 0%; margin-top: 0%; margin-bottom: 2%; background-color: #FFFFFF; border: 0px solid black; font-size: 18px; } ul { padding: 0; margin-bottom: 15%; margin-top: 10%; word-break: break-all; } li { padding: 1%; margin-bottom: -3%; margin-top: -7.5%; list-style: none; font-size: 20px; text-align: center; border: 0px solid black; font-weight: 600; color: #9ca6ba; background-color: white; } .main-section { border: 0px solid black; height: 55%; margin-bottom: 0%; margin-top: -3%; padding-left: 5%; padding-right: 5%; } .top-label { border: 1px solid black; } 
 <!DOCTYPE html> <html> <head> <title>Hangman!</title> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Modified CSS file --> <link rel="stylesheet" type="text/css" href="assets/css/hangman-style.css"> <!-- CSS for Google Fonts --> <link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet"> <!-- Javascript is enabled --> </head> <body> <header> </header> <div class="container-fluid"> <div class="row"> <div class="col-md-4 col-md-offset-4 top-label"> <br> <h1>Press any key to get started!</h1> <hr> <ul> <li>Total Wins: </li> <br> <center><h3><span id="wins"></span></h3></center> <br> <br> <li># of Guesses Remaining: </li> <br> <center><h3><span id="guesses-left"></span></h3></center> <br> <br> <li>Letters Already Guessed: </li> <br> <center><h3><span id="letters-guessed"></span></h3></center> <br> <br> <li>Current Word: </li> <center> <br> <h3><span id="word-guess"></span></h3></center> </ul> </div> </div> </div> <footer>Copyright 2017</footer> </div> <script type="text/javascript" src="assets/javascript/game.js"></script> </body> </html> 

There is a lot going on here but I will just try to help with one part of it which is checking to see if the letter exists in the word and if it does, replace the _ with the letter.

const words = ['John', 'Jacob', 'Jingleheimersmith']

function chooseWord(array) {
  return array[Math.floor(Math.random() * array.length)].toUpperCase()
}

function fillInWordWithLetter(letter, word) {
  return word.toLowerCase().split('').map(l =>  {
    if (l === letter) {
      return l.toUpperCase()
    }
    return '_'
  }).join(' ')
}

fillInWordWithLetter('j', chooseWord(words))

If you run this in the console you will see how the word is updated with the letter if the letter exists in the word, otherwise it returns the _ . This should help get you in the right direction and you may have to fiddle around with it to make it do what you need it to. After getting the letter filled into the word you should be able to update the DOM with the new word with the letters inserted.

Here it is in REPL.it: https://repl.it/IVO3/1

I have made a simple web page based on your code that does most of what you wanted - see below.

My general comments:

  1. When using just ES5 JavaScript remember that variables declarations are "global" in its scope so using several var i in for statement refers to the same i variable!
  2. You declared all your code variables on the document scope - this is in general a bad behavior - I did not change it but you should read about making JavaScript modules etc.

     <!DOCTYPE html> 

    body { padding: 0; background-color:; }

      header { margin-bottom: 2.5%; border-bottom: 0px solid black; background-image: url("../images/hangman-header.jpg"); background-size: 100% 125px; height: 125px; } footer { background-image: url("../images/hangman-footer.jpg"); bottom: 0; left: 0; height: 7%; width: 100%; color: black; font-weight: 500; text-align: center; position: fixed; line-height: 3em; border-top: 3px solid lightgray; } hr { width: 90%; margin-bottom: 3%; margin-top: 0%; } h1 { text-align: center; font-size: 28px; line-height: 50px; } h2 { font-size: 29px; text-align: center; } h3 { padding: 0%; background-color: #FFFFFF; font-size: 18px; } ul { padding: 0; margin-bottom: 15%; margin-top: 10%; word-break: break-all; } li { list-style: none; font-size: 20px; text-align: center; border: 0px solid black; font-weight: 600; color: #9ca6ba; background-color: white; } .main-section { border: 0px solid black; height: 55%; margin-bottom: 0%; padding-left: 5%; padding-right: 5%; } .top-label { border: 1px solid black; } </style> 

     <header> </header> <div class="container-fluid"> <div class="row"> <div class="col-md-4 col-md-offset-4 top-label"> <br> <h1>Press any key to get started!</h1> <hr> <ul> <li> Total Wins: <h3><span id="wins"></span></h3> </li> <li> # of Guesses Remaining: <h3><span id="guesses-left"></span></h3> </li> <li> Letters Already Guessed: <h3><span id="letters-guessed"></span></h3> </li> <li> Current Word: <br /> <h3><span id="word-guess"></span></h3> </li> </ul> </div> </div> </div> <footer>Copyright XYZ 2017</footer> <script type="text/javascript"> // This is our array of words for the game var words = ['grey', 'school', 'warrior', 'thunder', 'real', 'shark', 'butter', 'tomato', 'potato', 'university', 'popcorn', 'progress', 'elephant', 'phone', 'artist', 'handkerchief', 'chemistry', 'picture', 'camera', 'alternate', 'sandwich', 'water', 'traitor', 'america', 'basketball', 'personal', 'homerun', 'apple', 'banana', 'monster', 'lightning', 'microphone', 'door', 'monitor', 'television', 'prisoner', 'detective', 'breaking', 'solution', 'fantasy', 'ocean', 'president', 'patio', 'titanic', 'candy', 'hamburger', 'currency', 'copper', 'buffalo', 'cowboy']; var currentWord = words[Math.floor(Math.random() * words.length)].toUpperCase(); // This variable holds the number of guesses left var guessesLeft = 6; document.getElementById("guesses-left").innerHTML = guessesLeft; // This variable will count the number of times we won var wins = 0; document.getElementById("wins").innerHTML = wins; var resetLettersGuessed = "" // This is an empty array that we will push our blanks to var progressWord = []; // This is an array that we will push the letters from the current word to // for comparison of whether the player's guess is correct or not var mysteryWord = []; var i; console.log("Current word is: " + currentWord); // This is the code that will push out blank spaces for the letters of the current // word so the player can see the word and begin to guess letters for (i = 0; i < currentWord.length; i++) { progressWord.push("__"); } document.getElementById("word-guess").innerHTML = progressWord.join(" "); // function evaluating the positions of the given letter in the currentWord string // return empty array in case of failure function letterInWord(letter) { // the array that will contain the char positions in the currentWord that has the var positions = new Array(); for (i = 0 ; i < currentWord.length; i++) { if (currentWord[i] === letter) positions.push(i); } return positions; } // return number of letters that is still not guessed function lettersToGuess() { var i ; var toGess = 0 ; for (i in progressWord) { if (progressWord[i] === "__") toGess++; } return toGess; } // These are the key events used to play and to document the letters already used and/or // letters in the answers document.onkeyup = function (event) { var letter = event.key; var lettersGuessed = letter.toLocaleUpperCase(); var i; console.log("You have typed a letter: ".concat(letter)); var positions = letterInWord(lettersGuessed); // This will alert correct and compare the letter guessed with the current word if (positions.length) { console.log("User has pressed a letter from word: " + letter); for (i = 0 ; i < positions.length; i++) { progressWord[positions[i]] = lettersGuessed; } // replace progress Word underscore with letter pressed document.getElementById("word-guess").innerHTML = progressWord.join(" "); } else { // alert("WRONG!"); document.getElementById("letters-guessed").innerHTML += lettersGuessed + " "; // subtract a point from guesses left guessesLeft--; document.getElementById("guesses-left").innerHTML = guessesLeft; } // This code will tell the user the game is over along with a message about // their win streak, then it will reset the game while quickly showing // what the word was if (guessesLeft === 0) { alert("Game Over! You finished with a streak of " + wins + " wins! The word was " + currentWord); location.reload(); } // this is the code that alerts you when you've won the game, then it will reset // the current word to begin another round if (lettersToGuess() == 0) { var phrases = ['Yup! Onto the next one!', 'Leggo!', 'You like the Air Jordan of Hangman!', 'Dont hurt em!', 'Turn up!', 'Go and brush ya shoulders off!', 'In the zone!'] var nextRound = phrases[Math.floor(Math.random() * phrases.length)]; alert(nextRound); // reset guesses left guessesLeft = 6; document.getElementById("guesses-left").innerHTML = guessesLeft; // reset letters guessed document.getElementById("letters-guessed").innerHTML = resetLettersGuessed; // This code generates a new word to guess and then pushes out the blanks again currentWord = words[Math.floor(Math.random() * words.length)].toUpperCase(); progressWord = []; for (i = 0; i < currentWord.length; i++) { progressWord.push("__"); } document.getElementById("word-guess").innerHTML = progressWord.join(" "); // Add to the win total wins++; document.getElementById("wins").innerHTML = wins; } } </script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM