In my last tutorial I described the snake game I built using JavaScript, and before that I built a version of minesweeper. For this week’s post I decided to show you guys how to build hangman with JavaScript. I’m sure there are plenty of coding choices I’ve made that can be criticized, but hopefully I’ve still accomplished my goals. Namely, to have fun making little games and teach people a little bit about JavaScript and programming.
Click here to play movie hangman!
Here are the three files necessary for creating the hangman game:
I already know what you’re thinking. How did I afford such an outstanding artist? Believe it or not, I actually created that condemned bandit artwork all on my own. Like most professional programmers, I can wear multiple hats.
I loved playing hangman when I was growing up as a kid. It’s one of those rare games that teaches you important concepts without you even realizing it. In order to become good at hangman, you have to become proficient with language. Another thing I loved as a kid (and still do) was watching movies. So naturally, I decided to combine these two passions and create “Movie Hangman”.
Unlike my previous game tutorials, I decided to build hangman with mobile users foremost in mind. To accomplish this I used something called CSS media queries. We use these to apply different CSS rules for different screen sizes. Be sure to check it out in the CSS file if you’re interested, as the bulk of this post covers the JavaScript game logic.
Alright, let’s start learning how to build hangman with JavaScript.
Rules of Hangman
- A word or phrase is chosen for the player to guess.
- Initially, the player can only see how many letters and words make up the full word or phrase.
- The player begins by guessing letters. Each correct guess reveals every location where the letter exists in the word or phrase. Each incorrect guess results in another piece of the man getting added to the gallows.
- If he thinks he knows it, the player is also allowed to guess the entire word or phrase.
- The player wins if he successfully guess the word or phrase. He loses if he completes the picture of the condemned man, resulting in his grim demise.
Game Object
The Game function is responsible for creating our game object. This object will be responsible for holding the data about the current state of the game and the methods for acting upon that data. The game object will have 7 internal variables for handling state: word, guessedLetters, maskedWord, incorrectGuesses, possibleGuesses, won, and lost.
The word variable stores the word that the player is trying to guess. We assign it a random movie from our list of movies when we initialize the game object.
The guessedLetters variable is an array. We use it to store letters as the player guesses them.
The maskedWord variable is the word or phrase as it is displayed to the player. It starts out as a bunch of underscores with spaces separating the words, and it slowly gets filled in as the player makes more correct guesses. We initialize it via a for-loop.
The incorrectGuesses variable is a counter for storing the number of times the player has guessed incorrectly. Too many wrong guesses and the player will lose the game. Naturally, this counter starts at zero.
The possibleGuesses variable is a string containing all of the letters in the alphabet. Letters are removed as they are guessed. These are displayed to the player so he doesn’t have to remember what he has already guessed.
The won and lost variables keep track of whether the player has won or lost the game. These are displayed to the player when the game is over.
Public Methods of the Game Object
- getWord: A simple getter for the word variable.
- getMaskedWord: A simple getter for the maskedWord variable.
- guess: We call this function whenever a player guesses a letter. After capitalizing the letter for consistency we make sure it hasn’t already been guessed. Then we add it to the the array of guessed letters and remove it from our list of possible guesses. If the word contains the guessed letter we determine what the indexes of those matches are. Then, we reveal those letters in the masked word that is displayed to the player. If the word does not contain the guessed letter we call the private handleIncorrectGuess function to increment the number of incorrect guesses and check for a loss.
- getPossibleGuesses: The possibleGuesses variable returned as an array using the spread syntax.
- getIncorrectGuesses: A simple getter for the incorrectGuesses variable.
- guessWord: We call this function whenever the player wants to take a guess at the entire word or phrase.
- isWon: A simple getter for the won variable.
- isLost: A simple getter for the lost variable.
Private Methods of the Game Object
- guessAllLetters: This function loops through all of the letters in the word and calls guess on them. Its purpose is to display the movie title after the player guesses it correctly, or alternatively when the player has lost the game.
- handleIncorrectGuess: This function takes care of a few things whenever a player guesses wrongly. It updates the number of incorrect guesses and checks for a loss. If a loss has a occurred, it calls guessAllLetters.
There is one more function worth talking about in this section called replace. It doesn’t really belong in our game object because it has utility outside of that context. We are gonna keep it on its own in case we ever decide to use it later.
The function takes a string, an index, and a replacement string as parameters. It substitutes the replacement string for the character at the specified index. We use it to replace underscores with characters in our masked word.
That wraps up our discussion about the game object. Let’s move on and talk about how we handle player input.
Handling Player Input
Our goal is to make this game a fun experience on a desktop computer as well as a mobile phone. In order to do that we need to offer a few different ways to play.
One way to play involves using the keyboard to enter letters. This works great on a full-fledged hardware setup, but not so great on a mobile phone. For mobile users we ought to offer a way to use the touchscreen to make guesses.
Guessing a letter
Both of these input methods resolve down to the same basic action: sending a letter to our game object as a guess. This is a pretty good indicator that we should have a common function for handling this logic.
We will call this function guessLetter. It resides inside the listenForInput function which will be used for setting up our input handling logic. When called, and as long as the game is still going on, this function calls guess on our game object and then calls render to update the screen. We’ll talk more about the render function momentarily.
For both the keyboard and touchscreen input we attach event listeners to the document body.
Handling Touchscreen Input
When the player touches a letter (or clicks on it with his mouse), the handleClick function is called. This function checks the class list of the HTML element that was clicked. If the class list contains the “guess” class, that letter is passed to the guessLetter function.
Handling Keyboard Input
Handling keyboard input is a bit more complicated because there are more features to implement and more validation is necessary. The function that takes care of all this is called handleKeyPress.
The first thing we do is calculate some values that will help us take appropriate action. One of the first things we do is determine if the key that was pressed is a letter. Then, we grab HTML elements representing the guess word button, the new game button, and the guess box. We also check to see if the guess box is already populated with a win/loss message.
Finally, we take action. If the cursor is not in the guess box and player pressed a letter, we make a guess. If the game is over and the player pressed enter, we start a new game. And if the player pressed enter, the game is still going on, and there is content inside the guess box, we take a guess at the full movie title.
Guessing the Word
The player can take a guess at the full word by clicking the guess word button. He can also do so by pressing enter, as we saw in the previous section. When this occurs, the guessWord function is called.
This function first checks if the game is still going on. If it is, the guessWord function of the game object is called, and then render is called to update the screen.
Rendering the Graphics
Let’s discuss how to update the screen after changes are made to the game object. This is handled by the render function, and it is called after every guess that the player makes.
Overall it’s a pretty simple function. We set the innerHTML of the different elements that correspond to the data in our game object. We also set the image by using a neat little naming convention hack.
The trickiest part of this function is how we render the possible remaining guesses to the screen. We have to clear out the div and then loop through the possible guesses variable, appending the appropriate span as we go along.
Starting a New Game of Hangman
Okay, we’re almost done building hangman. Soon you’ll have all of the pieces needed for learning how to build hangman with JavaScript. The last thing to cover is kicking off a new game!
When the page loads, we call the Game function to create a new game object. Then we call render to display the game data to the screen, and call listenForInput to, well, start listening for input from the player.
We also have a function called newGame. If you observe the HTML, you’ll see that this function is attached to the new game button. Instead of going to the trouble of resetting our game object and event listeners, we use a neat little trick to go back to the most recent URL in the browser history. This should redirect the player to the URL of the hangman game, and reinitialize all of the JavaScript.
Conclusion
Congrats on learning how to build hangman with JavaScript! Hopefully it makes sense after breaking it up into modules like this. If you have questions or see ways to improve the code, I’d love to hear from you in the comments!
For your next steps, you could try adding some more features, like different, selectable word categories or supporting characters besides just letters.
Let me know in the comments what other simple games like this you would like to see, and don’t forget to drop me your email so you don’t miss the next one that comes out. You will also receive my free checklist for writing great functions.
Take care, and God bless!
This is one of the crisp work I have ever seen with a good explanation of code.
Is there a way to add a score and score table on this game, if possible could you tell me how to do it cause I can’t seem to make it work.
Thank you
Thanks for the kind words! Yeah, you could implement something like that. I haven’t implemented it, and I’m not sure exactly what you have in mind. But I imagine you could come up with some kind of scoring system to keep track of how many words guessed correctly in a certain time frame (or some other metric). Then you could store it client side (https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage) to pull back later. I cover that topic a bit in my ear trainer tutorial: (https://mitchum.blog/how-to-build-an-ear-trainer-with-javascript/). If you wanted a scoring table for multiple users…well you’d probably need some server side code to handle that.
Thanks so much for posting this. Since l am quite new to programming l need to see the code as guidance and, unfortunately, your HTML code doesn’t go to the code, but instead to the game itself. Could you fix that so l may have a chance of trying this myself? Thanks again.
Ah good point. Thanks for sharing that observation. One thing you can do to see it is right click on the page and then click view source. That should show you the html code itself, instead of how the browser renders it.
Bookmarked!, I love your web site!