Skip to content
Snippets Groups Projects
FirefighterBoard.java 5.65 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;
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
    import util.TargetStrategy;
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
    import java.util.*;
    
    
    public class FirefighterBoard implements Board<List<ModelElement>> {
      private final int columnCount;
      private final int rowCount;
    
      private final int initialFireCount;
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
      private final int initialFirefighterCount;
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
      private final TargetStrategy targetStrategy = new TargetStrategy();
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
      private List<FireFighter> firefighters;
      private Set<Fire> fires;
    
    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();
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
    
      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);
          }
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        this.initialFireCount = initialFireCount;
        this.initialFirefighterCount = initialFirefighterCount;
        initializeElements();
      }
    
      public void initializeElements() {
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        firefighters = new ArrayList<>();
        fires = new HashSet<>();
        for (int index = 0; index < initialFireCount; index++)
          fires.add(new Fire(randomPosition()));
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        for (int index = 0; index < initialFirefighterCount; index++)
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
          firefighters.add(new FireFighter(randomPosition()));
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      }
    
      private Position randomPosition() {
    
        return new Position(randomGenerator.nextInt(rowCount), randomGenerator.nextInt(columnCount));
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      }
    
      @Override
      public List<ModelElement> getState(Position position) {
        List<ModelElement> result = new ArrayList<>();
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        for (FireFighter firefighter : firefighters)
          if (firefighter.getPosition().equals(position))
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
            result.add(ModelElement.FIREFIGHTER);
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        if (this.getFirePositions(fires).contains(position))
          result.add(ModelElement.FIRE);
    
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        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());
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        step++;
    
        return modifiedPositions;
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      private List<Position> updateFires() {
    
        List<Position> modifiedPositions = new ArrayList<>();
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        if (step % 2 == 0) {
          List<Position> newFirePositions = new ArrayList<>();
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
          for (Position fire : getFirePositions(this.fires)) {
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
            newFirePositions.addAll(neighbors.get(fire));
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
          this.getFirePositions(fires).addAll(newFirePositions);
    
          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<>();
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        List<Position> firefighterNewPositions = new ArrayList<>();
        for (Position firefighterPosition : this.getFireFighterPositions(this.firefighters)) {
    
    couetoux.b's avatar
    couetoux.b committed
          Position newFirefighterPosition =
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
                  targetStrategy.neighborClosestToFire(firefighterPosition,
                          this.getFirePositions(fires), neighbors);
          firefighterNewPositions.add(newFirefighterPosition);
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
          extinguish(newFirefighterPosition);
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
          modifiedPosition.add(firefighterPosition);
    
          modifiedPosition.add(newFirefighterPosition);
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
          List<Position> neighborFirePositions = neighbors.get(newFirefighterPosition).stream()
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
                  .filter(this.getFirePositions(fires)::contains).toList();
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
          for (Position firePosition : neighborFirePositions)
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
            extinguish(firePosition);
    
          modifiedPosition.addAll(neighborFirePositions);
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        ArrayList<FireFighter> newFireFighters = new ArrayList<>();
        for(Position position : firefighterNewPositions){
          newFireFighters.add(new FireFighter(position));
        }
        firefighters = newFireFighters;
    
        return modifiedPosition;
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      }
    
      @Override
      public void reset() {
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        initializeElements();
      }
    
      private void extinguish(Position position) {
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        for(Fire fire: fires){
          if(fire.getPosition().equals(position)){
            fires.remove(fire);
          }
        }
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      @Override
      public void setState(List<ModelElement> state, Position position) {
    
        extinguish(position);
    
    COUETOUX Basile's avatar
    COUETOUX Basile committed
        for (; ; ) {
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
          if (!getFireFighterPositions(this.firefighters).remove(position)) break;
        }
        for (ModelElement element : state) {
          switch (element) {
            case FIRE -> fires.add(new Fire(position));
            case FIREFIGHTER -> firefighters.add(new FireFighter(position));
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        }
      }
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
    
    
      public Set<Position> getFirePositions(Set<Fire> fireSet){
        Set<Position> firePositions = new HashSet<>();
        for(Fire fire : fireSet){
          firePositions.add(fire.getPosition());
        }
        return firePositions;
      }
    
    
      public ArrayList<Position> getFireFighterPositions(List<FireFighter> fireFighterList){
        ArrayList<Position> fireFighterPositions = new ArrayList<>();
        for(FireFighter fireFighter : fireFighterList){
          fireFighterPositions.add(fireFighter.getPosition());
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
        }
    
    BELHACHEMI Mehdi's avatar
    BELHACHEMI Mehdi committed
        return fireFighterPositions;
    
    LABOUREL Arnaud's avatar
    LABOUREL Arnaud committed
      }