Files
livrets/docs/superpowers/specs/2026-08-31-generation-ponderee-questions-design.md

2.7 KiB
Raw Permalink Blame History

Design : Génération pondérée des questions (moins de questions faciles)

Date : 2026-08-31 Statut : Validé par le produit (approche 1 choisie)

1. Objectif

Le tirage uniforme des facteurs produit ~16 % de questions triviales (facteur 1 : 1 × 2, 3 × ? = 3) et beaucoup de petits produits trop faciles. On remplace le tirage uniforme par une pondération progressive : les grands facteurs reviennent plus souvent, les petits restent rares mais possibles.

2. Décision

Décision Choix
Mécanisme Poids sur chaque facteur, tirés indépendamment
Poids Linéaire : P(k) ∝ k, sur 1..maxTable
Formes Direct / MissingFactor inchangées (~50/50)
Anti-répétition Pas de doublon consécutif (inchangé)

Rejeté : poids sur le produit (nécessite une factorisation, biaise les tables) ; rejet par score de difficulté (boucle de rejet, terminaison fragile pour maxTable ≤ 2, coupe net les petits facteurs au lieu de les rendre rares).

3. Comportement

  • QuestionGenerator.next() tire a et b dans 1..maxTable avec poids ∝ facteur. Exemple maxTable = 10 : P(1) ≈ 1,8 %, P(2) ≈ 3,6 %, P(5) ≈ 9 %, P(10) ≈ 18 %.
  • Termination garantie : tout facteur a un poids > 0, pas de boucle de rejet sur la difficulté. Pour maxTable = 1, la seule question possible (1 × 1) reste générée.
  • La boucle « pas deux fois la même question de suite » est conservée (le tirage est relancé en cas d'égalité).
  • GameConfig, Question, les écrans et le reste du moteur ne changent pas : le joueur limite toujours la difficulté via maxTable.

4. Implémentation

QuestionGenerator.kt uniquement : construction d'une table de poids cumulés 1..maxTable (somme = maxTable·(maxTable+1)/2), tirage via random.nextDouble(totalWeight) puis recherche du facteur. Aucune autre dépendance.

5. Tests (commonTest, QuestionGeneratorTest)

Mise à jour/ajouts :

  1. Bornes : facteurs dans 1..maxTable (inchangé).
  2. Formes Direct et MissingFactor produites (inchangé).
  3. Pas de doublon consécutif (inchangé).
  4. Nouveau — biais progressif : avec une graine fixe et 5 000 tirages (maxTable = 10), la fréquence des questions contenant un facteur 1 est < 1/5 de celle contenant un facteur 10 (attendu ≈ 3,6 % vs ≈ 33,1 %).
  5. Nouveau — les petits facteurs restent possibles : avec une graine fixe et 5 000 tirages (maxTable = 10), au moins une question contient un facteur 1 (attendu ≈ 3,6 %, soit ~180 occurrences).
  6. Nouveau — maxTable = 1 : 200 appels à next() retournent tous une question à facteurs 1 × 1 (aucune boucle infinie).

6. Hors périmètre

  • Courbe de difficulté progressive au fil de la partie
  • Sélection fine de tables, modes alternatifs (cf. spec v1)