Second Milestone Project for the Web Development course offered by Code Institute. A simple memory game coded with JavaScript.
This is a simple pattern game in which a pattern flashes across 4 bottons on the screen, which the player must correctly replicate. The length of the pattern and the speed at which the pattern flashes increases as time goes on. If the player does not input the correct sequence, the game ends and they must start over.
- Simple design.
- Visually appealing.
- Interactive controls.
- Intuitive gameplay.
- As a user, I want a functioning game interface.
- As a user, I want an intuitive game interface.
- As a user, I want a game interface that's easy to look at.
- As a user, I want a game whose rules are easy to understand.
- As a user, I want a clear indication of when I have made a mistake.
- As a user, I want a way to track my longest run.
Pattern is built as a simple one-page website consisting of 4 game buttons of different colours and a start button, as well as a high score display and longest pattern display.
The site shifts to accommodate several screen sizes while keeping the same basic layout.
When the player starts the game, the start button is removed, and a pattern flashes on the screen.
Once a pattern is finished, the player must press the buttons in the order displayed. If the player does not do so, the game ends, and a popup on the screen informs the player of this.
On smaller screens, the buttons shift to a more vertical layout.
(I do not possess a screen small enough to get a mobile snapshot of the game over screen, unfortunately.)
#FF0000
is used for the red button.#FFFF00
is used for the yellow button.#1B1BF7
is used for the blue button.#008000
is used for the green button.#808085
is used for the game start button.
I have used MS Paint to sketch out a basic wireframe for the site:
- A way to change the effective difficulty (speed of flashes and time between flashes)
- A way to adjust the minimum and maximum pattern length
- Possible colour changes for the buttons
The site has been tested extensively to ensure the best user experience across multiple screen sizes.
The developer used W3C CSS Validation Service and W3C Markup Validation Service to check the validity of the HTML and CSS, and JSHint to check the validity of the JavaScript. Jest was also used to test core functionalities in and spot errors in the JavaScript code, along with manual testing; script.test.js
contains the tests written for this purpose, and Jest is installed so that these tests can still be run.
In order to make sure the site renders acceptably across several screen sizes, I made liberal use of the DevTools offered by Google Chrome, as well as testing load times, mobile and desktop, with the Lighthouse Chrome extension.
When writing my JavaScript, I used a mix of manual and automated testing; I wrote sections of code and wrote tests for their functionality. This helped me in troubleshooting parts of the code that didn't work as expected. I also manually tested the site to catch errors that I would have missed with pure automated testing. For instance, I discovered the second problem in the Bugfixes section by manually testing the site (this can be attributed to a poor test being written in the first place; this has since been corrected).
As a user of the site, I want:
- an intuitive game interface.
- Ensured that buttons respond to being clicked.
- Ensured that buttons can only be pressed when the pattern isn't being displayed.
- a game interface that's easy to look at.
- Subjective, but I believe the simple multicoloured buttons set against a white background is easy to look at and keeps player attention on the game itself.
- a game whose rules are easy to understand.
- The game simply requires that the player click the buttons in the order of the pattern they are shown.
- a clear indication of when I have made a mistake.
- Tested that game stops when player makes a mistake.
- Tested that the player is alerted when a mistake has been made and the game is reset properly.
- a way to track my longest run.
- Tested that high score (longest run) and max pattern length are displayed upon game-over.
- Tested that worse subsequent runs do not override the high score displays.
- Tested that high score displays persist between refreshes.
- Problem: There was a mass of unneeded whitespace at the bottom of the page.
- Solution: Initially I had just used divs with relative positioning stacked atop each other, shifting their positions with the
left
andtop
css attributes. To fix the whitespace issue, I wrapped each 'row' of buttons in acontainer
div (thestart
button has its ownstart-container
) and usedfloat: inline-start
to position them within the rows.
- Solution: Initially I had just used divs with relative positioning stacked atop each other, shifting their positions with the
- Problem: Found an issue where the new pattern was added to (instead of replacing) the old pattern, and player's new input was being added to the old input.
- Solution: in the
nextTurn()
function that handles each new turn, I had not reset both the player's inputplayerInput
and the current patterncurrentPat
properly. I addedcurrentPat = [];
to reset the current pattern.f - Problem: New pattern still being added to old pattern; new player input still being added to old player input.
- Solution:
playerInput
andcurrentPat
are keys in thegameStuff
object, which I wasn't actually keeping in mind. Changed code to resetgameStuff.playerInput
andgameStuff.currentPat
.
- Solution:
- Solution: in the
- Problem: The pattern could sometimes be hard to follow visually.
- Solution: I had added a
:hover
CSS rule to have the buttons light up when the mouse is over them, but this could get in the way of the actual pattern being displayed. I removed that particular rule, and increased the contrast between buttons lighting up and not (by reducing their opacity further) for good measure.
- Solution: I had added a
- Problem: The high score and maximum pattern length were not being updated.
- Solution: These are supposed to update once the player has made an error and has to start over. The code that updated these displays was erroneously placed after the
gameReset
call, putting relevant stats at 0. ShiftinggameReset
to the bottom fixed this issue.
- Solution: These are supposed to update once the player has made an error and has to start over. The code that updated these displays was erroneously placed after the
- Problem: The high score and maximum pattern length did not persist between browser refreshes.
- Solution: I made use of
localStorage
, addinghighScore
andmaxLength
data items that could be referenced and loaded onto the page. - Problem: The code I use returns a
TypeError: Cannot set properties of null (setting 'innerHTML)
when run through Jest. All tests fail; the test suite fails to run entirely.- Solution: I created a new
score-script.js
file which handles the initial loading of the high score and max length as stored inlocalStorage
. The rest of the code still works when manually tested, and all automated tests now pass again.
- Solution: I created a new
- Solution: I made use of
Deploy to GitHub Pages or a similar website hosting and rendering service. The html files can also be opened from local storage (this requires downloading all files in a dedicated folder; this can be done with the git pull command).
To deploy this site to GitHub Pages from its GitHub repository, the following steps were taken.
- Log in to GitHub.
- From the list of repositories on the screen, select pattern-MP2. (The above link leads straight to the repository in question.)
- Select Settings from the menu items near the top of the page.
- From the left sidebar, select Pages.
- Under Build and Deployment select Deploy from a branch as the Source and main as the branch.
- Page is refreshed and site is being deployed.
- Scroll down to GitHub Pages section again to retrieve the link for the deployed site.
At the moment of submitting the milestone project, the development branch and main branch are identical.
To clone this project from GitHub:
- Follow this link to its GitHub repository.
- Under the Code dropdown menu in the Code section, you can copy the HTTPS link or download a ZIP.
- A copied link can be used to make a pull request using Git Bash.
- Change the current working directory to one where you want the clone to be made.
- Run
git init
to initialise a local repository. - Run
git remote add origin
and paste the copied link right after. Running this command sets the GitHub repository as the 'origin'. - Run
git branch -M main
if the local repository doesn't have a main branch. - Run
git pull origin main
to make the pull request.
To clone this project into GitPod, you will need:
- A GitHub account.
- A Chrome browser or compatible browser.
Then follow these steps:
- Install the GitPod browser extension for Chrome.
- Restart the browser after installation.
- Log into GitPod with your GitHub account.
- Navigate into the Project GitHub repository.
- Click the green GitPod button in the top right corner of the repository. This will trigger a new GitPod workspace to be created from the code in GitHub where you can work normally.
To install Jest, follow these instructions. The test file and settings are available within the repository; no further setup should be required to get the tests working.
To run the automated tests, use npm test
or npm t
.
Code not written by me and not covered below is attributed to proper sources in comments within the code. All other code is written by me.