Créez une classe Personnage avec:
Encapsulation: exposez uniquement des getters en lecture (id, nom, pv, position, statut), pas de setters publics. Ajoutez un toString() lisible (nom, pv, statut, position).
Créez une exception ActionInterdite extends RuntimeException.
Toutes les violations de règles jettent ActionInterdite avec un message clair.
Validez les paramètres (ex: dégâts/soins négatifs ⇒ clamp à 0 ou exception, à vous de choisir, justifiez).
Ajoutez un champ inventaire dans Personnage; getter en lecture.
Méthode envoyerMessage(Personnage cible, String contenu): Interdit si émetteur HORS_LIGNE ou cible HORS_LIGNE ⇒ ActionInterdite Logguez “Msg → <cible>: <contenu>” côté émetteur
Méthode simulatePing(): renvoie une latence simulée en millisecondes (int entre 5 et 200), interdit si HORS_LIGNE.
Option A (sans dépendance):
String toJson() — construisez une chaîne JSON simple via StringBuilder (attention aux guillemets, échappez au minimum nom/objets). static Personnage fromJson(String json) — parse minimaliste: pour simplifier, vous pouvez ignorer l’inventaire ou parser seulement nom/pv/position/statut. Option B (avec Jackson): Ajoutez Jackson Databind. Sérialisez/désérialisez Personnage (id lu/écrit en String). Marquez les champs non voulus si besoin.
id (UUID) défini au constructeur et jamais modifié. Implémentez equals() et hashCode() basés uniquement sur id. Démonstration: mettez des Personnage dans un HashSet et vérifiez l’unicité.
static Personnage nouveau(String nom) — valeurs par défaut: pv=100, x=0, y=0. static Personnage fromSnapshot(…) — construit depuis des valeurs primaires (ex: pour tests).
Programme Main lisant des lignes sur stdin: Commandes: connect, disconnect, fight, stopfight, move dx dy, hit n, heal n, ping, status, additem nom poids, rmitem nom, json, quit Gérez proprement les exceptions (afficher “Erreur: …”).
Affichez l’état après chaque commande utile.
Exercice 10 — Tests unitaires (JUnit 5)
Tests suggérés: PV bornés (ne pas dépasser 100; pas négatif). Transitions d’états interdites (ex: disconnect depuis EN_COMBAT). Inventaire plein ⇒ exception. KO ⇒ déplacement impossible; premier soin réanime à min 1 PV (si vous adoptez cette règle). equals/hashCode par id.