Files
regnum/README.md
T
Kevin L'Hereec 11cba0467b feat: écran de fin de partie + tests unitaires client et E2E Playwright
- Fix: UIScene n'était jamais lancée (active: false, jamais scene.launch)
  donc l'event 'game-over' du serveur n'était jamais affiché — la partie
  semblait ne pas avoir de fin. Remplacé par un panneau Vue dans GameView
  (vainqueur, classement trié, bouton Quitter via vue-router). UIScene.js
  supprimée (code mort).
- Extraction de client/src/utils/hudUtils.js (constantes ATTRS/couleurs et
  gaugePercent) depuis GameView.vue pour les rendre testables isolément.
- Tests unitaires client (Vitest) : store Pinia (game.js) et hudUtils
  (24 tests, client/test/unit/).
- Tests d'intégration E2E (Playwright, e2e/) avec de vrais clients
  Socket.io et rendu Phaser réel dans Chromium :
  * game-flow.spec.js : lobby → démarrage → main de 4 cartes → résolution
  * item-shop.spec.js : boutique, bouton désactivé si jauge insuffisante,
    achat retire l'objet pour tous + effet appliqué + affiché sur la table
  * game-over.spec.js : partie complète (12 tours) → panneau de fin
  webServer démarre automatiquement client+serveur ; ajout d'une route
  GET /health côté Express pour permettre à Playwright de détecter un
  serveur déjà démarré.
- README : documentation des 3 niveaux de tests (unitaires serveur,
  unitaires client, intégration E2E) et de la nouvelle arborescence.
2026-08-21 15:27:44 +02:00

136 lines
5.0 KiB
Markdown

# Regnum
Jeu de cartes en ligne multijoueur (2-4 joueurs). Collecte des points en jouant des cartes de royaume simultanément pendant X tours.
## Stack
- **Frontend** : Vue 3 + Phaser 3 + Pinia
- **Backend** : Node.js + Express + Socket.io
- **Temps réel** : WebSockets
## Structure
```
regnum/
├── client/ # Vue 3 + Phaser 3
│ ├── src/
│ │ ├── views/ # HomeView, LobbyView, GameView
│ │ ├── game/ # Scènes Phaser (Boot, Game) + objets + items
│ │ ├── stores/ # Pinia store
│ │ ├── services/# Socket.io client
│ │ └── utils/ # Fonctions pures partagées (HUD, etc.)
│ └── test/unit/ # Tests unitaires Vitest (store, utils)
├── server/ # Node.js
│ ├── src/
│ │ ├── game/ # Room, RoomManager, cards, items
│ │ └── index.js # Serveur Express + Socket.io
│ └── test/game/ # Tests unitaires node:test (moteur de jeu)
└── e2e/ # Tests d'intégration Playwright (client+serveur réels)
└── tests/
```
## Lancement
### Serveur
```bash
cd server
npm install
npm run dev
```
### Client
```bash
cd client
npm install
npm run dev
```
Ouvrir `http://localhost:5173`
## Tests
Le projet a 3 niveaux de tests, à exécuter indépendamment :
### 1. Tests unitaires — serveur (moteur de jeu)
Logique pure de `Room.js` / `cards.js` / `items.js` (règles, gains, achats, effets permanents), avec le test runner natif de Node.js :
```bash
cd server
npm test # exécution unique
npm run test:watch # mode watch
```
### 2. Tests unitaires — client (store, utilitaires)
Store Pinia et fonctions pures du HUD (`hudUtils.js`), avec Vitest :
```bash
cd client
npm run test:unit # exécution unique
npm run test:unit:watch # mode watch
```
### 3. Tests d'intégration E2E (client + serveur réels)
Parcours complets (créer/rejoindre une salle, jouer des tours, acheter un objet, fin de partie) pilotés dans un vrai navigateur Chromium via Playwright, avec de vrais clients Socket.io. `webServer` dans `e2e/playwright.config.js` démarre automatiquement le serveur et le client si besoin.
```bash
cd e2e
npm install # première fois seulement
npx playwright install chromium # première fois seulement, si besoin
npm test # exécution unique
npm run test:ui # mode interactif (debug)
```
## Règles
### Principe général
- 2 à 4 joueurs par partie, chacun avec son propre deck des mêmes 12 personnages (seule la couleur d'équipe change).
- Chaque joueur commence avec une main de 4 cartes ; le reste du deck (8 cartes) est pioché une carte par tour.
- La partie dure **12 tours**. Elle se termine avant si tous les joueurs n'ont plus ni carte en main ni carte à piocher.
- Chaque tour, tous les joueurs choisissent **simultanément** une carte (cachée), puis les cartes sont révélées et résolues en même temps.
### Les 4 jauges
Chaque personnage possède 4 attributs (valeurs de 1 à 6), qui correspondent à 4 jauges cumulées par le joueur pendant toute la partie :
| Jauge | Icône |
|---|---|
| Nourriture | 🟡 |
| Guerre | 🔴 |
| Santé | 🟢 |
| Diplomatie | 🔵 |
### Résolution d'un tour
Pour chaque attribut, un joueur compare la valeur de sa carte jouée à celle de son **voisin de gauche** (ordre des joueurs dans la partie, en boucle) :
```
gain = max(0, ma_valeur - valeur_du_voisin_de_gauche)
```
Le gain (jamais négatif) est ajouté à la jauge correspondante du joueur. Le score total d'un joueur est la somme de ses 4 jauges.
### Les 12 personnages
Reine, Prince, Boucher, Médecin, Apothicaire, Fou du Roi, Assassin, Paysan, Bourreau, Chevalier, Marchand, Évêque — chacun avec un profil d'attributs différent (ex : le Paysan est fort en Nourriture mais faible en Diplomatie, l'Assassin est très fort en Guerre mais faible partout ailleurs).
### Objets achetables
Pendant la phase de sélection, un joueur peut dépenser des points d'une jauge pour acheter un objet, qui procure un **effet permanent** pour le reste de la partie tant qu'il le possède. Chaque objet coûte 3 points et n'existe qu'en **un seul exemplaire** pour toute la partie (premier arrivé, premier servi) :
| Objet | Jauge liée | Effet |
|---|---|---|
| Trébuchet | 🔴 Guerre | Double le gain de Guerre à chaque tour |
| Charrue | 🟡 Nourriture | Double le gain de Nourriture à chaque tour |
| Trousse du Médecin | 🟢 Santé | Garantit +2 en Santé à chaque tour, quel que soit le résultat |
| Sceau Royal | 🔵 Diplomatie | Copie le meilleur gain de Diplomatie parmi tous les autres joueurs |
En cas de conflit (plusieurs joueurs achètent le même objet le même tour), c'est le joueur le plus proche du **"premier joueur"** du tour (rôle qui tourne entre les joueurs à chaque tour) qui l'obtient ; les autres conservent leurs points.
### Fin de partie
Le joueur avec le score total (somme des 4 jauges) le plus élevé après 12 tours remporte la partie.