Skip to content

JJWallis/hangman-app

Repository files navigation

Hangman Game

This project was a personal challenge of mine - to build a fully functioning Hangman game

Table of contents

Overview

The challenge

Your users should be able to:

  • Interact with the 'Start Game' button to begin playing the game
  • Enter their letter of choice and recieve correct validation if input is invalid
  • Submit their letter of choice and receive confirmation of whether they guessed correctly
  • The timer should terminate after 30 seconds and prompt the user to restart the game
  • For each incorrect guess, an additional version of the hangman image should be displayed, as well decreasing the number of guesses remaining
  • Each correctly guessed letter should be displayed to the user at its corresponding position in the word

Screenshot

Links

My process

Built with

  • Semantic HTML5 markup
  • Flexbox
  • JavaScript
  • ES6 Modules

What I learned

<p id="word-to-guess">
   <span id="letter0">_</span>
   <span id="letter1">_</span>
   <span id="letter2">_</span>
   <span id="letter3">_</span>
</p>

I first attempted to reveal the correctly guessed letter within one single <p>, before then realising I needed to individually match each letter position with that corresponding letter's index value in the 'selected word' array. I was proud of my ability to semantically produce this solution inside a <p> wrapper, using <span> tags which wouldn't add any more unnecessary semantic meaning to the words' markup.

<pre id="hangman-img" class="hangman">
      +—+
      | |
   
         |
   
         |
   
         |
   
         |
   
   =========
</pre>

This project was my first time using the <pre> tag in action which, although is clearly powerful in displaying whatever string you present it with, also presents a major issue in controlling the alignment of the data. In the future, it would be better to use images of each hangman position which could then be controlled much easier within the CSS so they would change at the same point to achieve a level of uniformity.

.error-icon {
   background: url('/images/exclamation-solid.svg') no-repeat 90% center / 4%;
}

To add to the visual representation of invalid inputted data, I decided to practice dynamically toggling different background icons from an error class which was applied to the input. For future projects, I feel using a fixed px value for the positioning could help with controlling the icon's position if other content around it were to responsively adjust.

   timerBegin: () => setInterval(timerCount, 1000),
   timerEnd: () => clearInterval(finish),

In order to build the restricted timer logic, I had to first setup the timer using the built in asynchronous function setInterval(), whilst further learning how to cancel it appropiately based on specific events occuring. This callback function will probably end up being more useful than setTimeout(), but I will need to research how to account for 'browser teething' issues, that cause the function to run at an increasingly delayed time compared to the amount you manually set.

const random = () => Math.floor(Math.random() * 9) + 1
const word = words[random()]
functions.element(guess, 'value', '')
return word.split('')

I was proud of my ability to run the random() function inside the array selection syntax, as well as making use of the split() method to return that word in the desired format.

Continued development

In regards to storing the words which were used in the game, I chose to hardcode them into an array manually to test if my random number selection logic worked. However, in the future I realise you would pull this kind of data from an external API, which could therefore be much more dynamic in creating different topics and word lengths.

I kept track of the game's 'state' through multiple number variables in the global scope, which in the future I will try to refactor by potentially using an object to store all of them, or reverse their individual logic for multiple purposes (if one increases, then the other should decrease).

Useful resources

  • Pig Game Project - Completing this game in advance really helped me with a lot of the base logic for games, such as only executing the game via boolean logic which determines if it is currently being played, or if the user has pressed the 'start' button.

  • JavaScript - ES6 Modules - Kyle's quick crash course like tutorial helped me quickly get up to speed with Modules in JavaScript, focusing on the theory behind how they work and the difference between default and named imports.

Author