Hangman Game in Javascript
Introduction to Hangman Game
Hangman is a classic word guessing game where one player thinks of a word and the other player tries to guess it by suggesting letters within a certain number of guesses. If the guessing player suggests a letter that occurs in the word, the other player fills in the blanks with that letter in the correct positions. If the suggested letter does not occur in the word, the other player draws one element of a hangman stick figure as a tally mark.
Get Programing Is Fun’s stories in your inbox
Join Medium for free to get updates from this writer.
In this tutorial, we’ll build a Hangman game using HTML, CSS, and JavaScript. The game will include features such as displaying the word to be guessed, tracking correct and incorrect guesses, drawing the Hangman figure using HTML5 Canvas, and displaying messages for win or loss conditions.
HTML Structure
The HTML structure defines the layout and elements needed for the Hangman game:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hangman Game</title>
<style>
/* CSS styles are defined here */
</style>
</head>
<body>
<div class="game-container">
<h1>Hangman</h1>
<div id="word-container"></div>
<div id="wrong-letters-container">
<p>Wrong Letters:</p>
<span id="wrong-letters"></span>
</div>
<div id="message-container" class="hidden">
<p id="message"></p>
</div>
<div id="notification-container" class="hidden">
<p>You have already entered this letter</p>
</div>
<canvas id="hangman" width="200" height="200"></canvas>
<div class="keyboard">
<!-- Buttons for each letter -->
</div>
</div>
<script>
// JavaScript logic is defined here
</script>
</body>
</html>Explanation:
<div class="game-container">: This is the main container for the game UI, holding all the game elements.<h1>Hangman</h1>: Displays the title of the game.<div id="word-container">: Container to display the word with underscores for each letter.<div id="wrong-letters-container">: Displays the letters guessed incorrectly.<div id="message-container" class="hidden">: Container to display messages like "Congratulations! You won!" or "Unfortunately, you lost!".<div id="notification-container" class="hidden">: Notification container to show messages like "You have already entered this letter".<canvas id="hangman" width="200" height="200"></canvas>: Canvas element to draw the Hangman figure.<div class="keyboard">: Container for letter buttons that players click to guess letters.
CSS Styling
The CSS styles define the appearance of the Hangman game:
body {
/* Center the game vertically and horizontally */
display: flex;
justify-content: center;
align-items: center;
height: 100vh; /* Full viewport height */
margin: 0;
font-family: 'Arial', sans-serif;
background-color: #282c34; /* Dark background color */
color: #fff; /* Text color */
}
.game-container {
text-align: center;
background: #3a3f47; /* Darker background for the game area */
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); /* Box shadow for depth */
}
#word-container {
margin-top: 20px;
font-size: 24px;
}
#wrong-letters-container {
margin-top: 20px;
}
#wrong-letters-container p {
margin: 0;
}
#wrong-letters-container span {
font-size: 18px;
margin-right: 5px;
}
#message-container {
margin-top: 20px;
}
.hidden {
display: none;
}
canvas {
margin-top: 20px;
background: #fff;
border-radius: 10px;
}
.keyboard {
margin-top: 20px;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.keyboard button {
margin: 5px;
padding: 10px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 5px;
background: #61dafb;
color: #282c34;
transition: background 0.3s;
}
.keyboard button:hover {
background: #21a1f1;
}
#notification-container {
margin-top: 10px;
background: #ff7675;
padding: 10px;
border-radius: 5px;
color: #fff;
}Explanation:
body: Centers the game on the screen with a dark background and white text..game-container: Centers content, adds padding, a darker background, rounded corners, and a box shadow for a card-like appearance.#word-container: Styles for displaying the word with underscores for unguessed letters.#wrong-letters-container: Styles for displaying incorrectly guessed letters..keyboard button: Styles for letter buttons including padding, background color, and hover effects.#notification-container: Styles for the notification container with a red background and white text.
JavaScript Logic
The JavaScript handles the game’s functionality, including word selection, letter guessing, drawing the Hangman figure, and displaying messages:
const wordContainer = document.getElementById('word-container');
const wrongLettersContainer = document.getElementById('wrong-letters');
const messageContainer = document.getElementById('message-container');
const message = document.getElementById('message');
const notificationContainer = document.getElementById('notification-container');
const hangmanCanvas = document.getElementById('hangman');
const ctx = hangmanCanvas.getContext('2d');
const buttons = document.querySelectorAll('.keyboard button');
const words = ['javascript', 'programming', 'hangman', 'interface', 'browser'];
let selectedWord = words[Math.floor(Math.random() * words.length)];
let correctLetters = [];
let wrongLetters = [];
function displayWord() {
wordContainer.innerHTML = `
${selectedWord
.split('')
.map(letter => `<span>${correctLetters.includes(letter) ? letter : ''}</span>`)
.join('')}
`;
const innerWord = wordContainer.innerText.replace(/\n/g, '');
if (innerWord === selectedWord) {
message.innerText = 'Congratulations! You won!';
messageContainer.classList.remove('hidden');
}
}
function updateWrongLetters() {
wrongLettersContainer.innerHTML = `
${wrongLetters.length > 0 ? '<p>Wrong Letters:</p>' : ''}
${wrongLetters.map(letter => `<span>${letter}</span>`).join('')}
`;
drawHangman();
}
function showNotification() {
notificationContainer.classList.add('show');
setTimeout(() => {
notificationContainer.classList.remove('show');
}, 2000);
}
function drawHangman() {
const errors = wrongLetters.length;
ctx.clearRect(0, 0, hangmanCanvas.width, hangmanCanvas.height);
if (errors > 0) {
// Draw parts of the hangman depending on the number of wrong letters
// Base
ctx.fillRect(10, 180, 100, 10);
// Pole
ctx.fillRect(50, 10, 10, 170);
// Top beam
ctx.fillRect(50, 10, 80, 10);
// Rope
ctx.fillRect(120, 10, 10, 30);
}
if (errors > 1) {
// Head
ctx.beginPath();
ctx.arc(125, 50, 20, 0, Math.PI * 2);
ctx.stroke();
}
if (errors > 2) {
// Body
ctx.fillRect(120, 70, 10, 50);
}
if (errors > 3) {
// Left arm
ctx.moveTo(125, 80);
ctx.lineTo(100, 100);
ctx.stroke();
}
if (errors > 4) {
// Right arm
ctx.moveTo(125, 80);
ctx.lineTo(150, 100);
ctx.stroke();
}
if (errors > 5) {
// Left leg
ctx.moveTo(125, 120);
ctx.lineTo(100, 150);
ctx.stroke();
}
if (errors > 6) {
// Right leg
ctx.moveTo(125, 120);
ctx.lineTo(150, 150);
ctx.stroke();
message.innerText = 'Unfortunately, you lost!';
messageContainer.classList.remove('hidden');
}
}
buttons.forEach(button => {
button.addEventListener('click', () => {
const letter = button.innerText.toLowerCase();
if (selectedWord.includes(letter)) {
if (!correctLetters.includes(letter)) {
correctLetters.push(letter);
displayWord();
} else {
showNotification();
}
} else {
if (!wrongLetters.includes(letter)) {
wrongLetters.push(letter);
updateWrongLetters();
} else {
showNotification();
}
}
});
});
displayWord(); // Initial display of word with underscoresExplanation:
- Variables:
wordContainer,wrongLettersContainer, etc., store references to HTML elements for interaction. words: Array of words from which a random word is selected for each game session.selectedWord: Randomly chosen word fromwordsarray.correctLetters: Array to store correctly guessed letters.wrongLetters: Array to store incorrectly guessed letters.displayWord(): UpdateswordContainerwith underscores for unguessed letters and actual letters for guessed ones.updateWrongLetters(): UpdateswrongLettersContainerwith incorrectly guessed letters and draws the Hangman figure accordingly.showNotification(): Displays a notification innotificationContainerif the same letter is guessed more than once.drawHangman(): Draws parts of the Hangman figure onhangmanCanvasbased on the number of incorrect guesses.- Event Listeners: Each button in
buttonsadds an event listener to handle letter guesses when clicked. displayWord(): Initial call to display the word with underscores for unguessed letters at the start of the game.
Detailed Walkthrough
Initialization and Setup
The game starts by defining necessary variables such as wordContainer, wrongLettersContainer, etc., which store references to HTML elements where game content will be displayed. The words array contains a set of words from which one will be randomly selected for each game session.
const wordContainer = document.getElementById('word-container');
const wrongLettersContainer = document.getElementById('wrong-letters');
const messageContainer = document.getElementById('message-container');
const message = document.getElementById('message');
const notificationContainer = document.getElementById('notification-container');
const hangmanCanvas = document.getElementById('hangman');
const ctx = hangmanCanvas.getContext('2d');
const buttons = document.querySelectorAll('.keyboard button');
const words = ['javascript', 'programming', 'hangman', 'interface', 'browser'];
let selectedWord = words[Math.floor(Math.random() * words.length)];
let correctLetters = [];
let wrongLetters = [];displayWord() Function
The displayWord() function updates the wordContainer with the current state of the word being guessed. It checks each letter of selectedWord and displays it if correctly guessed (correctLetters array contains the letter), or displays an underscore if not guessed yet.
function displayWord() {
wordContainer.innerHTML = `
${selectedWord
.split('')
.map(letter => `<span>${correctLetters.includes(letter) ? letter : ''}</span>`)
.join('')}
`;
const innerWord = wordContainer.innerText.replace(/\n/g, '');
if (innerWord === selectedWord) {
message.innerText = 'Congratulations! You won!';
messageContainer.classList.remove('hidden');
}
}updateWrongLetters() Function
The updateWrongLetters() function updates the wrongLettersContainer with letters that have been incorrectly guessed. It also calls the drawHangman() function to update the Hangman figure on the canvas based on the number of incorrect guesses (wrongLetters array length).
function updateWrongLetters() {
wrongLettersContainer.innerHTML = `
${wrongLetters.length > 0 ? '<p>Wrong Letters:</p>' : ''}
${wrongLetters.map(letter => `<span>${letter}</span>`).join('')}
`;
drawHangman();
}Drawing the Hangman Figure
The drawHangman() function uses the HTML5 Canvas API to draw different parts of the Hangman figure based on the number of incorrect guesses (wrongLetters array length).
function drawHangman() {
const errors = wrongLetters.length;
ctx.clearRect(0, 0, hangmanCanvas.width, hangmanCanvas.height);
if (errors > 0) {
// Draw parts of the hangman depending on the number of wrong letters
// Base
ctx.fillRect(10, 180, 100, 10);
// Pole
ctx.fillRect(50, 10, 10, 170);
// Top beam
ctx.fillRect(50, 10, 80, 10);
// Rope
ctx.fillRect(120, 10, 10, 30);
}
if (errors > 1) {
// Head
ctx.beginPath();
ctx.arc(125, 50, 20, 0, Math.PI * 2);
ctx.stroke();
}
if (errors > 2) {
// Body
ctx.fillRect(120, 70, 10, 50);
}
if (errors > 3) {
// Left arm
ctx.moveTo(125, 80);
ctx.lineTo(100, 100);
ctx.stroke();
}
if (errors > 4) {
// Right arm
ctx.moveTo(125, 80);
ctx.lineTo(150, 100);
ctx.stroke();
}
if (errors > 5) {
// Left leg
ctx.moveTo(125, 120);
ctx.lineTo(100, 150);
ctx.stroke();
}
if (errors > 6) {
// Right leg
ctx.moveTo(125, 120);
ctx.lineTo(150, 150);
ctx.stroke();
message.innerText = 'Unfortunately, you lost!';
messageContainer.classList.remove('hidden');
}
}Handling Button Clicks
Event listeners are added to each button in the buttons NodeList. When a button is clicked, the corresponding letter is checked against selectedWord. If it matches, it is added to correctLetters and displayWord() is called. If it does not match, it is added to wrongLetters and updateWrongLetters() is called. A notification is shown if the same letter is clicked more than once.
buttons.forEach(button => {
button.addEventListener('click', () => {
const letter = button.innerText.toLowerCase();
if (selectedWord.includes(letter)) {
if (!correctLetters.includes(letter)) {
correctLetters.push(letter);
displayWord();
} else {
showNotification();
}
} else {
if (!wrongLetters.includes(letter)) {
wrongLetters.push(letter);
updateWrongLetters();
} else {
showNotification();
}
});
});End Game Conditions
When all letters in selectedWord are correctly guessed (innerWord === selectedWord), the message "Congratulations! You won!" is displayed in messageContainer. If the Hangman figure is fully drawn (errors > 6), the message "Unfortunately, you lost!" is displayed.
Summary
This Hangman game implementation uses HTML for structure, CSS for styling, and JavaScript for game logic. Players guess letters by clicking buttons, and the game updates with correct guesses, wrong guesses, Hangman figure drawings, and messages to indicate game progress. This setup provides an interactive and visually appealing experience for users playing the game in a web browser environment.
This tutorial covered the complete implementation of a Hangman game, from setting up the HTML structure and styling with CSS to implementing game logic with JavaScript. Players can enjoy guessing words and seeing the Hangman figure drawn dynamically on the canvas as they play. This project serves as a great introduction to basic web development concepts and the integration of HTML, CSS, and JavaScript to create interactive games.
THANK YOU for your time. If there is any bug with the code I would really appriciate it if you guys could report it.








