Jeu de mémoire
Seize cartes retournées, huit paires à retrouver, et un compteur de coups. Le bon exercice pour gérer un état de jeu qui dépend de deux clics.
- Mélanger un tableau avec Fisher-Yates
- Comparer deux choix puis attendre
- Bloquer les clics pendant une animation
Pourquoi un jeu de mémoire ? Parce qu'il cache une vraie difficulté : le jeu ne réagit pas à un clic, mais à une paire de clics. Il faut garder le premier choix en mémoire, comparer au second, puis laisser le temps de voir avant de retourner les cartes.
Pendant ce temps, un troisième clic ne doit rien casser. C'est le premier contact avec un état « occupé ».
Pourquoi en JavaScript simple ? Un tableau mélangé, un tableau de deux cartes choisies, un booléen. Le retournement est un simple rotateY en CSS.
MÉLANGER
Fisher-Yates : chaque ordre a exactement la même chance. sort(() => Math.random() - 0.5) ne l'est pas.
function melanger(t) { for (let i = t.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [t[i], t[j]] = [t[j], t[i]]; } return t; }L'ÉTAT
const SYMBOLES = ['山', '川', '火', '水', '木', '月', '日', '花']; let cartes = melanger([...SYMBOLES, ...SYMBOLES]); let choix = []; let bloque = false; let coups = 0;
LE HTML
Une carte est un bouton : clavier et lecteur d'écran fonctionnent d'office.
jeu.innerHTML = cartes.map((s, i) => `<button class="carte" data-i="${i}"><b>?</b><span>${s}</span></button>`).join('');RETOURNER
jeu.addEventListener('click', e => { const c = e.target.closest('.carte'); if (!c || bloque || c.classList.contains('vue')) return; c.classList.add('vue'); choix.push(c); if (choix.length < 2) return; coups++; const [a, b] = choix; choix = []; if (cartes[a.dataset.i] === cartes[b.dataset.i]) return; // paire trouvée : elles restent visiblesATTENDRE AVANT DE CACHER
bloque = true; setTimeout(() => { a.classList.remove('vue'); b.classList.remove('vue'); bloque = false; }, 800); });
PIÈGE 1 : Le mélange biaisé
Mauvais : cartes.sort(() => Math.random() - 0.5). Certaines positions reviennent bien plus souvent que d'autres.
Correct : l'algorithme de Fisher-Yates, qui échange chaque carte avec une position au hasard avant elle.
PIÈGE 2 : Le troisième clic
Mauvais : laisser cliquer pendant les 800 ms d'attente. On retourne trois cartes et le jeu se perd.
Correct : un booléen bloque, vérifié au début du gestionnaire de clic.
PIÈGE 3 : Cliquer deux fois la même carte
Mauvais : accepter un second clic sur une carte déjà retournée. Elle forme une paire avec elle-même.
Correct : ignorer les cartes qui ont déjà la classe vue ou trouvée.
- Une grille 6 × 6 pour une version difficile : il suffit de 18 symboles.
- Un chronomètre qui démarre au premier clic et s'arrête à la dernière paire.
- Des images à la place des kanji, pour un jeu à thème.
- Préchargez les images avant d'afficher la grille, sinon la première carte retournée apparaît vide.
- Annoncez les paires trouvées avec une zone aria-live pour les lecteurs d'écran.
Les cartes deviennent un tableau d'objets { symbole, vue, trouvee } dans un useState.
Le setTimeout vit dans un useEffect qui réagit aux deux cartes choisies, et se nettoie au démontage.
Le mélange se fait une seule fois, dans la fonction d'initialisation de useState.
Chargement des commentaires…