Skip to content
← 1001 Widgets
N° 010 · ●●○

Booster

A ten-card booster to open, with rarities drawn at random like in a real pack. The right exercise to understand weighted draws.

HTMLJS
What you'll learn
  • Draw at random with weights
  • Guarantee a rare in every pack
  • Flip a card in 3D
Why this language

Pourquoi ouvrir un booster ? Tirer des cartes, c'est appliquer des probabilités : chaque rareté a sa chance de sortir. On apprend le tirage pondéré, puis on met en scène la révélation, carte par carte.

Ce widget ne vend rien : les cartes sont inventées, et le hasard est là pour le plaisir.

Pourquoi en JavaScript simple ? Un tableau de raretés, une fonction de tirage, une boucle d'affichage.

How it works
  1. LES RARETÉS

    Chaque rareté a un poids : plus il est grand, plus elle sort souvent.

    const RARETES = [
      { nom: 'Commune', poids: 70 },
      { nom: 'Peu commune', poids: 22 },
      { nom: 'Rare', poids: 7 },
      { nom: 'Secrète', poids: 1 }
    ];
  2. LE TIRAGE PONDÉRÉ

    On tire un nombre entre 0 et la somme des poids, puis on avance jusqu'à la rareté qui le contient.

    function tirerRarete() {
      const total = RARETES.reduce((s, r) => s + r.poids, 0);
      let n = Math.random() * total;
      for (const r of RARETES) {
        if (n < r.poids) return r;
        n -= r.poids;
      }
    }
  3. LE BOOSTER

    Dix cartes, avec au moins une rare garantie en dernière position, comme dans les vrais boosters.

    function ouvrir() {
      const cartes = Array.from({ length: 9 }, tirerRarete);
      const derniere = tirerRarete();
      cartes.push(derniere.poids <= 7 ? derniere : RARETES[2]);
      return cartes;
    }
  4. LE HTML

    <button id="ouvrir">Ouvrir un booster</button>
    <ol id="cartes"></ol>
  5. RÉVÉLER UNE À UNE

    Chaque carte arrive face cachée. Un clic la retourne.

    document.getElementById('ouvrir').addEventListener('click', () => {
      const ol = document.getElementById('cartes');
      ol.innerHTML = '';
      ouvrir().forEach(r => {
        const li = document.createElement('li');
        li.innerHTML = '<button>Retourner</button>';
        li.dataset.rarete = r.nom;
        ol.append(li);
      });
    });
    document.getElementById('cartes').addEventListener('click', e => {
      const li = e.target.closest('li');
      if (!li || li.classList.contains('vue')) return;
      li.classList.add('vue');
      li.textContent = li.dataset.rarete;
    });
Pitfalls

PIÈGE 1 : Des pourcentages qui ne font pas 100

Pitfall

Mauvais : écrire les chances en pourcentages et en oublier un. Le total fait 98 %, et le tirage tombe parfois dans le vide.

Fix

Correct : des poids relatifs, et une somme calculée. On ajoute une rareté sans tout recalculer.

PIÈGE 2 : Relancer jusqu'à la rare

Pitfall

Mauvais : refaire le tirage tant qu'aucune rare n'est sortie. Le booster ne respecte plus les chances annoncées.

Fix

Correct : garantir une seule position, la dernière, et laisser les autres au hasard.

PIÈGE 3 : Le résultat lisible dans le code

Pitfall

Mauvais : croire qu'une carte cachée en CSS est secrète. Un coup d'œil aux outils du navigateur suffit pour tout voir.

Fix

Correct : pour un jeu, c'est sans importance. Pour un vrai tirage, le résultat ne doit arriver du serveur qu'au moment du clic.

PERSONNALISER
  • Vos raretés : changez les noms et les poids, ajoutez une « Alternative » à 0,5.
  • Un style par rareté : une bordure lime pour les rares, un fond plein pour les secrètes, un reflet avec la Carte à reflet.
  • Un bouton « Tout retourner » qui révèle les dix cartes avec un petit décalage.
OPTIMISATION
  • Affichez les chances sous le bouton : c'est honnête, et c'est attendu dès qu'un tirage touche à de l'argent.
  • Simulez 100 000 boosters dans la console pour vérifier que les fréquences collent aux poids.
VERS REACT

Le booster est un tableau dans un useState, et chaque carte garde son état « vue ».

La révélation change une seule carte : un map sur le tableau avec l'index cliqué.

Variants
Comments
0/1000

Loading comments…

Audience measurement

With your consent, this site measures its traffic with Google Analytics and the Meta pixel, via Google Tag Manager. Nothing is loaded until you choose, and you can change your mind at any time with the "Cookies" link at the bottom of the page.