package model; import java.util.ArrayList; import java.util.List; import model.car.Car; import model.map.Map; import visual.*; public class Game { @FunctionalInterface public static interface Observer { /** * * @return si False le programme s'arrete, sinon il continue */ public boolean apply(); } public static class Builder { private final List OBSERVERS = new ArrayList<>(); private int time = 500; private Map map = null; public Builder car(Car car) { this.OBSERVERS.add(car); return this; } public Builder map(Map map) { this.map = map; return this; } public Builder time(int time) { this.time = time; return this; } public Builder rankboard(String title, int width, int height, int x, int y) { this.OBSERVERS.add(new RankboardView(null, title, width, height, x, y)); return this; } public Builder track(String title, int width, int height, int x, int y) { this.OBSERVERS.add(new TrackView(null, title, width, height, x, y)); return this; } public Builder dashboard(Car car, String title, int width, int height, int x, int y) { this.OBSERVERS.add(new DashboardView(null, car, title, width, height, x, y)); return this; } public Builder dashboards(int width, int height, int x, int y) { List cars = OBSERVERS.stream() .filter(o -> o instanceof Car) .map(o -> (Car) o) .toList(); int index = 0; for (Car car : cars) { dashboard(car, car.getName(), width, height, x, y + (height * index++)); } return this; } public Game build() { Game game = new Game(this.map, this.time, this.OBSERVERS); for (Game.Observer observer : new ArrayList<>(this.OBSERVERS)) { switch (observer) { case GameView gameView -> { gameView.setGame(game); } default -> { } } } return game; } } private Map map; private int time; private List observers; private boolean isPaused; private Game() { } private Game(Map map, int time, List observer) { this.map = map; this.time = time; this.observers = observer; for (Game.Observer obs : this.observers) { switch (obs) { case Car car -> { car.setMap(map); } default -> { } } } } public Game addObserver(Observer o) { observers.add(o); return this; } public Game removeObserver(Observer o) { observers.remove(o); return this; } private boolean isFinish() { for (Game.Observer observer : observers) { switch (observer) { case Car car -> { if (car.getFuel() > 0) return false; } default -> { } } } return true; } public void notifyObservers() { for (Observer o : observers) { if (!o.apply()) { System.exit(0); } } } public void run() { try { while (!isFinish()) { synchronized (this) { while (isPaused) wait(); } notifyObservers(); Thread.sleep(time); } } catch (InterruptedException e) { e.printStackTrace(); System.exit(1); } } public synchronized boolean togglePause() { if (isPaused) notifyAll(); isPaused = !isPaused; return isPaused; } public List getCars() { return observers.stream() .filter(o -> o instanceof Car) .map(o -> (Car) o) .toList(); } public Map getMap() { return map; } public boolean getPause() { return isPaused; } }