In today’s tutorial, we will learn how to code a number memorising game in JavaScript. In this game. In this project, in the beginning, the user is presented with three difficulty levels easy, medium, and hard. Once they click on one of the options. They are shown a number which they have to memorize within 2 seconds after the time finish.
The number disappears, and they have to enter it into the input field after submitting the answer. They are told whether it is correct or not in the top right corner, the game also keeps track of how many they have answered correctly. Additionally, they can also end the game, which will take them back to the start screen.
What should you know before you start?
- HTML
- CSS
- JavaScript
What will we learn?
- Know how to create a function
- Know how to invoke or call a function
- Understand Javascript’s built-in
setTimeout
function - know Javascript’s addEventListener()
- Know what variable scope is
- know DOM manipulation in JavaScript
- know JavaScript Math Functions
Math.floor()
Math.random()
- know javascript function isNaN( )
You can see the Demo Here Number Memorising Game In JavaScript
Implementation Number Memorising Game In JavaScript
To implement the Number Memorising Game, first, we need to create a folder(Number Memorising Game in JavaScript) for our HTML, CSS, and JavaScript files with their respective extensions (.html, .css, .js). You could use any editor you wish but for this tutorial, I’d prefer you use vs code.
create index.html
Here we are making an attractive UI of Number Memorising Game In JavaScript
Create your HTML file, name it index.html. The code snippet below shows the HTML file structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Number Memorising Game In JavaScript</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>JavaScript Game</h1>
<button id="end" class="hide">End game</button>
<p id="total"></p>
<div id="level">
<p>Select difficulty:</p>
<button id="easy" class="difficulty">Easy</button>
<button id="medium" class="difficulty">Medium</button>
<button id="hard" class="difficulty">Hard</button>
</div>
<div id="game" class="hide">
<div id="numbers"></div>
<form>
<label for="answer">Type in number</label>
<input type="text" id="answer" autocomplete="off">
<button type="submit" id="submit">Submit</button>
</form>
<div id="feedback"></div>
<button id="next" class="hide">Next</button>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
To link our JavaScript and CSS files in the HTML file, the script and link tags are used as shown above. Though there are other ways of adding JavaScript and CSS to HTML in this article, I choose to use the external file source.
create style.css
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;500&display=swap');
:root {
--easy: #00B3B0;
--easy-dark: #009996;
--orange: #f7a922;
--medium: #726ec4;
--medium-dark: #4f4ab5;
--hard: #E92553;
--hard-dark: #d11541;
--white: #E2DFD6;
--navy: #29265D;
--navy-light: #38347f;
--font: 'Rubik', sans-serif;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: var(--font);
}
body {
font-size: 1.5rem;
}
.container {
padding: 1em;
max-width: 500px;
margin: 1em auto;
}
h1 {
font-size: 2rem;
text-align: center;
}
form, #level {
padding: 1em 0 0;
}
label, input {
display: block;
}
input {
width: 100%;
padding: 0.8em;
margin: 1em 0;
font-size: 1.5rem;
}
.hide {
display: none;
}
button {
font-size: inherit;
cursor: pointer;
border: none;
padding: 0.7em;
display: block;
width: 100%;
margin: 1em 0;
border-radius: 0.5em;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
background-color: var(--navy-light);
color: #fff;
transition: background-color 0.2s linear;
}
button:hover {
background-color: var(--navy);
}
button:focus {
outline: none;
box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--medium);
}
#easy {
background-color: var(--easy);
}
#easy:hover {
background-color: var(--easy-dark)
}
#medium {
background-color: var(--medium);
}
#medium:hover {
background-color: var(--medium-dark);
}
#hard {
background-color: var(--hard);
}
#hard:hover {
background-color: var(--hard-dark);
}
#end {
width: auto;
float: right;
padding: 0.5em 1em;
font-size: 1rem;
}
#total {
clear: both;
text-align: right;
}
.correct {
color: var(--easy)
}
.wrong {
color: var(--hard);
}
#numbers {
color: #4743a3;
font-size: 4rem;
}
#feedback {
font-weight: 600;
font-size: 1.6rem;
}
footer {
position: absolute;
padding: 1em;
bottom: 0;
left: 0;
width: 100%;
font-size: 1rem;
text-align: center;
}
footer a {
color: var(--easy-dark);
}
footer a:hover {
color: var(--medium-dark);
}
svg {
width: 20px;
height: 20px;
margin-bottom: -3px;
stroke: var(--hard);
}
@media screen and (min-width: 48em) {
body {
background-color: var(--navy);
min-height: 100vh;
}
.container {
width: 600px;
background-color: #fff;
border-radius: 1em;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
footer {
color: #fff;
}
footer a {
color: var(--easy);
}
footer a:hover {
color: var(--medium);
}
}
💡 Now It’s time For Javascript Code 😎.
Create index.js File
JavaScript Code: For JavaScript, follow the below-given steps.
- Acessing HTML Elements
- Create a function generateNumber that function generates a random number
- Create a function assignNumber
- Create a function checkResult to check user input number with actual number is right or wrong
- add Event Listener in Form Element
- add Event Listener in next button for reassigning the number
- Create a function toggleVisibility for hiding and showing HTML element
- Create a function generateGame for starting the game According to game difficulty like easy, medium, and hard.
- update score when user enter the correct number
- add Event Lisner in the end button for ending the game
The first thing I did was to create references to the necessary HTML elements.
Step 1: Acessing HTML Elements
const numberField = document.querySelector("#numbers");
const inputField = document.querySelector("input");
const submitBtn = document.getElementById("submit");
const feedback = document.getElementById("feedback");
const nextBtn = document.getElementById("next");
const level = document.getElementById("level");
const game = document.getElementById("game");
const form = document.querySelector("form");
const end = document.getElementById("end");
const total = document.getElementById("total");
let testNumber;
The input field and submit button are as you can guess the input field where the user types in the answer and the submit button below. We only have one input build. So we use the document.queryselector in this case which will return the first input on the page.
Feedback is the div where we will tell the user whether the answer is correct or not. Currently, it is not visible. Then the next button is the next button. game is the div containing all the other elements we see and finally, we have the form again selected with queryselector.
Below, We define a variable called testNumber. This will hold a number users have to remember it will change several times. Hence we are using let instead of const. The let variables can be reassigned const, on the other hand, cannot. Several functions will also need to have access to it. So we added it to the global scope.
Step 2: Create a function generateNumber that function generates a random number
function generateNumber(){
const min=1000;
const max=9999;
return Math.floor(Math.random() * (max - min + 1)) + min;
}
The first function we will code is going to generate the test number. This should always return a number of a specific length for the easy level. It should be four digits long so basically the smallest number can be 1000 and the highest 9999. We are saving these limits in a min and max variable. we will make this dynamic based on user selection later on in this article.
Then using the following formula Math.floor(Math.random() * (max – min + 1)) + min; you can ensure that the number will always be between the minimum and maximum value specified in the math.random inbuilt javascript method is used to generate a number between 0 and 1.
For example, the random number is 0.1342. In this example, we then multiply this with 9000. if we take the max limit of 9999 and deduct the minimum of 1000. this equals 8999 by adding one we get 9000. Depending on what math.random returns we then get a number between 900 and 8999.999999. So never quite 9000 by adding the minimum limit to this number.
We ensure that the smallest number is 1000 and the highest is 99999.999 as we don’t want any decimal places. We then use math.floor inbuilt javascript method to round the number down.
Step 3: Create a function assignNumber
function assignNumber(){
testNumber = generateNumber();
numberField.innerText= testNumber;
}
Next, we will create the function the assignNumber. This will call our generateNumber function and assign it to our testNumber variable. Then it is going to access the dom element and add the number as its inner text.
Step 4: Create a function checkResult to check user input number with actual number is right or wrong
function checkResult(){
const inputValue = inputField.value;
if(parseInt(inputValue) === testNumber){
feedback.innerText ="Correct";
feedback.classList.add('correct');
feedback.classList.remove('wrong');
}else if(isNaN(inputValue)){
feedback.innerText =`Only Numbers Allowed!`;
feedback.classList.remove('correct');
feedback.classList.add('wrong');
}else{
feedback.innerText =`Incorrect The Answer Is ${testNumber}`;
feedback.classList.remove('correct');
feedback.classList.add('wrong');
}
}
We also need a checkResult function to see if the answer is correct or not. With this one we want to first get the value from the input field we can do this by accessing the value property of it. Then in an, if statement we can check if this input value equals the test number.
Now input field value returns a string to be able to use the strict comparison operator with three equal signs. We need to convert the string into a number. And another condition is to check for only Numeric values. The user should get some information on whether they got the information.
If the input value matches true we are going to change the text of the div to say correct and apply some styles. we are adding the class list correctly which will make the text green. Additionally, we are also removing the class which makes the text red. The reason we are removing wrong is that the user might have gotten a question wrong and then the next one right.
if we don’t remove it the two might interfere with each other. In the else, if statements updating text with only Numbers Allowed. In the last else statement, we are again updating the text we are telling the user they got the result wrong. And what the right answer would have been. In this case, we are removing the correct class and adding the wrong one.
Step 5: add Event Listener in Form Element
form.addEventListener('submit',function(e){
e.preventDefault();
checkResult();
})
Let’s add an event listener to the form. The event we will be listening for is called submit and will fire anytime the user submits the form. This can be done either by clicking submit or pressing enter on your keyboard. When you submit a form the default behavior of the page will be to reload. We don’t want this as it would reset all variables to stop this from happening. We can use e.preventdefault below we are going to call checkResult function.
Step 6: add Event Listener in next button for reassigning the number
nextBtn.addEventListener('click',function(e){
feedback.innerText='';
inputField.value = '';
assignNumber();
})
Let’s add the next button functionality. We are adding a click event to the next button when clicking reset the value of the feedback. So it is not visible we can assign an empty string. We can also reset the input field value by assigning an empty string. And then we only need to call the assignNumber function to get a new number.
Here when we enter the number then submit and the next button visible at all times. However, it doesn’t make sense that submit should only be visible when the user has to fill out the field. Next, on the other hand, should only be shown when the answer has been submitted. we can toggle their visibility. So we are creating toggleVisibility function.
Step 7: Create a function toggleVisibility for hiding and show HTML element
function toggleVisibility(elements){
elements.forEach(element => {
element.classList.toggle('hide');
});
}
We will always pass an array of dom elements with the for-each loop. We are toggling the hide class on each one of them. So if the element has the class hide applied it will remove it and vice versa. The hide class we have declared in our style sheet and just adds display none. When the page initially loads the next button should not be visible.
form.addEventListener('submit',function(e){
e.preventDefault();
checkResult();
toggleVisibility([submitBtn,nextBtn]);
nextBtn.focus();
})
nextBtn.addEventListener('click',function(e){
feedback.innerText='';
inputField.value = '';
assignNumber();
inputField.focus();
toggleVisibility([submitBtn,nextBtn]);
})
We are calling our new toggleVisibility function within the form event listener and passing an array with the submit and next buttons. Now when we submit our answer the submit button disappears and next appears. To make the interaction for the user easier we want to autofocus on the input field. And the next button is based on. Whether the user has provided an answer this can be really easily done with javascript.
In the form event listener, we are adding nextBtn.focus() and in the next button event listener we are adding inputField.focus() and that’s it this way the user can simply type in the number press enter. And next will already have focus when next is clicked. The input field will get focused so the user can type straight away without having to use their mouse to navigate.
function assignNumber(){
testNumber = generateNumber();
numberField.innerText= testNumber;
numberField.classList.remove('hide');
setTimeout(function(){
numberField.classList.add('hide');
},2000);
}
Now make the game challenging the number needs to disappear. We can use the javascript inbuild setTimeout function. In assignNumber function, we can add setTimeout. Which takes two arguments the first one is the callback function. This function should simply add the classlist hide to the number. The second argument is the time. After which it should get called we want to be 2000 milliseconds which equals two seconds.
Now allows users to select different difficulty levels.
Step 8: Create a function generateGame for starting the game According to game difficulty like easy, medium, and hard.
let minMax;
const difficulty={
easy:[1000,9999],
medium:[100000,999999],
hard:[10000000,99999999]
}
const difficultyBtns= document.querySelectorAll('.difficulty');
difficultyBtns.forEach((btn)=>{
btn.addEventListener('click',function(e){
const value=e.target.innerText.toLowerCase();
minMax=difficulty[value];
})
})
we define an object called difficulty it has three keys easy, medium, and hard. Each of these will have an array with the minimum and maximum number needed by the generate number function. Easy will still generate 4 digits. Medium 6 digit and hard 8 digit numbers. Next, let’s select the three difficulty buttons which will determine the min and max values and also start the game to select these elements.
We are using querySelectorAll which will return all of them then we are using a for each loop. And to each, we are assigning a click event listener when the user clicks on one of the buttons. We want to access its text. we can use e.target.innerText with to lowercase in build method. We can transform the text to be lowercase. The reason why we are doing this is that.
We are going to use this text to select the correct array from the difficulty object as the keys. Inside this object is lowercase. we need the value by which. we select it to be lower case to select it. when you need to select something from an object with a dynamic variable use the bracket notation. We are saving the appropriate array to the minMax variable.
Now Create a function generateGame.
function generateGame(minMax){
toggleVisibility([level,game]);
assignNumber(minMax);
}
function assignNumber(minMax){
testNumber = generateNumber(minMax);
numberField.innerText= testNumber;
numberField.classList.remove('hide');
setTimeout(function(){
numberField.classList.add('hide');
},2000);
}
function generateNumber(minMax){
const min=minMax[0];
const max=minMax[1];
return Math.floor(Math.random() * (max - min + 1)) + min;
}
difficultyBtns.forEach((btn)=>{
btn.addEventListener('click',function(e){
const value=e.target.innerText.toLowerCase();
minMax=difficulty[value];
generateGame(minMax);
end.classList.remove('hide');
inputField.focus();
})
})
In This function, minMax value is passed. When the game is started the difficulty buttons should disappear. And the game should appear for which we can use toggle visibility. Next, we can call the assignNumber function. Here we pass minMax and also pass in generateNumber. Now we adjust the minMax values to always make use of the array. In the different button event listener, we are calling the generateNumber function with the minMax value and we are set to autofocus on the input.
New Shows how many answers were correct.
Step 9: update score when user enter the correct number
let numOfAnswered = 0;
let numOfCorrect = 0;
difficultyBtns.forEach((btn)=>{
btn.addEventListener('click',function(e){
const value=e.target.innerText.toLowerCase();
minMax=difficulty[value];
generateGame(minMax);
end.classList.remove('hide');
total.innerText = `Total: ${numOfCorrect} / ${numOfAnswered}`
inputField.focus();
})
})
function checkResult(){
numOfAnswered +=1;
const inputValue = inputField.value;
if(parseInt(inputValue) === testNumber){
numOfCorrect +=1;
feedback.innerText ="Correct";
feedback.classList.add('correct');
feedback.classList.remove('wrong');
}else if(isNaN(inputValue)){
feedback.innerText =`Only Numbers Allowed!`;
feedback.classList.remove('correct');
feedback.classList.add('wrong');
}else{
feedback.innerText =`Incorrect The Answer Is ${testNumber}`;
feedback.classList.remove('correct');
feedback.classList.add('wrong');
}
}
form.addEventListener('submit',function(e){
e.preventDefault();
checkResult();
total.innerText = `Total: ${numOfCorrect} / ${numOfAnswered}`
toggleVisibility([submitBtn,nextBtn]);
nextBtn.focus();
})
We also need to declare variables. That will hold values for the number of questions answered and the number of correct answers. Which we both can initialize with zero. In the difficulty buttons event listener, we can remove the hide class from the end button. After the game is started and we can show the total by using total .innerText. we are using es6 string literals. Every time the check result function gets called. we want to add 1 to numOfAnswered. if the answer is correct. we also want to increase numOfCorrect then anytime the form gets submitted. we want to update the inner text of the total.
Last we only need to add the end game functionality.
Step 10: Ending Game
end.addEventListener('click',function(e){
minMax = undefined;
testNumber = undefined;
numOfAnswered = 0;
numOfCorrect = 0;
total.innerText = '';
feedback.innerText = '';
inputField.value = '';
end.classList.add('hide');
nextBtn.classList.add('hide');
submitBtn.classList.remove('hide');
toggleVisibility([level, game]);
})
We are going to add one more javascript click event listener which is going to reset everything.
Full source code: Number Memorising Game In JavaScript