Skip to content
Snippets Groups Projects
Scenario.java 5.93 KiB
Newer Older
  • Learn to ignore specific revisions
  • Yanis O's avatar
    Yanis O committed
    package model;
    
    
    
    import java.util.List;
    import java.util.Map;
    import java.util.Random;
    
    import app.SimulatorApplication;
    import model.firefighterscenario.Fire;
    import model.firefighterscenario.Mountain;
    import model.firefighterscenario.Road;
    import model.firefighterscenario.Rockery;
    
    Yanis O's avatar
    Yanis O committed
    import util.Matrix;
    
    import util.PathGenerator;
    import util.Position;
    import util.PositionUtil;
    
    public class Scenario implements Board<Square>{
    
      private Matrix<Square> matrix;
      protected int step;
      protected int turnsToSpawnAirTanker;
    
      private Map<EntityFactory, Integer> initialMap;
    
      public Scenario(int columns, int rows, Map<EntityFactory, Integer> initialMap) {
        this.matrix = new Matrix<Square>(columns, rows);
        initScenario(matrix);
        this.turnsToSpawnAirTanker = SimulatorApplication.TURNS_FOR_SPAWNING_AIRTANKER;
        this.step = 0;
        this.initialMap = initialMap;
        placeInitialEntities(initialMap);
      }
      public void initScenario(Matrix<Square> matrix){
        for(int x = 0; x < matrix.getRows(); x++){
            for(int y = 0; y < matrix.getColumns(); y++){
                Square s = new Square(new Position(x, y), new EmptySquare(new Position(x,y)));
                matrix.set(x,y, s);
            }
        }
    }
      protected Matrix<Square> getMatrix(){
        return this.matrix;
      }
    
      public void placeInitialEntities(Map<EntityFactory, Integer> initialMap) {
        EntitySpawner spawner = new EntitySpawner(this);
        spawner.spawnEntities(initialMap);
        generateRoads();
        
      }
    
      public Square getStates(Position position) {
        if (position.x() > matrix.size() || position.y() > matrix.size()) {
          throw new IllegalArgumentException(
              "The position x:" + position.x() + " y:" + position.y() + " is out of the board.");
        }
        return matrix.get(position.x(), position.y());
      }
    
      public void setSquare(Square square) {
        Position position = square.getPosition();
        if (!(getStates(position).isEmpty())) {
          return;
        }
        if (doesPositionExist(position)) {
          matrix.set(position.x(), position.y(), square);
        }
      }
    
      public void setSquare(Square square, boolean replaceStates) {
        Position position = square.getPosition();
        if (!(getStates(position).isEmpty()) && !replaceStates) {
          return;
        }
        matrix.set(position.x(), position.y(), square);
      }
    
      public void addEntityAtSquare(Entity entity, Position position) {
        if (doesPositionExist(position)) {
          matrix.get(position.x(), position.y()).addEntity(entity);
        }
      }
    
      public int rowCount() {
        return matrix.getRows();
      }
    
      public int columnCount() {
        return matrix.getColumns();
      }
    
      @Override
      public void clearCaseFrom(Entity entity, Position position) {
        matrix.get(position.x(), position.y()).getEntities().removeIf(element -> element.equals(entity));
      }
    
      public Position getNearestEntity(Position fromPos, Class<?> entityType) {
        int rows = matrix.getRows();
        int cols = matrix.getColumns();
        Position nearestPosition = fromPos;
    
        // Définir la distance maximale possible
        int maxDistance = rows + cols;
        // Parcourir les distances croissantes à partir de 1
        for (int distance = 1; distance < maxDistance; distance++) {
          List<Position> positionsAtDistance = PositionUtil.getPositionsAtManhattanDistance(fromPos, distance, rows, cols);
    
          for (Position currentPos : positionsAtDistance) {
            Square currentSquare = matrix.get(currentPos.x(), currentPos.y());
            for (Entity currentEntity : currentSquare.getEntities()) {
              if (entityType.isInstance(currentEntity)) {
                // Dès qu'une entité est trouvée à cette distance, elle est la plus proche
                // possible
                return currentPos;
              }
            }
          }
        }
    
        return nearestPosition; // Retourne null si aucune entité n'est trouvée
      }
    
      public void reset() {
        step = 0;
        matrix.clear();
        initScenario(matrix);
        placeInitialEntities(initialMap);
      }
    
      public int stepNumber() {
        return this.step;
      }
    
      @Override
      public boolean doesPositionExist(Position position) {
        return matrix.validateIndex(position);
      }
    
      @Override
      public int getStepNumber() {
        return step;
      }
    
      @Override
      public boolean doesSquareContainEntity(Position squarePos, Class<?> entityType) {
        return getStates(squarePos).getEntities().stream().anyMatch(entityType::isInstance);
      }
    
      @Override
      public boolean isPositionEmpty(Position position) {
        return getStates(position).isEmpty();
      }
    
      @Override
      public boolean isPositionFree(Position position, int priority) {
        List<Entity> entities = matrix.get(position.x(), position.y()).getEntities();
        for (Entity e : entities) {
          if (e.getPriority() == priority) {
            return false;
          }
        }
        return true;
      }
    
      private void generateRoads() {
        if(columnCount() < 10 || rowCount() < 10){
          return;
        }
        Random random = new Random();
    
        // Get board dimensions
        int rowCount = rowCount();      // Number of rows (vertical axis)
        int columnCount = columnCount(); // Number of columns (horizontal axis)
    
        // Decide randomly whether to set x or y to 0
        boolean setXToZero = random.nextBoolean();
    
        int x = 0;
        int y = 0;
    
        if (setXToZero) {
            // x is set to 0, y is random within column bounds
            x = 0;
            y = random.nextInt(columnCount);
        } else {
            // y is set to 0, x is random within row bounds
            x = random.nextInt(rowCount);
            y = 0;
        }
    
        Position startPosition = new Position(x, y);
        PathGenerator pathGenerator = new PathGenerator(this, startPosition, 4, columnCount());
        // Call generateEntitiesInLine to place the roads
        List<Position> snake = pathGenerator.generate();
        for(Position p : snake){
          List<Entity> entitiesAtSquare = List.copyOf(getStates(p).getEntities());
          for(Entity e: entitiesAtSquare){
            if(e instanceof Mountain || e instanceof Rockery || e instanceof Fire){
              clearCaseFrom(e, e.getPosition());
            }
          }
          addEntityAtSquare(new Road(p), p);
        }
    }
    
    Yanis OUALAN's avatar
    Yanis OUALAN committed