Morpion
Un morpion à deux joueurs, avec la ligne gagnante mise en valeur et le score qui se garde. Le bon exercice pour apprendre à décrire un jeu par son état.
- Représenter un plateau avec un tableau de 9 cases
- Tester les 8 lignes gagnantes
- Bloquer le plateau quand la partie est finie
Pourquoi un morpion ? Neuf cases, deux joueurs, huit façons de gagner. C'est le plus petit jeu complet qu'on puisse coder : un plateau, des tours, une condition de victoire, une fin de partie.
On représente le plateau par un tableau de neuf cases, et on teste les huit lignes gagnantes après chaque coup.
Pourquoi en JavaScript simple ? Toute la logique tient dans un tableau. C'est la base de la variante imbattable, qui ajoute une IA.
LE HTML
<div id="plateau"></div> <p id="statut" aria-live="polite"></p> <button id="rejouer">Rejouer</button>
L'ÉTAT
Neuf cases vides, le joueur qui commence, et la fin de partie.
let cases = Array(9).fill(null); let joueur = 'X'; let fini = false;
LES LIGNES GAGNANTES
Trois lignes, trois colonnes, deux diagonales.
const LIGNES = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]; function gagnant() { for (const [a, b, c] of LIGNES) { if (cases[a] && cases[a] === cases[b] && cases[a] === cases[c]) return cases[a]; } return cases.every(Boolean) ? 'nul' : null; }AFFICHER
Neuf boutons, désactivés quand la case est prise ou la partie finie.
function afficher() { document.getElementById('plateau').innerHTML = cases.map((v, i) => `<button data-i="${i}" ${v || fini ? 'disabled' : ''} aria-label="Case ${i + 1}">${v || ''}</button>` ).join(''); const g = gagnant(); document.getElementById('statut').textContent = g === 'nul' ? 'Match nul.' : g ? `${g} gagne.` : `Au tour de ${joueur}.`; }JOUER
document.getElementById('plateau').addEventListener('click', e => { const i = e.target.dataset.i; if (i === undefined || cases[i] || fini) return; cases[i] = joueur; fini = Boolean(gagnant()); joueur = joueur === 'X' ? 'O' : 'X'; afficher(); }); document.getElementById('rejouer').addEventListener('click', () => { cases = Array(9).fill(null); joueur = 'X'; fini = false; afficher(); }); afficher();
PIÈGE 1 : Tester la victoire à la main
Mauvais : une longue suite de if pour chaque ligne. Une faute de frappe, et une diagonale ne compte plus.
Correct : un tableau des huit lignes et une seule boucle.
PIÈGE 2 : Jouer après la fin
Mauvais : oublier de bloquer le plateau. On peut encore cliquer après la victoire.
Correct : une variable fini, et des boutons désactivés.
PIÈGE 3 : Des div cliquables
Mauvais : des <div> avec un onclick. Impossible de jouer au clavier.
Correct : des <button>, un aria-label par case, et le statut dans une zone aria-live.
- Surligner la ligne gagnante : renvoyez la ligne dans gagnant() et ajoutez une classe aux trois cases (c'est ce que fait la démo).
- Un score qui survit à « Rejouer » : trois compteurs, X, O et nuls.
- Vos symboles : remplacez X et O par deux kanji, ou deux emoji.
- Le joueur courant se déduit du nombre de cases remplies : une variable de moins à garder synchronisée.
- Pour une IA, l'algorithme minimax explore toutes les suites possibles : c'est la variante « Morpion imbattable ».
cases dans un useState, et le gagnant calculé pendant le rendu, jamais stocké.
Un historique des coups permet un bouton « Annuler » en une ligne.
Chargement des commentaires…