https://github.com/traveltimn/simon-game
Simon Memory Game in JavaScript
https://github.com/traveltimn/simon-game
css jasmine jasmine-jquery javascript memory-game simon-game
Last synced: about 1 month ago
JSON representation
Simon Memory Game in JavaScript
- Host: GitHub
- URL: https://github.com/traveltimn/simon-game
- Owner: TravelTimN
- Created: 2019-11-10T21:07:25.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2025-06-20T10:25:35.000Z (12 months ago)
- Last Synced: 2025-11-29T14:46:46.752Z (6 months ago)
- Topics: css, jasmine, jasmine-jquery, javascript, memory-game, simon-game
- Language: JavaScript
- Homepage: https://traveltimn.github.io/simon-game
- Size: 513 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
10DEC2020 - Update branch from `master` to `main`.
---

# [Simon Memory Game](https://traveltimn.github.io/simon-game)
## Table of Contents
1. [**UX**](#ux)
- [**User Stories**](#user-stories)
- [**Design**](#design)
- [**Framework**](#framework)
- [**Color Scheme**](#color-scheme)
- [**Icons**](#icons)
- [**Typography**](#typography)
- [**Wireframes**](#wireframes)
2. [**Features**](#features)
- [**Existing Features**](#existing-features)
- [**Features Left to Implement**](#features-left-to-implement)
3. [**Technologies Used**](#technologies-used)
- [**Front-End Technologies**](#front-end-technologies)
- [**Miscellaneous Technologies**](#miscellaneous-technologies)
4. [**Testing**](#testing)
- [**Validators**](#validators)
- [**Compatibility**](#compatibility)
- [**Known Issues**](#known-issues)
- [**Automated Testing**](#automated-testing)
5. [**Deployment**](#deployment)
- [**Local Deployment**](#local-deployment)
- [**Remote Deployment**](#remote-deployment)
6. [**Credits**](#credits)
- [**Content**](#content)
- [**Media**](#media)
- [**Code**](#code)
- [**Acknowledgements**](#acknowledgements)
---
## UX
This project is an example project for the **Interactive Front-End** module of the [Code Institute](https://codeinstitute.net/) Full Stack Software Development course. The objective for this milestone project is to "*build an interactive front-end site that should respond to users' actions, such as a data dashboard, a memory game, or use of an external API such as Google Maps*".
### User Stories
"**_As a user, I would like to_** _______________"
- :white_check_mark: read the instructions on how to play the game.
- :white_check_mark: test my logical memory skills by matching a progressively difficult level of a series of colorful buttons.
- :white_check_mark: play the game using either a mouse, the keyboard, or tapping on a touch screen.
- :white_check_mark: play the game with both visual and audio effects from the buttons and sounds.
- :white_check_mark: be notified when I've made a mistake from the sound of an error klaxon.
- :white_check_mark: continue playing if I've made a mistake, but repeat the previous level a bit slower.
- :white_check_mark: play the game in either standard mode, or strict mode (which ends the game immediately if I get one wrong answer).
- :white_check_mark: restart the game at any point during my turn.
- :white_check_mark: win the game after successfully matching 31 consecutive randomized colors.
- :white_check_mark: hear the winning razz once I've completed all 31 levels successfully.
### Design
A standard layout that is fully responsive on mobile devices and larger screens has been utilized. The constant use of responsive CSS sizing elements such as `vw`, `vh`, `%`, and `calc()` helps to ensure the site responds to the appropriate user device.
#### Framework
There was no need to utilize any particular frameworks or libraries for this project, such as the following:
- Bootstrap / Materialize
- CSS Grid / Flexbox
- jQuery *(exception: jasmine-jquery only for tests)*
#### Color Scheme
-  green button
-  red button
-  yellow button
-  blue button
All of these colors are set at `:root` level within my [style.css](assets/css/style.css) file. This also allows me to reuse my colors as a `class` across the site, instead of having to assign the colors each and every time.
#### Icons
- [Font Awesome 5.12.1](https://fontawesome.com/)
- 2 *Font Awesome* icons were used, purely for social media icons on the Info Modal.
- [GitHub brand](https://fontawesome.com/icons/github-square?style=brands)
- [Linkedin brand](https://fontawesome.com/icons/linkedin?style=brands)
#### Typography
- 5 [Google Fonts](https://fonts.google.com/) were used across the site:
- [Original Surfer](https://fonts.google.com/specimen/Original+Surfer) : main body text.
- [Press Start 2P](https://fonts.google.com/specimen/Press+Start+2P) : button letters (RGBY).
- [Quantico](https://fonts.google.com/specimen/Quantico) : counter and announcements.
- [Sarpanch](https://fonts.google.com/specimen/Sarpanch) : game logo text.
- [Luckiest Guy](https://fonts.google.com/specimen/Luckiest+Guy00) : all modal text.
### Wireframes
I built mockup concept wireframes using [Balsamiq Wireframes](https://balsamiq.com/).
- Code Institute have provided all students with free access until the end of 2020.
My wireframes for this project can be found in the [**wireframes**](assets/wireframes/) folder.
- [Wireframe](assets/wireframes/simon-wireframe.bmpr): original `Balsamiq.bmpr` file.
- [Wireframe](assets/wireframes/simon-wireframe.png): visual representation for GitHub.

##### back to [top](#table-of-contents)
---
## Features
In accordance to the project brief, I have successfully implemented all of the *required* features, as well as a few additional features to improve user experience!
### Existing Features
**JavaScript Memory Game**:
- Build a memory game using JavaScript to execute instructions to perform arithmetic, logic, controlling, and input/output operations to a user.
**Progressive Difficulty**:
- Players can progress through multiple levels if successfully matching Simon's moves each round. Levels get harder the further you manage to play.
- *Levels 1-5 are EASY*
- *Levels 6-13 are MEDIUM*
- *Levels 14-31 are HARD*
**Strict Mode**:
- To truly test their memory matching skills, players can choose to play in Strict Mode, but one wrong move will immediately end the game!
**Restart Game**:
- At any point during their turn, player's can opt to restart the game for a new randomized series of colors.
**Player Timeout**:
- If the player doesn't make a move within 5 seconds, a klaxon will sound to signify an error. This 5 second timer resets after each move. The level will repeat again at a slower playback speed only if *Strict Mode* is not active.
**Automatic Console Shut-off**:
- If the player does not interact with the game console for 45 consecutive seconds, the game console will automatically shut itself off. This 45 second timer does not apply when it is Simon's turn; this is to take in consideration when player's are at high levels and have made an error, Simon repeats the round at a slower speed, which nearly exhausts the entire 45 seconds of inactivity.
**Winning Razz**:
- If the player is successful enough to beat Simon's 31 levels, the traditional winning *'Razz'* will trigger. This is a combination of rapid pulses of the final color, mixed with a round of applause in order from Red, Yellow, Blue, Green on repeat, followed by the losing klaxon to signify the player has won the game!
- Winning Modal will display length of time it took to beat Simon.
### Features Left to Implement
**Leaderboard**:
- Ideally, I'd like to implement a leaderboard of session users that have completed all 31 levels successfully, which can be displayed to anybody else.
##### back to [top](#table-of-contents)
---
## Technologies Used
### Front-End Technologies
- 
- [HTML5](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5) - Used as the base for markup text.
- 
- [CSS3](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS3) - Used as the base for cascading styles.
- 
- [JavaScript ES6](https://developer.mozilla.org/en-US/docs/Web/JavaScript) - Used as the base for game interaction.
- 
- [Jasmine](https://jasmine.github.io/) - Used for Test-Driven Development (TDD).
- 
- [jasmine-jquery](https://www.npmjs.com/package/jasmine-jquery) - Used to simplify some of the automated Jasmine tests.
### Miscellaneous Technologies
- 
- [VS Code](https://code.visualstudio.com/) - Used as my primary IDE for developing projects.
- 
- [GitHub](https://github.com/) - Used as remote storage of my projects online.
- 
- [Balsamiq](https://balsamiq.com/) - Used to bring my wireframes to life.
- 
- [Audacity](http://audacity.sourceforge.net/) - Used to record my own audio files.
##### back to [top](#table-of-contents)
---
## Testing
A thorough mix of automated and manual testing have gone into building the project. In addition to tests, I have validated all files against online validation sites, and checked compatibilities across various modern browsers and devices.
### Validators
**HTML**
- [W3C HTML Validator](https://validator.w3.org)
- Document checking completed. No errors or warnings to show.
**CSS**
- [W3C CSS Validator](https://jigsaw.w3.org/css-validator/)
- The W3C Jigsaw validator does not yet recognize root variables, and therefore shows 110 **Parse** and **Value** **Errors**. These are used to set/use global CSS variables.
- `:root`
- `var(--foo)`
- I also received 2 **Warnings**:
- Imported style sheets are not checked in direct input and file upload modes.
- `-webkit-tap-highlight-color` is an unknown vendor extension.
**JavaScript**
- [JShint](https://jshint.com/)
- File: [script.js](assets/js/script.js)
- METRICS:
- There are **57** functions in this file.
- Function with the largest signature take **1** arguments, while the median is **0**.
- Largest function has **21** statements in it, while the median is **3**.
- The most complex function has a cyclomatic complexity value of **12** while the median is **1**.
- UNDEFINED VARIABLE:
- `KeyboardEvent`
- File: [simon-tests.js](testing/automated/specs/simon-tests.js)
- METRICS:
- There are **91** functions in this file.
- Function with the largest signature take **0** arguments, while the median is **0**.
- Largest function has **16** statements in it, while the median is **3**.
- The most complex function has a cyclomatic complexity value of **2** while the median is **1**.
- UNDEFINED VARIABLES:
- `describe`
- `beforeEach`
- `it`
- `expect`
- `spyOn`
- `jasmine`
- `method`
- `$`
- [Esprima](https://esprima.org/demo/validate.html)
- Code is syntactically valid.
### Compatibility
Full details about compatibility tests can be found in my [testing folder](testing/), which includes results from Chrome's DevTools Audit report as well.
To ensure a broad range of users can successfully use the site, I tested it across the 6 major browsers in both desktop and mobile configuration.
- **Chrome** (*v.80.0.3987.116*)
- **Firefox** (*v.74.0b5* - *Developer Edition*)
- **Edge** (*v.80.0.361.56*)
- **Safari** (*v.12.1.2*)
- **Opera** (*v.62.0.3331.99*)
- **Internet Explorer** (*v.11.885.17134.0*)
I have also created a testing matrix ([raw Excel file here](testing/manual/testing-simon-matrix.xlsx)).
**Testing Matrix**

**Chrome's DevTools Audit Report**
| Performance | Accessibility | Best Practices | SEO | PWA |
| :---: | :---: | :---: | :---: | :---: |
| 98% | 100% | 100% | 100% | - |

### Known Issues

While passing my code through the online validators, I encountered one questionable issue. I opened an *Issue* on GitHub so I could revisit this problem and resolve it later.
- [KeyboardEvent.keyCode depreciated](https://github.com/TravelTimN/simon-game/issues/1)
- This was fixed and pushed with [commit a6eab2a](https://github.com/TravelTimN/simon-game/commit/a6eab2aae265c7248225227dfaaf15050112a751).
### Automated Testing
I used [Jasmine 3.5.0](https://jasmine.github.io/) in conjunction with [jasmine-jquery 2.1.1](https://www.npmjs.com/package/jasmine-jquery) to build all automated tests (test-driven development). These tests can be found in the [testing/automated](testing/automated/) folder.
There are **59 tests** in my specs, all successfully passing, with **0 failures**.

CLICK HERE to see tests on the Power Button
- should exist
- should be *'off'* by default
- should not trigger Simon's turn *(if power=off)*
- should trigger the **strictButton** to be *'false'* *(during power off)*
- should call the `disablePlayer()` function *(during power off)*
- should call the `disableStart()` function after 500ms *(during power off)*
- should call the `disableStrict()` function after 500ms *(during power off)*
- should call the `disableColors()` function after 500ms *(during power off)*
- should clear the **gameSpeed interval** after 500ms *(during power off)*
- should clear the **playerTimer timeout** after 500ms *(during power off)*
- should trigger the **game console** to turn *'on'* if clicked
- should call the `enableStart()` function *(during power on)*
- should call the `enableStrict()` function *(during power on)*
- should call the `inactiveGame()` function *(during power on)*
- should turn the **Level Counter** *'on'* *(during power on)*
CLICK HERE to see tests on the Start Button
- should exist
- should be *'disabled'* *(if power=off)*
- should have a **default** cursor *(if power=off)*
- should be *'enabled'* *(if power=on)*
- should have a **pointer** cursor *(if power=on)*
- should call the `enablePlay()` function if clicked
CLICK HERE to see tests on the Strict Button
- should exist
- should be *'disabled'* *(if power=off)*
- should have a **default** cursor *(if power=off)*
- should be *'enabled'* *(if power=on)*
- should have a **pointer** cursor *(if power=on)*
- should end the game if *'enabled'* and player is **incorrect**
CLICK HERE to see tests on the Level Counter
- should exist
- should show **ON** when the game is powered *'on'*
- should show **01** when the game *'starts'*
- should show **NO** if a player is *'incorrect'*
- should show **13** when a player reaches the *'fastest'* mode
- should show **WIN** if a player completes all *'31 levels'*
CLICK HERE to see tests on the Green Button
- should exist
- should *not* be *'enabled'* if the `disablePlayer()` function is called
- should call the `pushButton()` function if clicked during the `enablePlayer()` function
- should have class **active** if the `enableColors()` function is called
- should *not* have class **active** if the `disableColors()` function is called
- should play the **greenAudio** audio file if player **isCorrect**
CLICK HERE to see tests on the Red Button
- should exist
- should *not* be *'enabled'* if the `disablePlayer()` function is called
- should call the `pushButton()` function if clicked during the `enablePlayer()` function
- should have class **active** if the `enableColors()` function is called
- should *not* have class **active** if the `disableColors()` function is called
- should play the **redAudio** audio file if player **isCorrect**
CLICK HERE to see tests on the Yellow Button
- should exist
- should *not* be *'enabled'* if the `disablePlayer()` function is called
- should call the `pushButton()` function if clicked during the `enablePlayer()` function
- should have class **active** if the `enableColors()` function is called
- should *not* have class **active** if the `disableColors()` function is called
- should play the **yellowAudio** audio file if player **isCorrect**
CLICK HERE to see tests on the Blue Button
- should exist
- should *not* be *'enabled'* if the `disablePlayer()` function is called
- should call the `pushButton()` function if clicked during the `enablePlayer()` function
- should have class **active** if the `enableColors()` function is called
- should *not* have class **active** if the `disableColors()` function is called
- should play the **blueAudio** audio file if player **isCorrect**
CLICK HERE to see tests on the 'Lose' audio file
- should exist
- should play the **lose** audio file if player **is not correct**
##### back to [top](#table-of-contents)
---
## Deployment
My [simon-game repository](https://github.com/TravelTimN/simon-game) was developed locally using **VS Code**, and all commits were pushed to **GitHub** using **Git**.
### Local Deployment
In order to run this project locally on your own system, you will need the following installed (as a bare minimum):
- [GIT](https://www.atlassian.com/git/tutorials/install-git) for cloning and version control.
- [Microsoft Visual Studio Code](https://code.visualstudio.com) (or any suitable IDE) to develop your project.
Next, to proceed with local deployment, you can...
EITHER:
- **Download** this GitHub repository
- by clicking the green "*Clone or download*" button above,
- select *Download Zip*,
- this will download the project as a zip-file (*remember to unzip it first*).
OR:
- **Clone** this GitHub repository
- by entering the following command into the Git CLI terminal:
- `git clone https://github.com/TravelTimN/simon-game.git`
- [Troubleshooting for **git cloning**](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/cloning-a-repository)
Congratulations! Your project should be completely setup and ready for local development! :tada:
### Remote Deployment
This site was deployed using [GitHub Pages](https://pages.github.com/) using the **main branch**.
Deployed Site:
- [https://traveltimn.github.io/simon-game](https://traveltimn.github.io/simon-game)
Once you have the project setup locally, you can proceed to deploy it remotely with the following steps:
1. Navigate to your GitHub repository:
- `https://github.com/USERNAME/REPO`
2. Click on the **Settings** tab at the top:
- `https://github.com/USERNAME/REPO/settings`
3. Scroll down on that page to the **GitHub Pages** section.
4. The first drop-down field should be **Source** with *None* preselected.
5. Select **main branch** from the list.
6. The page should refresh.
7. Scroll back down to the **GitHub Pages** section.
8. You should now have a deployed link:
- `https://USERNAME.github.io/REPO`
**IMPORTANT NOTE**:
- Please allow a few minutes to pass before opening your newly deployed link! Clicking this link too quickly may result in a failure to build the site, causing an Error 404 page instead.
Congratulations! Your project should be deployed successfully on GitHub Pages! :tada:
##### back to [top](#table-of-contents)
---
## Credits
### Content
- [WaitingForFriday](https://www.waitingforfriday.com/?p=586) - Reverse Engineering a Simon Game. I wanted to keep the game as real to the original as possible.
- *"[How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/)"* by Chris Beams *(as recommended by Code Institute assessors)*.
### Media
- [Szynalski](https://www.szynalski.com/tone-generator/) - Online Tone Generator to create all sounds.
- [marcgg](https://marcgg.com/blog/2016/11/01/javascript-audio) - Generate sounds programmatically with JavaScript.
- [TinyPNG](https://tinypng.com/) - Online Image Compressor.
- [Shields.io](https://shields.io) - Markdown badges for README.
All audio files were created by me. These files are not to be used without proper attribution, acknowledgment, and credit to this repository. You must specify that audio files were obtained from my repository, for example:
> "*Audio files were obtained with approval from [https://github.com/TravelTimN/simon-game](https://github.com/TravelTimN/simon-game)*"
You are, however, welcome to generate your own audio files using the same methods and tools that I used, but the use of my files should be attributed if you use them for your own project(s).
### Code
- [Jasmine QRG](https://github.com/TravelTimN/ci-ifd-lead/blob/main/week5-jasmine/jasmine.md) - My Quick Reference Guide as CI IFD_lead.
- [Jasmine Cheatsheet](https://devhints.io/jasmine) - A helpful Jasmine cheatsheet.
- [Jasmine 'setFixtures'](https://lostechies.com/derickbailey/2011/10/14/quick-hack-to-work-around-jasmine-jquery-fixture-limitations/) - How to use `setFixtures` in Jasmine.
- [Jasmine 'spyOn'](https://stackoverflow.com/a/9511646) - How to use `spyOn` in Jasmine.
- [Jasmine 'createSpy' + 'createSpyObj'](https://scriptverse.academy/tutorials/jasmine-createspy-createspyobj.html) - How to use `createSpy` and `createSpyObj` in Jasmine.
- [Jasmine 'timeouts' + 'intervals'](https://stackoverflow.com/a/50883535) - How to use `set`||`clear` + `Timeout`||`Interval` in Jasmine.
- [Jasmine 'timeouts' + 'intervals'](https://makandracards.com/makandra/32477-testing-settimeout-and-setinterval-with-jasmine) - How to use `set`||`clear` + `Timeout`||`Interval` in Jasmine.
- [Jasmine 'addEventListener'](https://stackoverflow.com/a/32576013) - How to use `addEventListener` in Jasmine.
- [Jasmine 'removeEventListener'](https://stackoverflow.com/questions/43489131/jasmine-test-removeeventlistener) - How to use `removeEventListener` in Jasmine.
- [Jasmine audio files](https://stackoverflow.com/questions/53900671/testing-htmlmediaelement-play-in-angular-7-jasmine-karma-chrome) - How to test 'audio files' in Jasmine.
### Acknowledgements
- [Chris Quinn](https://github.com/10xOXR) - My accountability partner on all projects.
##### back to [top](#table-of-contents)