package model; import util.Position; import java.util.*; public class FirefighterBoard implements Board<List<ModelElement>> { private final int columnCount; private final int rowCount; private final int initialFireCount; private final int initialFirefighterCount; private final int initialCloudCount; private final model.TargetStrategy targetStrategy = new model.TargetStrategy(); private List<Firefighter> firefighters; private Fire fire; private final Map<Position, List<Position>> neighbors = new HashMap<>(); private List<Cloud> clouds; private final Position[][] positions; private int step = 0; private final Random randomGenerator = new Random(); public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount, int initialCloudCount) { this.columnCount = columnCount; this.rowCount = rowCount; this.positions = new Position[rowCount][columnCount]; for (int column = 0; column < columnCount; column++) for (int row = 0; row < rowCount; row++) positions[row][column] = new Position(row, column); for (int column = 0; column < columnCount; column++) for (int row = 0; row < rowCount; row++) { List<Position> list = new ArrayList<>(); if (row > 0) list.add(positions[row - 1][column]); if (column > 0) list.add(positions[row][column - 1]); if (row < rowCount - 1) list.add(positions[row + 1][column]); if (column < columnCount - 1) list.add(positions[row][column + 1]); neighbors.put(positions[row][column], list); } this.initialFireCount = initialFireCount; this.initialFirefighterCount = initialFirefighterCount; this.initialCloudCount = initialCloudCount; initializeElements(); } public void initializeElements() { firefighters = new ArrayList<>(); clouds = new ArrayList<>(); Set<Position> firePositions = new HashSet<>(); for (int index = 0; index < initialCloudCount; index++) { clouds.add(new Cloud(randomPosition(), neighbors)); } for (int index = 0; index < initialFireCount; index++) firePositions.add(randomPosition()); fire = new Fire(firePositions, neighbors); for (int index = 0; index < initialFirefighterCount; index++) firefighters.add(new Firefighter(randomPosition())); for (int index = 0; index < initialCloudCount; index++) { clouds.add(new Cloud(randomPosition(), neighbors)); } } private Position randomPosition() { return new Position(randomGenerator.nextInt(rowCount), randomGenerator.nextInt(columnCount)); } @Override public List<ModelElement> getState(Position position) { List<ModelElement> result = new ArrayList<>(); for (Cloud cloud : clouds) { if (cloud.getPosition().equals(position)) { result.add(ModelElement.CLOUD); } } for (Firefighter firefighter : firefighters) if (firefighter.getPosition().equals(position)) result.add(ModelElement.FIREFIGHTER); if (fire.getFirePositions().contains(position)) result.add(ModelElement.FIRE); return result; } @Override public int rowCount() { return rowCount; } @Override public int columnCount() { return columnCount; } public List<Position> updateToNextGeneration() { List<Position> modifiedPositions = updateFirefighters(); if (step % 2 == 0){ modifiedPositions.addAll(fire.spreadFire()); } // Déplacer les nuages et éteindre les feux for (Cloud cloud : clouds) { //cloud.moveRandomly(); //cloud.extinguishFire(fire); cloud.moveAndExtinguishFire(fire); cloud.extinguishFireCloud(fire); //modifiedPositions.addAll(fire.spreadFire()); } step++; return modifiedPositions; } @Override public int stepNumber() { return step; } private List<Position> updateFirefighters() { List<Position> modifiedPosition = new ArrayList<>(); for (Firefighter firefighter : firefighters) { modifiedPosition.add(firefighter.getPosition()); Position newPosition = firefighter.moveToBestPosition(targetStrategy, fire.getFirePositions(), neighbors); firefighter.setPosition(newPosition); modifiedPosition.add(newPosition); firefighter.extinguish(newPosition, fire.getFirePositions()); // Éteindre les feux dans les positions voisines List<Position> adjacentFires = neighbors.get(newPosition).stream() .filter(fire.getFirePositions()::contains) .toList(); for (Position firePosition : adjacentFires) { firefighter.extinguish(firePosition, fire.getFirePositions()); modifiedPosition.add(firePosition); } } return modifiedPosition; } @Override public void reset() { step = 0; initializeElements(); } @Override public void setState(List<ModelElement> state, Position position) { fire.getFirePositions().remove(position); firefighters.removeIf(f -> f.getPosition().equals(position)); clouds.removeIf(c -> c.getPosition().equals(position)); for (ModelElement element : state) { switch (element) { case FIRE -> fire.getFirePositions().add(position); case FIREFIGHTER -> firefighters.add(new Firefighter(position)); case CLOUD -> clouds.add(new Cloud(position, neighbors)); } } } }