package model; import util.Position; import util.TargetStrategy; import java.util.*; public class BoardFireFighterBehavior implements BoardBehavior{ private static TargetStrategy targetStrategy = new TargetStrategy(); private static Map<Position, List<Position>> neighbors; private static List<Position> rocky; private ElementFactory<Rocky> rockyFactory; private static Map<Position, Terrain> terrainMap = new HashMap<>(); private static int step; static Movements fireMovements ; static Movements fireFighterMovements; static Movements cloudMovements; static Movements motorizedMovements; private ElementGenerator moutainGenerator; public BoardFireFighterBehavior(Map<Position, List<Position>> neighbors, ElementFactory<Fire> fireFactory ,ElementFactory<FireFighter> firefighterFactory, ElementFactory<Cloud> cloudFactory,ElementFactory<MotorizedFireFighter> motorizedFactory,ElementFactory<Rocky> rockyFactory) { this.step=0; this.neighbors = neighbors; this.rockyFactory=rockyFactory; fireMovements=new FireMovements(fireFactory); fireFighterMovements=new FireFighterMovements(firefighterFactory); cloudMovements=new CloudMovements(cloudFactory); motorizedMovements=new MotorizedMovements(motorizedFactory); moutainGenerator=new MountainGenerator(); } public void initializeElements(int rowCount, int columnCount) { fireMovements.initializeElement(rowCount,columnCount); fireFighterMovements.initializeElement(rowCount,columnCount); cloudMovements.initializeElement(rowCount,columnCount); // Pompiers motorisés motorizedMovements.initializeElement(rowCount,columnCount); // Rocky rocky = new ArrayList<>(); List<Rocky> rockies = rockyFactory.createElements(rowCount, columnCount); for (Rocky rockyElement : rockies) { rocky.add(rockyElement.getPosition()); } moutainGenerator.generateElement(rowCount,columnCount); generateRoads(rowCount,columnCount); } public static void extinguish(Position position) { fireMovements.getPositions().remove(position); } public Set<Position> getFirePositions() { return (Set<Position>) fireMovements.getPositions(); } public void incrementStep() { step++; } @Override public int stepNumber() { return step; } @Override public List<Position> updateToNextGeneration() { List<Position> modifiedPositions = fireFighterMovements.updateElements(); modifiedPositions.addAll(fireMovements.updateElements()); modifiedPositions.addAll(cloudMovements.updateElements()); modifiedPositions.addAll(motorizedMovements.updateElements()); incrementStep(); return modifiedPositions; } @Override public void reset() { this.step=0; // Vider toutes les positions stockées fireMovements.getPositions().clear(); fireFighterMovements.getPositions().clear(); cloudMovements.getPositions().clear(); motorizedMovements.getPositions().clear(); rocky.clear(); terrainMap.clear(); } /** * Éteint les feux à proximité d'une position donnée. * * @param firefighterPosition La position actuelle du pompier. * @param modifiedPositions Les positions modifiées pendant ce tour. */ public static void extinguishNearbyFires(Position firefighterPosition, List<Position> modifiedPositions) { List<Position> nearbyFires = getNeighbors().getOrDefault(firefighterPosition, Collections.emptyList()) .stream() .filter(fireMovements.getPositions()::contains) .toList(); for (Position fire : nearbyFires) { fireMovements.getPositions().remove(fire); modifiedPositions.add(fire); System.out.println("Feu éteint à : " + fire); } } public static Map<Position, Terrain> getTerrainMap() { return terrainMap; } public static boolean canMoveTo(Position position, Set<Position> firePositions, List<Position> firefighterPositions) { // Vérifie si la position est hors des limites (par exemple, en dehors de la grille ou inaccessible) if (!neighbors.containsKey(position)) { return false; } // Si la position est occupée par un feu et que le terrain n'est pas traversable par le feu if(cloudMovements.getPositions().contains(position)) { return false; } // Si la position est une montagne, aucun élément ne peut la franchir sauf les nuages if (terrainMap.get(position) != null && !cloudMovements.getPositions().contains(position)) { return false; // Impossible de franchir une montagne, sauf pour un nuage } if(rocky.contains(position)) { return Rocky.canFirePropagate(); } return true; // La position est traversable } private void generateRoads(int rowCount, int columnCount) { Random random = new Random(); // Définir les bords de départ et d'arrivée int startRow = random.nextInt(rowCount); // Bord gauche int endRow = random.nextInt(rowCount); // Bord droit int startCol = 0; // Bord gauche (colonne 0) int endCol = columnCount - 1; // Bord droit (dernière colonne) // Générer une route connectant ces deux points List<Position> path = createPath(new Position(startRow, startCol), new Position(endRow, endCol)); // Placer la route dans la grille for (Position pos : path) { if (!terrainMap.containsKey(pos)) { // Éviter les obstacles terrainMap.put(pos, new Road(pos)); } } } /** * Génère un chemin connectant deux positions. */ private List<Position> createPath(Position start, Position end) { List<Position> path = new ArrayList<>(); int currentRow = start.row(); int currentCol = start.column(); // Algorithme simple de connexion entre les points (chemin en "zigzag") while (currentRow != end.row() || currentCol != end.column()) { path.add(new Position(currentRow, currentCol)); // Mouvement vertical if (currentRow < end.row()) { currentRow++; } else if (currentRow > end.row()) { currentRow--; } // Mouvement horizontal if (currentCol < end.column()) { currentCol++; } else if (currentCol > end.column()) { currentCol--; } } // Ajouter la position finale path.add(end); return path; } public static List<Position> getRocky() { return rocky; } public static int getStep() { return step; } public static Map<Position, List<Position>> getNeighbors() { return neighbors; } public static TargetStrategy getTargetStrategy() { return targetStrategy; } public static Collection<Position> getFirefighterPositions() { return fireFighterMovements.getPositions(); } public Collection<Position> getCloudPositions() { return cloudMovements.getPositions(); } public List<Position> getMotorizedFighters() { return (List<Position>) motorizedMovements.getPositions(); } }