Skip to content
Snippets Groups Projects
FirefighterBoard.java 4.85 KiB
Newer Older
  • Learn to ignore specific revisions
  • LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
    package model;
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
    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;
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
      private final TargetStrategy targetStrategy = new TargetStrategy();
    
      private List<FireFighter> firefighter;
      private Set<Fire> fire;
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
      private Map<Position, List<Position>> neighbors = new HashMap();
      private final Position[][] positions;
    
      private int step = 0;
      private final Random randomGenerator = new Random();
    
    
      public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) {
        this.columnCount = columnCount;
        this.rowCount = rowCount;
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
        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;
        initializeElements();
      }
    
      public void initializeElements() {
    
        firefighter= new ArrayList<>();
        fire = new HashSet<>();
    
        for (int index = 0; index < initialFireCount; index++)
    
          fire.add(new Fire(randomPosition()));
    
        for (int index = 0; index < initialFirefighterCount; index++)
    
          firefighter.add(new FireFighter(randomPosition()));
    
      }
    
      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 (FireFighter firefighter : firefighter)
    
          if (firefighter.getFirefighterPosition().equals(position))
    
            result.add(ModelElement.FIREFIGHTER);
    
    
        for (Fire fire: fire)
          if (fire.getFirePositions().equals(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();
        modifiedPositions.addAll(updateFires());
    
        step++;
    
        return modifiedPositions;
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      private List<Position> updateFires() {
    
        List<Position> modifiedPositions = new ArrayList<>();
    
        if (step % 2 == 0) {
          List<Position> newFirePositions = new ArrayList<>();
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
            newFirePositions.addAll(neighbors.get(fire));
    
          for(Position position : newFirePositions) {
            fire.add(new Fire(position));
          }
    
          modifiedPositions.addAll(newFirePositions);
    
        return modifiedPositions;
    
      @Override
      public int stepNumber() {
        return step;
      }
    
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      private List<Position> updateFirefighters() {
    
        List<Position> modifiedPosition = new ArrayList<>();
    
        List<Position> firefighterNewPositions = new ArrayList<>();
    
        for (FireFighter firefighterPosition : firefighter) {
    
    couetoux.b's avatar
    couetoux.b committed
          Position newFirefighterPosition =
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
                  targetStrategy.neighborClosestToFire(firefighterPosition,
                          firePositions, neighbors);
    
          firefighterNewPositions.add(newFirefighterPosition);
          extinguish(newFirefighterPosition);
    
          modifiedPosition.add(firefighterPosition.getFirefighterPosition());
    
          modifiedPosition.add(newFirefighterPosition);
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
          List<Position> neighborFirePositions = neighbors.get(newFirefighterPosition).stream()
    
                  .filter(firePositions::contains).toList();
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
          for (Position firePosition : neighborFirePositions)
    
            extinguish(firePosition);
    
          modifiedPosition.addAll(neighborFirePositions);
    
        }
        firefighterPositions = firefighterNewPositions;
    
        return modifiedPosition;
    
      }
    
      @Override
      public void reset() {
    
        initializeElements();
      }
    
      private void extinguish(Position position) {
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      @Override
      public void setState(List<ModelElement> state, Position position) {
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
        for (; ; ) {
    
          if (!firefighterPostion.remove(position)) break;
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
        for (ModelElement element : state) {
          switch (element) {
    
            case FIRE -> fire.add(new Fire(position));
            case FIREFIGHTER -> firefighter.add(new FireFighter(position));
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
          }
        }
      }