๐จ My First Browser Game ยท Episode 2 of 6 ยท See All Episodes
๐ง Episode 2 ยท Beginner ยท DOM & CSS Skills
Match Maker! Memory Card Game
No canvas this time, build a card-flipping memory game out of real HTML elements, CSS 3D flips and DOM events. This is the same skill set as building web apps, disguised as a game.
๐ก Hint: Freeze input, schedule the flip-back for later with the browser timer function, then unfreeze inside it.
๐ง
Knowledge Check
+15 XP
What breaks WITHOUT the locked flag?
ACSS stops working
BPlayers can flip a 3rd card during the 0.8 s wait, tangling the two-card state machine
CsetTimeout fails
5
โฑ๏ธ
Moves, Timer & Winning
Count pairs tried, time the game, detect victory
Locked
๐ฏ
Goal for this step
Add a move counter, a live timer and the win banner.
1Moves = pair attempts: increment on every SECOND flip.
2Timer: setInterval every second updates a seconds counter on screen; start on first flip, stop on win.
3Win check: count .matched cards === 16 โ show "You won in 14 moves and 63 seconds!"
4Show moves and time in a HUD line above the board.
memory.html
let moves = 0, seconds = 0, timerId = null;
function startTimer() {
if (timerId) return; // only once
timerId = setInterval(function() {
seconds++;
document.getElementById("time").textContent = seconds + "s";
}, 1000);
}
function checkWin() {
if (document.querySelectorAll(".matched").length === 16) {
clearInterval(timerId);
document.getElementById("msg").textContent =
"๐ You won in " + moves + " moves and " + seconds + "s!";
}
}
โ๏ธ
Fill in the Blanks
+15 XP
A repeating timer uses with 1000 ms, and is stopped with (timerId). The win condition counts elements with the class.
๐ง
Knowledge Check
+15 XP
setTimeout vs setInterval, which is which?
AThey are identical
BsetTimeout fires ONCE after a delay (flip-back); setInterval fires REPEATEDLY (the ticking clock)
CsetInterval is newer
6
๐
Difficulty & Best Scores
4ร4 vs 6ร6 boards and localStorage records
Locked
๐ฏ
Goal for this step
Add difficulty levels and persistent best scores per level.
1Difficulty buttons: Easy 4ร4 (8 pairs) and Hard 6ร6 (18 pairs, extend the emoji list!). Rebuild the board from a size variable; set the grid columns in code.
2Store bests per mode: keys "memory-best-4" and "memory-best-6", fewest moves wins.
3Show the record next to each button, beat-your-best is the retention loop.
4You just built interface, state, animation and persistence. That IS front-end development. Episode 3 returns to canvas!
memory.html
function newGame(size) { // 4 or 6
board.style.gridTemplateColumns =
"repeat(" + size + ", 90px)";
const pairs = (size * size) / 2;
values = shuffle([...EMOJI.slice(0, pairs),
...EMOJI.slice(0, pairs)]);
buildBoard(values);
moves = 0; seconds = 0;
}
// after a win:
const key = "memory-best-" + size;
const best = Number(localStorage.getItem(key) || 999);
if (moves < best) localStorage.setItem(key, moves);
โจ๏ธ
Code Challenge
+20 XP
Compute the pair count for any board size:
memory.html
const pairs = (size * ) / ;
๐ก Hint: A square board has sizeรsize cards, and every pair covers two of them.
๐ง
Knowledge Check
+15 XP
The fairest "best score" for memory is fewest moves, not fastest time, becauseโฆ
ATimers are buggy
BMoves measure MEMORY skill; time also measures mouse speed and panic
ClocalStorage prefers integers
๐๐๐ฎโจ๐
Workshop Complete!
DOM building, shuffling, CSS animation and state logic, that is literally web-app development. Episode 3: back to canvas for Breakout!