Romancing The Cards - Introduction
Clone and Deployment Information
The purpose of this, JavaScript powered, game is to illustrate how a simple game can entertain and help with learning/memorizing words in a different language. It also has the hidden benefit to help improve memory retention by rewarding users that remember where a specific word was located on the board. To help this game be applicable to a wide audience it has six selectable languages which the user can choose any combination of. These user selected languages will pull random word pairs from their language banks to keep the user interested for multiple playthroughs. Other user selectable options are provided to adjust the difficulty of the game for maximum user enjoyment. These options are: the delay between selecting cards, time to complete each round, and the number of cards to pair.
- I want to learn basic words of a new language.
- I want to be entertained by a game on my browser or cell phone during my free time.
- I want to work on my memory retention ability.
- Showcase "Vanilla" JavaScript ability:
- Have a game that is "Vanilla" JavaScript powered and takes multiple user inputs.
- Have user inputs that can change the way JavaScript builds the game (Ex. number of cards, multiple languages, appearance of cards, etc...).
- All cards in game are dynamically added and removed with the start and end of each game round.
- Game is capable of multiple play throughs without a page refreash.
- The game timer is a continuously running JavaScript function.
- The card pair positions are random every time.
- The words chosen for each game are randomly pulled from the word bank of the user's selected language.
- As a user, I'd like an enjoyable way to spend my free time.
- As a user, I'd like a game that helps with memory retention skills.
- As a user, I'd like to learn some basic words of a different language.
- As a user, I want a game that challenges me.
- The game has different settings, such as: selectable difficulty, time on clock, multiple languages, and total number of card pairs to give a user an enjoyable way to spend time with plenty of replay value.
- The game has an adjustable difficulty that can be used to provide an experience that will challenge the user's memory retention skills.
- The game currently has six different languages to pick from and they are pairable in any way the user chooses.
- The game timer, difficulty, and total number of cards can be combined to give the user a over all difficulty setting of novice to literally unwinnable.
- This program is responsive across all devices
- The game title stands out due to the use of a large font with a dark text shadow.
- The text descriptions for user input are placed over a dark background with a bright text color to help them stand out and draw the eye. These are also placed in select/option listboxes for a good UX on tablet and mobile users.
- Multiple user inputs are given for returning and new users alike.
- Multiple user inputs (timer length, number of cards, and difficulty) allow users to choose how easy or difficult they want to make the game.
- A selection of six different languages is given to the user. These languages are pairable in any combination.
- An adjustable difficulty (matching delay) is provided to users. This force users to use their memory over hunting and pecking.
- A dark background image was used to help the cards stand out.
- The background resembles a desk or table because this is a typical place to play cards or study.
- The gameplay is kept intuitive and simple so users can focus on recognizing foreign words or remembering where words were placed.
- The game header contains a timer and points calculator in an easy to read format. This encourages users to do better each time.
- The cards are dynamically added/removed and menus disappear/appear with JavaScript when the game starts and ends. This maximizes availiable screen real estate which is extremely important for tablet and mobile users.
- The game allows multiple playthroughs without having to refresh the browser.
- A click limiter was installed to keep users from spam clicking to win or break the game.
- The game pulls random word pairings from its language bank for each round. This keeps the game feeling fresh and interesting to returning users.
- The "index card" of the game cards resemble that of flash cards that school students would use.
- The font family chosen for the cards mimics a hand-written font and was paired with a bright text color. This combination gives a fun homemade flash card appearance.
- The "playing card" of the game cards resemble playful deck cards. They give a more fun feeling rather than studious.
- A CSS effect is applied to the game cards to give them a flipping animation. This gives the game a simple but memorable wow factor.
- Code kept simple, clean, and elegant for quicker load times.
- "Vanilla" JavaScript used over jQuery because of its better performance.
- Load time checked by Pingdom.
- All images have been compresssed by tinyPNG.
- Balsamiq was used for the planning process.
- Wireframes were made for all predetermined size variations of the webpage.
- Each wireframe that contains cards was given a pointing arrow and a description because of the complexity of the card design.
- Click here to view all wireframes associated to this project.
- A fully functioning demo can be found on GitHub, here.
- GitHub's IDE GitPod was used for the construction process.
- GitHub houses the master branch.
- Increase the number of usable words in each language word bank.
- Add an API that would read out the "pairing langauge" word of a matched card pair.
- Add a greater selection of card backgrounds to give users a different visual experience according to their preference.
- Add a game board background selector for a different visual experience for returning users.
- Change the games select/option listboxes to ul/li JavaScript powered Listboxes. This would allow for greater customization and full support of ARIA.
- HTML - Is the basic construction (foundation) of this webpage.
- CSS - Used to make the basic construction of this webpage more visually appealing.
- JavaScript - Allow users to interact with webpage without having to reload page or load multiple pages.
- Windows 10 (Chrome 87, Edge 87, Firefox 84)
- Chrome
- Developed in Chrome.
- Initially tested in every bootstrap breakpoint during development.
- Tested in landscape, which is desktop responsiveness level.
- Tested in portrait, which is tablet responsiveness level.
- Edge
- Tested in landscape, which is desktop responsiveness level.
- Tested in portrait, which is tablet responsiveness level.
- Firefox
- Tested in landscape, which is desktop responsiveness level.
- Tested in portrait, which is tablet responsiveness level.
- Chrome
- G8 ThinQ (Chrome 87)
- Chrome
- Tested in landscape, which is tablet responsiveness level.
- Tested in portrait, which is mobile responsiveness level.
- Chrome
- iPad, 5th gen 13.3(Safari 13)
- Safari
- Tested in landscape, which is tablet responsiveness level.
- Tested in portrait, which is tablet responsiveness level.
- Safari
- Every test of Developer Tests was preformed on the above listed systems at the specified screen orientation.
- Between landscape and portrait tests, the application was not refreshed. This is a critical part of the test! Part of these tests is the game is never refreshed between tests. This helps test for stability.
- After completion of all of the Developer Tests on each system, the system was tested again with random moments of spam clicking and switching between landscape/portrait.
- Menus and headers disappear and reappear appropriately.
- The game's header changes to "You Lose!" when the timer runs out.
- The game resets to the user selection screen.
- Header items are easily visible, disappear when not in use, and always display correct values.
- The game never needs to be reloaded to function properly.
- Tester will not reload browser between play throughs.
- Tester knows the correct content of game's header and when it should be visible.
- Start a game with default settings.
- Let the timer run out and watch the game header change to "You Lose!" and let the game reset.
- Select an untested amount of Time on Clock and start the game.
- Repeat steps 2 and 3 until all times have been selected. (Be careful not to miss the 1 minute setting.)
- Document any incidences of incorrect header presentation.
- Document any failure of the timer.
- Document any multiple playthrough errors (mismatching cards, incorrect card placement, etc...).
- Menus and headers disappear and reappear appropriately.
- Game tells user when they have won or lost.
- Header items are easily visible, disappear when not in use, and always display correct values.
- The game never needs to be reloaded to function properly.
- Tester will not reload browser between play throughs.
- Tester knows the correct content of game's header and when it should be visible.
- Tester is watching the point calculator as they are playing the game and making sure it is displaying correctly.
- Tester will occasionally fail a game round just to be sure the lost condition works.
- Tester has a basic understanding of foreign languages used or a cheat sheet of correct word pairings.
- Tester always checks for correct word pairings.
- Start game with default settings
- Win this round. Then, watch game header change to "You Win!". Let the game reset.
- Change Number of Pairs to an untested amount and repeat step 2.
- Repeat step 3 until you've selected and won on all these Number of Pairs options.
- Change Base Language and repeat steps 2 ,3 and 4 in that order.
- Repeat step 5 until you've selected and won on all Base Language options.
- Document any incidences of incorrect header presentation.
- Document any failure of the timer.
- Document any incidences of incorrectly accepted/unaccepted word pairings.
- Document any incorrect win/lose conditions.
- Document any multiple playthrough errors (mismatching cards, incorrect card placement, etc...).
- Document any incidences of cards left on the table when they should have disappeared.
- These expectations match the test expectations that are being run. This test has its own expectations in addition to this.
- The difficulty increases a delay between matching card pairs.
- The game never needs to be reloaded to function properly.
- These assumptions match the test assumptions that are being run. This test has its own assumptions in addition to this.
- Tester will not reload browser between play throughs.
- Tester knows this setting can make the game extremely difficult or even unwinnable.
- Tester knows the card's face div has an ID and the last number of this ID is used to pair the cards.
- Tester will increase the time on clock if needed.
- Tester may not be able to win on hard or unforgiving on a tablet or mobile device and that's acceptable. (Detailed in the testing steps.)
- Tester will intentionally fail a single game on every difficulty level tested.
- Increase difficulty of the game.
- Run the Testing Base Language and Point Calculator test in its entirety.
- Repeat step 2 on the hard difficulty. (Attempt to win these rounds but losing most of them wont negatively impact testing.)
- Repeat step 2 on the unforgiving difficulty. (Attempt to win these rounds but losing most of them wont negatively impact testing.)
- Document any incidences of the difficulty not performing properly.
- Document any incidences of incorrect header presentation.
- Document any failure of the timer.
- Document any incidences of incorrectly accepted/unaccepted word pairings.
- Document any incorrect win/lose conditions.
- Document any multiple playthrough errors (mismatching cards, incorrect card placement, etc...).
- Document any incidences of cards left on the table when they should have disappeared.
- The game always has the correct pair of words up to match.
- The game never needs to be reloaded to function properly.
- Menus and headers disappear and reappear appropriately.
- Header items are easily visible, disappear when not in use, and always display correct values.
- Tester will not reload browser between play throughs.
- Tester has a basic understanding of foreign languages used or a cheat sheet of correct word pairings.
- Tester knows the card's face div has an ID and the last number of this ID is used to pair the cards.
- Tester always checks for correct word pairings.
- Tester is watching the point calculator as they are playing the game and making sure it is displaying correctly.
- Start the game on its default setting (add more time to Time on Clock if needed).
- Win the game.
- Wait for game to restart.
- Select the next amount of Number of Pairs and repeat steps 2 and 3.
- repeat step 4 until all Number of Pairs have been used.
- Select the next language of Pairing Language, set Number of Pairs to 5 pairs, and start game.
- Repeat steps 2, 3, 4, 5, and 6 until all Pairing Languages have been cycled through.
- Select the next language of Base Language, set Number of Pairs to 5 pairs, and start the game.
- Repeat steps 2, 3, 4, 5, 6, 7, and 8 until all Base Languages have been cycled through.
- Document any incidences of incorrectly accepted/unaccepted word pairings.
- Document any incidences of cards left on the table when they should have disappeared.
- Document any multiple playthrough errors (mismatching cards, incorrect card placement, etc...).
- These expectations match the test expectations that are being run. This test has its own expectations in addition to this.
- The game plays the same regardless of card skin chosen.
- These assumptions match the test assumptions that are being run. This test has its own assumptions in addition to this.
- Tester will not reload browser between play throughs.
- Tester will run all mentioned tests in their entirety.
- Select Playing Card under Card Type
- Run Developer Test, Testing Timer.
- Run Developer Test, Testing Base Language and Point Calculator.
- Run Developer Test, Testing Difficulty.
- Run Developer Test, Testing Language Pairings.
- Any aforementioned document Results from the Developer Tests.
- Any card graphical bugs seen during tests. (Ex. misalignment, fading errors, etc...)
- Identifies three errors that are documented in Other Problems.
- Identifies one warning. This warning is a vender extension that's required for safari to render text on the cards in the game.
- Identifies one warning that does not require action.
- Helped find occurrences of missing semicolons and unidentified variables.
- Occasionally a matching pair of cards will leave a single card on the table, sometimes making the game unwinnable. This card can be either face up or face down. This bug was generated by not flashing the "clickRecord" when a user lost the game. **update(This was a two-part bug detailed in the following bug)
- A single card of a matched pair would occasionally be removed from the game. The user would be awarded a point and the pair would be considered matched. If a user clicked fast enough, this bug would get past the program's initial defensive click logic. An additional layer of defensive logic was added to check for identical card ids. This logic still compares the two identical card ids chosen during fast clicks. However, the pairing now automatically fails and the single card is flipped back over.
- Some words with masculine and feminine forms (ex. celles-ci/ceux-ci) exceeded the character limit and would drop to the line below. Which created an an unappealing visual appearance. This bug was fixed by a change to font-size units from rem to a combination of rem and vw. However, a pixel width roughly between 1200 and 1166 can still use two lines, but now they provide a good visual experience.
- The background image would not always extend the entire length of the screen on smaller devices. Code from MDN (documented below) was used to find the appropriate length to set "min-height" to. This variable was created at the global and local levels. The global variable was used to set the height of the background when the program starts and to "reset" its height after winning or losing conditions of the game were met. The local variable was created to set the background after the cards have been created to be sure the background extended appropriately. Having these two different scoped variables ensures the program switches appropriately between the different screen heights on all devices. **update(This fix was proven insufficient and made obsolete with the fix detailed below)
- During testing on a mobile device it was discovered that switching from landscape to portrait could leave the background image shorter than the screen height. This bug was later found on a desktop device when switching from landscape to portrait. With the initial fix (detailed above) being insufficient the code was refactored into a function. This function was to be called on the local level in all of the same places as it was before. An additional "resize" event listener was added. This code would not run at the proper time so an additional piece of code was used from MDN (window.onresize = foo). This new code accurately detects when a resize occurs and sets the screen to the new height.
- A screen pixel width below 320px or above 4000px will quickly lose a good UX.
- Jigsaw (Validation Service) throws an error on ".cardFaceTypeIndex", ".cardBackTypeIndex", and ".cardFaceTypeFun". Despite this error, several browser OS combinations were tested (detailed in Developer Tested Systems) and none of them had problems with this code. It's very possible that this error is similar to how World Wide Web Consortium validators throw errors when a vendor extension is used.
- The "aria-expanded" state remains while the select/option boxlist isn't expanded. This occurs beacuse of the limitations of select/option. This bug could be triggered when a user focuses on the select/option listbox by not directly clicking on the select/option listbox itself. This focus bug could also be triggered by tabbing through the content of the page or clicking on the label for the select/option listbox. Another trigger of this bug was when a user selects the same option from a select/option listbox that is currently selected. This bug wasnt able to be fixed so the "aria-expanded" state was removed entirely along with its JavaScript code. A solution to add it back in could be with a future update that changes the select/option listbox to a ul/li JavaScript powered listbox. With the appropriate JavaScript, this will make the listbox more customizable, capable of a better UX, and more friendly towards ARIA states.
- Go to the location of the repository in GitHub, https://github.com/Richardaeld/google_translate_game.
- Click the "Code" button to get the drop down menu (underlined in red).
- Copy the HTTPS address provided (underlined in red).
- Create a blank or boiler plate GitPod project and open this new GitPod project.
- Go to the Bash and type, "git clone " and paste the HTTPS address found in GitHub page.
- Press enter.
- The clone will be created within the folder, "google_translate_game" (The original name of the project).
- Unpack everything from this folder to the root of the GitPod project tree and the project will be fully functional within GitPod.
- If you wish to deploy outside of GitPod's preview, follow "GitHub Deployment" section below.
- Go to the location of the cloned or deployment repository in GitHub.(ex. here)
- Select Settings at the top of the page (circled in red).
- Go down in settings page until you find the heading "GitHub Pages" (underlined in red).
- Click "None" under the "Source" subheading (circled in red).
- Select the branch you wish to publish.
- In this example we chose to select master (circled in red).
- Click save (underlined in red).
- Reload page and you will see the layout under Github Pages will change and tell you the page is ready to be published.
- Once the page is fully published, the layout will change once more and tell you the site has been published.
- Now the page is fully viewable at the provided HTTPS address.
- Balsamiq
- Used to produce the wireframes.
- Bootstrap
- Used as framework.
- BrowserStack
- Used to check for compatibility errors.
- GitHub
- Used for version control and deployment of demo (prototype) website.
- GitPod
- Integrated development environment used.
- Google Fonts
- Imported font families from here.
- Jigsaw (Validation Service)
- Used to identify errors in CSS.
- JSHint
- Used to identify errors in JavaScript.
- Lighthouse
- Used to check for performance, accessibility, best practices, and SEO.
- Pingdom
- Used to check load time.
- Techsini
- Used for their viewable responsiveness PNG.
- TinyPNG
- Used to Minimize KB load per image.
- W3C Validator
- Used to identify errors in markup.
- This animation's code originated from three different locations. With great effort, these code pieces were melded into something unique to this project but
still deserves accurate documentation/citation. This code has numerous citations in the CSS where the three main structures of the card's CSS exist (outside, rotating portion, and faces).
A citation was also added to the HTML above the dynamically added content section. The three places where code originated from are: Arjun Khara, MDN Web Docs, and
W3Schools. All these are documented in detail below.
- Arjun Khara
- First discovered idea of rotating 3d objects using only CSS here.
- Used idea of a single box to contain all moving objects and faces of a card or 3D object.
- Used ideas from his code to help understand how and where to place items, such as: "backface-visability" and "transform-style" to create desired effect.
- MDN Web Docs
- Used idea of a container that rotates 180 degrees with the aid of "backface-visability: hidden" and "transform-style:preserve-3d".
- Used code placement (ex: where to place "backface-visability" in HTML structure) ideas to help with rotating the cards on the board. This code can be found here.
- Used to help understand how "backface-visability: hidden" and "transform-style:preserve-3d" work together to produce the desired effect. This code can be found here.
- W3Schools
- Used code and ideas to help with rotating the cards on the game board. This code can be found here.
- Arjun Khara
- This JavaScript function was discovered at W3Schools and its code was adapted to accept a variable from the loop which it is run from.
- Two lines of code from MDN are responsible for the backbone of this codes function.
- MDN Web Docs
- Used code that allows JavaScript to dynamically read the length of the screen. This code can be found here.
- MDN Web Docs
- Used code that allows JavaScript to dynamically sense when the screen has been resized. This code can be found here.
- MDN Web Docs
- Felipe Souza Alarcon
- Used idea to place words in JavaScript object(s) for the language banks.
- MDN Web Docs
- Invaluable source of information about JavaScript, HTML, and CSS.
- W3Schools
- A wonderful resource for element, attribute, and event selection for JavaScript.
- Extremely helpful for explaining base HTML, CSS, and JavaScript principles.
- World Wide Web Consortium (W3C)
- Used for understanding ARIA content and industry standard use.
- Multiple standardizations were used from here.
- The aria standardizations that were specifically drawn from are:
- Stack Overflow
- Great souce of information for finding a starting place and direction to research.
- Helped in understanding the importance of loops in JavaScript.
- TestLodge
- Used to help formulate test syntax structure.
- Bootstrap
- Framework used to help speed up development and provide a better overall UX.
- GitHub
- Used their documentation as this project's deployment basis.
- Deployment Information - Used the structure of GitHub's deployment information as the basis for this project's readme deployment section.
- Clone Information - Used the structure of GitHub's "Cloning a repository" information as the basis for this project's readme deployment section
- Richard Eldridge (Project developer)
- Designed the game's icon (favicon).
- Took the picture for the game's background.
- Felipe Souza Alarcon for his honest guidance, foresight, and helping lead me into directions I did not know I could go with this project.
- Emily Eldridge for help with revising the grammar and flow of this README document.