diff --git a/src/Game.java b/src/Game.java index 46682b8..72ccae6 100644 --- a/src/Game.java +++ b/src/Game.java @@ -1,232 +1,289 @@ import java.awt.Color; +import java.awt.GraphicsEnvironment; import java.util.ArrayList; +/** + * La classe {@link Game} représente le moteur principal du jeu. + *
+ * Elle contient le modèle (les voitures, l'état du jeu, la carte), + * la vue (Track, Dashboard, Rankboard) et la logique de contrôle + * (pause, boucle de jeu, observateurs). + *
+ */ public class Game { - public static record CarInfo(String name, Color color) {} - - public static class Builder + /** + * {@link CarInfo} est une structure simple qui contient les informations + * nécessaires pour créer une voiture dans le jeu : son nom et sa couleur. + */ + public static class CarInfo { - /** - * Liste des voitures ajoutées au jeu. - * On utilise ArrayList pour pouvoir ajouter/supprimer des voitures dynamiquement. - */ - private ArrayList+ * Permet d'ajouter des voitures, de définir la carte, l'état initial et + * le temps entre les étapes du jeu avant de construire l'objet final. + *
+ */ + public static class Builder + { + /** Liste des voitures à créer pour le jeu */ + private ArrayList+ * Si la carte n'a pas été définie, le programme s'arrête. + *
+ */ + public Game build() + { + if (map == null) + { + System.err.println("Vous devez définir une carte avant de construire le jeu !"); + System.exit(1); + } + return new Game(map, cars, state, time); + } + } - private boolean isFinish() - { - for (Car car : cars) - { - if (car.getFuel() == 0) - return true; - } - return false; - } - - public Game addObserver(GObserver o) - { - obs.add(o); - return this; - } - - public Game remObserver(GObserver o) - { - obs.remove(o); - return this; - } - - public synchronized boolean togglePause() - { - if (isPaused) notifyAll(); - isPaused = !isPaused; - GameView.update(); - return isPaused; - } + /** Carte sur laquelle le jeu se déroule */ + private final Map map; + /** État du jeu (par exemple, positions, carburant) */ + private final State state; + /** Temps entre chaque étape du jeu en millisecondes */ + private final int time; - private synchronized void step() throws InterruptedException - { - for (int i = 0; i < cars.size(); i++) - { - // pause du jeu, while si on notifyall sans faire exprès un autre bout de code - while (isPaused) - wait(); - - cars.get(i).run(); + /** Liste des voitures du jeu */ + private final ArrayList+ * Chaque voiture obtient un Dashboard, la piste est affichée avec Track, + * et le Rankboard est créé pour afficher le classement. + *
+ * + * @param carInfos liste des informations des voitures + * @return l'instance de Game + */ + private Game init(ArrayList+ * Le jeu est fini si au moins une voiture a épuisé son carburant. + *
+ * + * @return true si le jeu est terminé + */ + private boolean isFinish() + { + for (Car car : cars) + { + if (car.getFuel() == 0) + return true; + } + return false; + } -// if (!isSuccess) -// { -// System.err.println("Une erreur s'est produite pendant le jeu."); -// System.exit(1); -// } -// } -// } + /** + * Ajoute un observateur pour recevoir les mises à jour du jeu. + * + * @param o observateur + * @return instance de Game pour chaîner + */ + public Game addObserver(GObserver o) + { + obs.add(o); + return this; + } -// public void run() -// { -// while (!isFinish()) -// { -// try -// { -// step(); -// Thread.sleep(time); -// } -// catch (InterruptedException e) -// { e.printStackTrace(); } -// } -// } -// } + /** + * Supprime un observateur. + * + * @param o observateur + * @return instance de Game pour chaîner + */ + public Game remObserver(GObserver o) + { + obs.remove(o); + return this; + } + + /** + * Bascule l'état de pause du jeu. + *+ * Si le jeu était en pause, il est relancé et les threads en attente sont notifiés. + *
+ * + * @return true si le jeu est maintenant en pause + */ + public synchronized boolean togglePause() + { + if (isPaused) notifyAll(); + isPaused = !isPaused; + GameView.update(); + return isPaused; + } + + /** + * Exécute un cycle du jeu + *+ * Chaque voiture effectue son action, puis les observateurs sont notifiés. + * La boucle attend si le jeu est en pause. + *
+ * + * @throws InterruptedException si le thread est interrompu pendant wait() + */ + private synchronized void step() throws InterruptedException + { + for (int i = 0; i < cars.size(); i++) + { + while (isPaused) + wait(); + + cars.get(i).run(); + + for (GObserver o : obs) + { + if (!o.apply()) + { + System.err.println("Une erreur s'est produite pendant le jeu."); + System.exit(1); + } + } + } + } + + /** + * Boucle principale du jeu. + *+ * Tant que le jeu n'est pas terminé, on exécute les étapes et on met à jour + * les vues toutes les 'time' millisecondes. + *
+ */ + public void run() + { + while (!isFinish()) + { + try + { + step(); + GameView.update(); + Thread.sleep(time); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/src/Main.java b/src/Main.java index 9a35226..b0985f5 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,34 +1,30 @@ import java.awt.Color; -import java.awt.GraphicsEnvironment; public class Main { public static void main(String[] args) throws InterruptedException { - if (!GraphicsEnvironment.isHeadless()) + Integer[][] map = new Integer[][] { - Integer[][] map = new Integer[][] - { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 5, 0 }, - { 0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, 0, 0, -1, 0 }, - { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 }, - { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 }, - { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 2, 0, 0, -1, 0 }, - { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 }, - { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 }, - { 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -3, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - }; - - Map m = Map.fromInts(map); - - Game game = new Game.Builder() - .addCar(new Game.CarInfo("Voiture 1", Color.BLUE)) - .addCar(new Game.CarInfo("Voiture 2", Color.PINK)) - .addCar(new Game.CarInfo("Voiture 3", Color.RED)) - .setMap(m) - .build(); - game.run(); - } + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 5, 0 }, + { 0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, 0, 0, -1, 0 }, + { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 }, + { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0 }, + { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, -1, 2, 0, 0, -1, 0 }, + { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 }, + { 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0 }, + { 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -3, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }; + + Map m = Map.fromInts(map); + + Game game = new Game.Builder() + .addCar(new Game.CarInfo("Voiture 1", Color.BLUE)) + .addCar(new Game.CarInfo("Voiture 2", Color.PINK)) + .addCar(new Game.CarInfo("Voiture 3", Color.RED)) + .setMap(m) + .build(); + game.run(); } } \ No newline at end of file