feat(round2): balance category turns across qualifiers (#47) #63

Merged
Reliodas merged 3 commits from feat/47-round2-rebalance into develop 2026-06-25 17:08:06 +00:00
Owner

Closes #47

Rend la deuxième manche équitable quand le nombre de qualifiés ne divise pas les 12 catégories.

Décision produit

Passages équilibrés + neutralisation du reste : chaque candidat joue exactement floor(12 / N) passages ; les 12 mod N catégories restantes ne sont pas jouées (neutralisées) plutôt que d'être attribuées aux mieux classés du déchiffrage. L'avantage du déchiffrage se limite à l'ordre de choix, sans passage supplémentaire.

Qualifiés Passages/candidat Jouées Neutralisées
3 4 12 0
4 3 12 0
5 2 10 2
6 2 12 0
7 1 7 5
8 1 8 4
9 1 9 3
10 1 10 2
11 1 11 1
12 1 12 0

Changements

  • round2.ts : categoryPlan(qualifiers){ turnsPerCandidate, categoriesToPlay } ; nextCategory termine la manche dès que currentPickIndex atteint categoriesToPlay.
  • Projection / types : turnsPerCandidate et categoriesToPlay exposés dans l'état de la deuxième manche (aucune logique officielle côté client).
  • Client (MJ) : l'écran de choix de catégorie affiche le nombre de passages par candidat et les catégories neutralisées.
  • Docs : Regles.md (règle + table) et Implémentation.md.

Conformité aux critères

  • décision produit documentée ✓ · serveur applique la règle, client n'affiche que l'état ✓ · le MJ voit les passages avant la phase ✓ · classements/qualifications déterministes (inchangés) ✓ · tests 3→12 qualifiés ✓ · Regles.md à jour ✓

Vérification (checkout propre, sans assets)

  • typecheck OK ; node:test 212 pass (1 skipped), Jest 13/13, Vitest 83/83
  • coverage serveur 93.6 % stmts (seuils respectés), client exit 0
  • build OK, check:assets OK, validate:questions OK (142), smoke OK, e2e Playwright 3/3
Closes #47 Rend la deuxième manche équitable quand le nombre de qualifiés ne divise pas les 12 catégories. ## Décision produit **Passages équilibrés + neutralisation du reste** : chaque candidat joue exactement `floor(12 / N)` passages ; les `12 mod N` catégories restantes ne sont pas jouées (neutralisées) plutôt que d'être attribuées aux mieux classés du déchiffrage. L'avantage du déchiffrage se limite à l'ordre de choix, sans passage supplémentaire. | Qualifiés | Passages/candidat | Jouées | Neutralisées | |---:|---:|---:|---:| | 3 | 4 | 12 | 0 | | 4 | 3 | 12 | 0 | | 5 | 2 | 10 | 2 | | 6 | 2 | 12 | 0 | | 7 | 1 | 7 | 5 | | 8 | 1 | 8 | 4 | | 9 | 1 | 9 | 3 | | 10 | 1 | 10 | 2 | | 11 | 1 | 11 | 1 | | 12 | 1 | 12 | 0 | ## Changements - **`round2.ts`** : `categoryPlan(qualifiers)` → `{ turnsPerCandidate, categoriesToPlay }` ; `nextCategory` termine la manche dès que `currentPickIndex` atteint `categoriesToPlay`. - **Projection / types** : `turnsPerCandidate` et `categoriesToPlay` exposés dans l'état de la deuxième manche (aucune logique officielle côté client). - **Client (MJ)** : l'écran de choix de catégorie affiche le nombre de passages par candidat et les catégories neutralisées. - **Docs** : `Regles.md` (règle + table) et `Implémentation.md`. ## Conformité aux critères - décision produit documentée ✓ · serveur applique la règle, client n'affiche que l'état ✓ · le MJ voit les passages avant la phase ✓ · classements/qualifications déterministes (inchangés) ✓ · tests 3→12 qualifiés ✓ · `Regles.md` à jour ✓ ## Vérification (checkout propre, sans assets) - typecheck OK ; `node:test` 212 pass (1 skipped), Jest 13/13, Vitest 83/83 - coverage serveur 93.6 % stmts (seuils respectés), client exit 0 - build OK, check:assets OK, validate:questions OK (142), smoke OK, e2e Playwright 3/3
Each qualified candidate now plays floor(12 / qualifiers) categories; when the
qualifier count does not divide the 12-category board, the remaining categories
are neutralized instead of handing extra turns to the best-ranked candidates.
The plan (turnsPerCandidate, categoriesToPlay) is computed by categoryPlan and
exposed in the second-round state. Rankings stay deterministic. Tests cover 3-12
qualifiers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Display how many categories each candidate will play, and how many are
neutralized, on the host category-select screen, from server-provided state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs(rules): document the balanced second-round rule (#47)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
442f1413d7
Replace the assumed-advantage note with the balanced rule: equal turns per
candidate and neutralized leftover categories, with a per-qualifier-count table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reliodas merged commit 29a36bb0a4 into develop 2026-06-25 17:08:06 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: jeux/le-grand-concours#63
No description provided.