Tic-tac-toe
Two-player tic-tac-toe, with the winning line highlighted and the score kept. The right exercise to learn to describe a game by its state.
- Represent a board with an array of 9 cells
- Test the 8 winning lines
- Lock the board when the game is over
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.
Loading comments…