diff --git a/src/model/car/BasicCar.java b/src/model/car/BasicCar.java index b88f407..c39bed7 100644 --- a/src/model/car/BasicCar.java +++ b/src/model/car/BasicCar.java @@ -9,42 +9,63 @@ import model.map.Circuit; import model.map.Map; /** - * {@link BasicCar} représente une voiture qui avance sur un circuit en boucles. - * Chaque appel à {@link #run()} avance la voiture d'une certaine position et - * fait perdre de l'essence. - * Quand la position atteint la fin de la boucle, un nouveau tour est compté. + * {@link BasicCar} représente une voiture basique. + * *
- * La voiture consomme du carburant à chaque déplacement, et son score - * est calculé en fonction du nombre de tours complétés et de sa progression sur - * le tour actuel. + * Chaque appel à {@link #apply()} : + *
+ * La voiture peut subir des dégâts ({@link State#DAMAGED}), inverser son sens, + * ou arrêter la consommation de carburant. *
*/ public class BasicCar implements Car { + /** Générateur de nombres aléatoires pour simuler la progression */ protected static final Random RANDOM = new Random(); + /** Couleur de la voiture pour l'affichage */ private final Color COLOR; + /** Nom de la voiture */ private final String NAME; + /** Position actuelle dans la boucle (entre 0 et loop) */ private int pos = 0; + /** Nombre de tours complétés */ private int round = 0; - /** Nombre de cases dans une boucle (doit être > 0) */ + + /** Référence à la carte/circuit sur lequel la voiture évolue */ private Map map; + /** Carburant restant */ private int fuel = 60; + /** Multiplicateur pour avancer ou reculer */ private int movement = 1; + /** Indique si la voiture consomme du carburant */ private boolean isConsuming = true; + /** État courant de la voiture */ + private State state = State.NORMAL; + + /** Compteur interne pour la durée d'un état endommagé */ + private int damageRound = 0; + /** * Construit une nouvelle voiture. * * @param name nom de la voiture * @param color couleur de la voiture - * @param map + * @param map carte du circuit */ public BasicCar(String name, Color color, Map map) { this.NAME = name; @@ -52,137 +73,111 @@ public class BasicCar implements Car { this.map = map; } + /** + * Construit une nouvelle voiture. + * + * @param name nom de la voiture + * @param color couleur de la voiture + * + */ public BasicCar(String name, Color color) { this.NAME = name; this.COLOR = color; } /** - * Référence à l'état du jeu, pour récupérer les paramètres comme la - * consommation - */ - private State state = State.NORMAL; - - private int damageRound = 0; - - public void setDamage() { - damageRound = 5; - state = State.DAMAGED; - } - - private void decreaseDamage() { - if (state.isDamaged()) { - if (--damageRound <= 0) { - state = state.onDamageEnd(); + * Diminue le compteur de dégâts à chaque tick et rétablit l'état + * si nécessaire. + */ + private void decreaseDamage() { + if (state.isDamaged()) { + if (--damageRound <= 0) { + state = state.onDamageEnd(); } } } - + public BasicCar setState(State state) { this.state = state; return this; } - - /** - * Clique sur "Accelerer" : change d'état et retourne un message (si - * nécessaire). - */ + @Override public String accelerate() { - // Si endommagée => l'énoncé dit qu'on ne peut pas bouger if (state.isDamaged()) { return "Voiture endommagée : impossible d'accélérer"; } State next = state.accelerate(); - - // Énoncé : en BOOST, si on accélère encore => message "déjà max" if (state == State.BOOST && next == State.BOOST) { return "Déjà à la vitesse maximale"; } state = next; return ""; } - - /** - * Clique sur "Rallentir" : change d'état et retourne un message (si - * nécessaire). - */ + @Override public String decelerate() { if (state.isDamaged()) { return "Voiture endommagée : impossible de ralentir"; } - State next = state.decelerate(); - - // Énoncé : en STOPPED, si on ralentit encore => message "déjà arrêtée" if (state == State.STOPPED && next == State.STOPPED) { return "Déjà arrêtée"; } - state = next; return ""; } - + /** - * Fait avancer la voiture d'un certain nombre de positions. + * Déplace la voiture sur le circuit selon l'état courant. *- * Si la position atteint la fin de la boucle, le compteur de tours est - * incrémenté et - * la position revient à zéro. + * Gère également les accidents et l'incrémentation des tours. *
- * - * @param move nombre de positions à avancer - * @return cette même instance (pour chaînage fluide) - */ - private void move() { - int jump = RANDOM.nextInt(state.MIN, state.MAX); - - for (int i = 0; i < jump; i++) { - pos = state.move(pos, movement); - - Point point = map.getPath(pos); - Circuit element = map.getElement(point.x, point.y); - - if (hasAccident(element, jump)) { - setDamage(); - return; + */ + private void move() { + int jump = RANDOM.nextInt(state.MIN, state.MAX); + for (int i = 0; i < jump; i++) { + pos = state.move(pos, movement); + + Point point = map.getPath(pos); + Circuit element = map.getElement(point.x, point.y); + + if (hasAccident(element, jump)) { + setDamage(); + return; } + round = pos / map.getPathSize(); } } - + + /** Vérifie si la voiture subit un accident selon l'élément du circuit */ private boolean hasAccident(Circuit element, int jump) { return element.isYRoad() && element.getValue() <= jump; } - - /** - * Consomme du carburant en fonction de l'état du jeu. - * - * @return cette même instance pour chaînage - */ + + /** Consomme du carburant en fonction de l'état courant */ public void consumeFuel() { fuel = state.fuelConsumption(fuel); if (fuel < 0) fuel = 0; // sécurité } - + + /** Indique si la voiture a terminé le nombre de tours requis */ public boolean finished() { return 3 < round; } - + /** - * Exécute une "étape" de la voiture : avance d'une position aléatoire et - * consomme du carburant. + * Exécute un tick de la voiture. *- * La progression est déterminée par un intervalle aléatoire fourni par l'état - * du jeu. + * Si endommagée, diminue les dégâts. Sinon, avance et consomme du carburant. *
- */ - @Override - public boolean apply() { - if (state.isDamaged()) { - decreaseDamage(); + */ + @Override + public boolean apply() { + if (state.isDamaged()) { + decreaseDamage(); } else if (fuel > 0) { move(); if (isConsuming) @@ -190,80 +185,79 @@ public class BasicCar implements Car { } return !finished(); } - + @Override public void consumption(boolean active) { isConsuming = active; } - + @Override public Car remove() { return this; } - + @Override public void reverse(boolean active) { - movement = (active) ? -1 : 1; + movement = active ? -1 : 1; } /** - * @return la position actuelle dans la boucle + * Définit la voiture comme endommagée. + *+ * Passe l'état de la voiture à {@link State#DAMAGED} et initialise le + * compteur de tours endommagés. + *
*/ + public void setDamage() { + damageRound = 5; + state = State.DAMAGED; + } + + @Override public int getPosition() { return Math.floorMod(pos, map.getPathSize()); } - - /** - * @return le score de la voiture, calculé comme : - * (nombre de tours + progression du tour) × 100 - */ + + @Override public int getScore() { return (int) ((round + (float) pos / map.getPathSize()) * 100); } - - /** - * @return le nombre de tours complétés - */ + + @Override public int getRound() { return round; } - - /** - * @return le carburant restant - */ + + @Override public int getFuel() { return fuel; } - - /** Retourne l'état courant de la voiture. */ + + @Override public State getState() { return state; } - - /** - * @return la couleur de la voiture - */ + + @Override public Color getColor() { return COLOR; } - - /** - * @return nom de la voiture - */ + + @Override public String getName() { return NAME; } - + @Override public void setup(Game game) { this.map = game.getMap(); } - + @Override public String toString() { return "nom: " + NAME + " score: " + getScore(); } - + @Override public void end() { System.out.println(this); diff --git a/src/model/car/BoostCar.java b/src/model/car/BoostCar.java index d5e2d55..b0b7806 100644 --- a/src/model/car/BoostCar.java +++ b/src/model/car/BoostCar.java @@ -1,8 +1,11 @@ package model.car; /** - * Décorateur Sound : - * affiche un message sonore quand la voiture accélère. + * BoostCar est un décorateur qui améliore la voiture en augmentant + * sa vitesse de manière temporaire ou permanente selon la logique du jeu. + *+ * Il hérite de {@link CarDecorator} et délègue toutes les méthodes à + * la voiture encapsulée sauf celles qu'on veut modifier. */ public class BoostCar extends CarDecorator { public BoostCar(Car car) { diff --git a/src/model/car/Car.java b/src/model/car/Car.java index 1fac0a5..d138181 100644 --- a/src/model/car/Car.java +++ b/src/model/car/Car.java @@ -3,29 +3,92 @@ package model.car; import java.awt.Color; import model.Game.Observer; - +/** + * {@link Car} est l'interface représentant une voiture dans le jeu. + * + *
+ * Elle hérite de {@link Observer} afin de pouvoir être notifiée à chaque tick + * du jeu et participer à la logique principale. + *
+ * + *+ * L'interface définit les actions possibles sur une voiture, ainsi que les + * méthodes pour obtenir son état, sa position, son score, et sa couleur. + *
+ */ public interface Car extends Observer { + + /** + * Accélère la voiture. + *+ * Modifie l'état de la voiture selon les règles du {@link State}. + *
+ * @return message explicatif. + */ public String accelerate(); + /** + * Ralentit la voiture. + *+ * Modifie l'état de la voiture selon les règles du {@link State}. + *
+ * @return message explicatif. + */ public String decelerate(); + /** + * Active ou désactive le mouvement inversé de la voiture. + * + * @param active true pour inverser la direction, false pour avancer normalement + */ public void reverse(boolean active); + /** + * Active ou désactive la consommation de carburant. + * + * @param active true pour consommer du carburant, false pour ne pas consommer + */ public void consumption(boolean active); + /** + * Supprime ou désactive la voiture (selon l'implémentation). + * + * @return l'instance de la voiture (pour chaînage ou gestion interne) + */ public Car remove(); + /** + * @return le nom de la voiture + */ public String getName(); + /** + * @return la position actuelle sur le circuit + */ public int getPosition(); + /** + * @return le score actuel de la voiture + */ public int getScore(); + /** + * @return le nombre de tours complétés + */ public int getRound(); + /** + * @return le carburant restant + */ public int getFuel(); + /** + * @return l'état courant de la voiture ({@link State}) + */ public State getState(); + /** + * @return la couleur de la voiture pour l'affichage + */ public Color getColor(); } diff --git a/src/model/car/CarDecorator.java b/src/model/car/CarDecorator.java index f72cd26..496a33c 100644 --- a/src/model/car/CarDecorator.java +++ b/src/model/car/CarDecorator.java @@ -1,12 +1,28 @@ package model.car; import java.awt.Color; - import model.Game; +/** + * {@link CarDecorator} est une classe abstraite servant de base pour + * les décorateurs de voitures. + * + *+ * Elle encapsule une voiture existante ({@link Car}) et délègue + * toutes les méthodes à cette voiture. Les sous-classes peuvent + * redéfinir certaines méthodes pour ajouter un comportement + * spécifique (ex. Boost, Drunk, Hybrid). + *
+ */ public abstract class CarDecorator implements Car { + /** La voiture encapsulée à décorer */ protected final Car car; + /** + * Construit un décorateur autour d'une voiture existante. + * + * @param car la voiture à décorer + */ public CarDecorator(Car car) { this.car = car; } diff --git a/src/model/car/DrunkCar.java b/src/model/car/DrunkCar.java index 0d984cc..8bb5082 100644 --- a/src/model/car/DrunkCar.java +++ b/src/model/car/DrunkCar.java @@ -1,15 +1,16 @@ package model.car; /** - * DrunkCar = décorateur "pilote ivre". - * + * DrunkCar est un décorateur simulant un pilote ivre. + ** Idée : - * - Quand l'utilisateur demande "Accelerer", le pilote peut se tromper - * et faire "Rallentir" à la place (au hasard). - * - Pareil quand on demande "Rallentir". - * - * => On modifie seulement les actions utilisateur (accelerate/decelerate), - * sans modifier la classe Car. + *
* Idée : - * - La voiture avance à chaque tour - * - Mais elle consomme du carburant seulement 1 fois sur 2 - * => donc elle économise du carburant. + * - La voiture avance à chaque tick comme une voiture normale + * - Elle consomme du carburant seulement une fois sur deux, économisant ainsi + * l'énergie. */ public class HybridCar extends CarDecorator { private int energy = 100; // énergie batterie (0..100) @@ -16,7 +16,6 @@ public class HybridCar extends CarDecorator { car.consumption(false); } - /** pour afficher l'énergie dans le Dashboard */ public int getEnergy() { return energy; } diff --git a/src/model/car/Selection.java b/src/model/car/Selection.java index 93a134f..367e3c2 100644 --- a/src/model/car/Selection.java +++ b/src/model/car/Selection.java @@ -7,69 +7,96 @@ import java.util.function.Function; import model.Game; +/** + * Selection gère la création et la configuration des voitures + * avant le lancement du jeu. + *
+ * Elle permet : + * - d'ajouter et retirer des voitures, + * - d'ajouter des décorateurs (Hybrid, Drunk, Boost), + * - de lancer le jeu avec les voitures sélectionnées. + *
+ */ public class Selection { + /** Builder du jeu associé */ private final Game.Builder gameBuilder; + + /** Liste interne des voitures sélectionnées */ private final List+ * Chaque état définit : + *
+ * Ce design correspond au State Pattern : + * le comportement du véhicule varie selon son état courant + * sans avoir recours à des conditions {@code if / switch}. + */ public enum State { + /** - * L'état NORMAL du Vehicule avance selon un chiffre au alentour de 1 à 6 cases - * par tour. Il consomme 2 unités de carburant à chaque tour. Si l'on - * accelere, il passe à l'état BOOST. Si on Rallenti, il passe à l'état LOW. + * État NORMAL du véhicule. + * + *
+ * Le véhicule avance d'un nombre aléatoire de cases + * compris entre 1 et 6 inclus. + * Il consomme 2 unités de carburant par tour. + * + *
+ * Transitions possibles : + *
+ * Le véhicule avance rapidement (entre 5 et 10 cases). + * Il consomme 5 unités de carburant par tour. + * + *
+ * Transitions possibles : + *
+ * Le véhicule avance lentement (entre 1 et 3 cases). + * Il consomme 1 unité de carburant par tour. + * + *
+ * Transitions possibles : + *
+ * Le véhicule est à l'arrêt : + *
+ * Transitions possibles : + *
+ * Le véhicule est endommagé : + *
+ * Cet état est temporaire : après réparation,
+ * le véhicule repasse à l'état {@link #LOW}.
*/
DAMAGED(0, 0, 0) {
+ @Override
public State accelerate() {
return this;
}
+ @Override
public State decelerate() {
return this;
}
@@ -108,39 +191,92 @@ public enum State {
return LOW;
}
};
- // @formatter:on
+ /* ==========================================================
+ * Attributs communs à tous les états
+ * ========================================================== */
+
+ /** Consommation de carburant par tour */
public final int FUELCOST;
+
+ /** Borne maximale (exclusive) de déplacement */
public final int MAX;
+
+ /** Borne minimale (inclusive) de déplacement */
public final int MIN;
+ /**
+ * Constructeur interne des états.
+ *
+ * @param fuelCost consommation par tour
+ * @param min déplacement minimal
+ * @param max déplacement maximal (inclus)
+ */
private State(int fuelCost, int min, int max) {
this.FUELCOST = fuelCost;
- this.MAX = max + 1;
this.MIN = min;
+ this.MAX = max + 1;
}
+ /**
+ * Retourne l'intervalle de déplacement possible pour cet état.
+ *
+ * @return liste contenant [MIN, MAX[
+ */
public List