From 45a4dc2b7e17d87e47ab0cd86d019083c843b2b5 Mon Sep 17 00:00:00 2001
From: kallel <mohamed-ali.KALLEL@etu.univ-amu.fr>
Date: Wed, 22 Nov 2023 13:56:06 +0100
Subject: [PATCH] task 1

---
 src/main/java/app/SimulatorApplication.java   |   3 +-
 src/main/java/controller/Controller.java      |  24 ++--
 src/main/java/model/Board.java                |   4 +-
 src/main/java/model/Element/Cloud.java        |  33 +++++
 src/main/java/model/Element/Fire.java         |  53 +++++++
 src/main/java/model/Element/ModelElement.java |  15 ++
 .../model/Element/MotorisedFirefigther.java   |  42 ++++++
 src/main/java/model/Element/Mountain.java     |  25 ++++
 src/main/java/model/Element/Road.java         |  25 ++++
 src/main/java/model/Element/Rockerie.java     |  26 ++++
 src/main/java/model/FirefighterBoard.java     | 129 ++++++------------
 src/main/java/model/ModelElement.java         |   5 -
 src/main/java/util/Tools.java                 |  66 +++++++++
 src/main/java/view/ViewElement.java           |   4 +-
 src/test/java/model/FirefighterBoardTest.java |   1 +
 15 files changed, 354 insertions(+), 101 deletions(-)
 create mode 100644 src/main/java/model/Element/Cloud.java
 create mode 100644 src/main/java/model/Element/Fire.java
 create mode 100644 src/main/java/model/Element/ModelElement.java
 create mode 100644 src/main/java/model/Element/MotorisedFirefigther.java
 create mode 100644 src/main/java/model/Element/Mountain.java
 create mode 100644 src/main/java/model/Element/Road.java
 create mode 100644 src/main/java/model/Element/Rockerie.java
 delete mode 100644 src/main/java/model/ModelElement.java
 create mode 100644 src/main/java/util/Tools.java

diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java
index 6b009e4..d20a636 100644
--- a/src/main/java/app/SimulatorApplication.java
+++ b/src/main/java/app/SimulatorApplication.java
@@ -18,7 +18,8 @@ public class SimulatorApplication extends javafx.application.Application {
   private static final int SQUARE_WIDTH = 50;
   private static final int SQUARE_HEIGHT = 50;
   public static final int INITIAL_FIRE_COUNT = 3;
-  public static final int INITIAL_FIREFIGHTER_COUNT = 6;
+  public static final int INITIAL_FIREFIGHTER_COUNT = 10;
+  public static final int INITIAL_CLOUD_COUNT=10;
 
   private Stage primaryStage;
   private Parent view;
diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index 2a60897..3291416 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -13,7 +13,9 @@ import javafx.scene.control.ToggleGroup;
 import javafx.util.Duration;
 import javafx.util.Pair;
 import model.Board;
-import model.ModelElement;
+import model.Element.Fire;
+import model.Element.FireFigther;
+import model.Element.ModelElement;
 import model.FirefighterBoard;
 import util.Position;
 import view.Grid;
@@ -21,6 +23,7 @@ import view.ViewElement;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import static java.util.Objects.requireNonNull;
 
@@ -59,9 +62,9 @@ public class Controller {
   }
 
   private void updateBoard(){
-    List<Position> updatedPositions = board.updateToNextGeneration();
+    Map<Position,List<ModelElement>> updatedPositions = board.updateToNextGeneration();
     List<Pair<Position, ViewElement>> updatedSquares = new ArrayList<>();
-    for(Position updatedPosition : updatedPositions){
+    for(Position updatedPosition : updatedPositions.keySet()){
       List<ModelElement> squareState = board.getState(updatedPosition);
       ViewElement viewElement = getViewElement(squareState);
       updatedSquares.add(new Pair<>(updatedPosition, viewElement));
@@ -80,17 +83,20 @@ public class Controller {
     grid.repaint(viewElements);
     updateGenerationLabel(board.stepNumber());
   }
-
   private ViewElement getViewElement(List<ModelElement> squareState) {
-    if(squareState.contains(ModelElement.FIREFIGHTER)){
-      return ViewElement.FIREFIGHTER;
+    if (squareState == null) {
+      return ViewElement.EMPTY;
     }
-    if (squareState.contains(ModelElement.FIRE)){
-      return ViewElement.FIRE;
+    if (squareState.isEmpty()) {
+      return ViewElement.EMPTY;
     }
-    return ViewElement.EMPTY;
+    return squareState.get(0).getViewElement();
+
   }
 
+
+
+
   private void initializeTimeline() {
     Duration duration = new Duration(Controller.PERIOD_IN_MILLISECONDS);
     EventHandler<ActionEvent> eventHandler =
diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java
index bb089a4..0f6bab6 100644
--- a/src/main/java/model/Board.java
+++ b/src/main/java/model/Board.java
@@ -1,8 +1,10 @@
 package model;
 
+import model.Element.ModelElement;
 import util.Position;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * This interface represents a generic board for modeling various state-based systems.
@@ -48,7 +50,7 @@ public interface Board<S> {
    *
    * @return A list of positions that have changed during the update.
    */
-  List<Position> updateToNextGeneration();
+  Map<Position, List<ModelElement>> updateToNextGeneration();
 
   /**
    * Reset the board to its initial state.
diff --git a/src/main/java/model/Element/Cloud.java b/src/main/java/model/Element/Cloud.java
new file mode 100644
index 0000000..b5eb6db
--- /dev/null
+++ b/src/main/java/model/Element/Cloud.java
@@ -0,0 +1,33 @@
+package model.Element;
+
+import util.Position;
+import view.ViewElement;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import static util.Tools.*;
+
+
+public class Cloud implements ModelElement {
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof Cloud;
+    }
+
+    @Override
+    public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) {
+        Random nextCloud =new Random() ;
+        addElement(neighbors(position, rowCount, columnCount).get(nextCloud.nextInt()),board, new Cloud());
+        removeElement(position,board,new Cloud());
+
+    }
+
+
+    @Override
+    public ViewElement getViewElement() {
+        return ViewElement.Cloud;
+    }
+}
diff --git a/src/main/java/model/Element/Fire.java b/src/main/java/model/Element/Fire.java
new file mode 100644
index 0000000..b67356c
--- /dev/null
+++ b/src/main/java/model/Element/Fire.java
@@ -0,0 +1,53 @@
+package model.Element;
+
+import model.FirefighterBoard;
+import util.Position;
+import view.ViewElement;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+import static util.Tools.addElement;
+import static util.Tools.neighbors;
+
+public class Fire implements ModelElement  {
+    int fireWasCreate;
+
+    public void setFireWasCreate(int fireWasCreate) {
+        this.fireWasCreate = fireWasCreate;
+    }
+
+    @Override
+    public void update(Position position, Map<Position, List<ModelElement>> board,int step,  int columnCount, int rowCount) {
+        if (step%2==0){
+            Fire nextFire = new Fire();
+            nextFire.setFireWasCreate(step);
+            for (Position position1 : neighbors(position, rowCount, columnCount)) {
+
+                if (!board.containsKey(position1)){
+                    addElement(position1, board, new Fire());
+                } else if (board.get(position1).isEmpty()) {
+                    addElement(position1, board, new Fire());
+                }
+                if (board.get(position1).contains(new Rockerie()) && (step - fireWasCreate)%4 ==0){
+                    if (!(board.get(position1).contains(new Mountain())||board.get(position1).contains(new FireFigther())||board.get(position1).contains(new MotorisedFirefigther())||board.get(position1).contains(new Cloud())||(board.get(position1).contains(new FireFigther())))){
+                        addElement(position1, board, new Fire());
+                    }
+                }
+            }
+        }
+    }
+
+
+
+    @Override
+    public ViewElement getViewElement() {
+        return ViewElement.FIRE;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof Fire;
+    }
+}
diff --git a/src/main/java/model/Element/ModelElement.java b/src/main/java/model/Element/ModelElement.java
new file mode 100644
index 0000000..9e88284
--- /dev/null
+++ b/src/main/java/model/Element/ModelElement.java
@@ -0,0 +1,15 @@
+package model.Element;
+
+import util.Position;
+import view.ViewElement;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ModelElement {
+  void update (Position position,Map<Position,List<ModelElement>>board,int step,int columnCount, int rowCount);
+
+
+
+  ViewElement getViewElement();
+}
diff --git a/src/main/java/model/Element/MotorisedFirefigther.java b/src/main/java/model/Element/MotorisedFirefigther.java
new file mode 100644
index 0000000..94bc962
--- /dev/null
+++ b/src/main/java/model/Element/MotorisedFirefigther.java
@@ -0,0 +1,42 @@
+package model.Element;
+
+import util.Position;
+import view.ViewElement;
+
+import java.util.List;
+import java.util.Map;
+
+import static util.Tools.*;
+import static util.Tools.removeElement;
+
+public class MotorisedFirefigther implements ModelElement{
+    @Override
+    public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) {
+        for (Position position1 : neighbors(position, rowCount, columnCount)) {
+            if (board.containsKey(position1)) {
+                if (board.get(position1).contains(new Fire())) {
+                    extinguish(position,board);
+                    return;
+                }
+
+            }
+
+        }
+        Position newPositionStep = neighborClosestToFire(position,board,rowCount,columnCount);
+        Position newPositionTwoStep=neighborClosestToFire(newPositionStep,board,rowCount,columnCount);
+        extinguish(newPositionTwoStep,board);
+        addElement(newPositionTwoStep,board,new MotorisedFirefigther());
+        removeElement(position,board,new MotorisedFirefigther());
+
+
+    }
+
+    @Override
+    public ViewElement getViewElement() {
+        return ViewElement.MotorisedFirefigther;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof Mountain;
+    }
+}
diff --git a/src/main/java/model/Element/Mountain.java b/src/main/java/model/Element/Mountain.java
new file mode 100644
index 0000000..8d363c0
--- /dev/null
+++ b/src/main/java/model/Element/Mountain.java
@@ -0,0 +1,25 @@
+package model.Element;
+
+import util.Position;
+import view.ViewElement;
+
+import java.util.List;
+import java.util.Map;
+
+public class Mountain implements ModelElement{
+
+
+    @Override
+    public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) {
+
+    }
+
+    @Override
+    public ViewElement getViewElement() {
+        return ViewElement.Mountain;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof Mountain;
+    }
+}
diff --git a/src/main/java/model/Element/Road.java b/src/main/java/model/Element/Road.java
new file mode 100644
index 0000000..e455f73
--- /dev/null
+++ b/src/main/java/model/Element/Road.java
@@ -0,0 +1,25 @@
+package model.Element;
+
+import util.Position;
+import view.ViewElement;
+
+import java.util.List;
+import java.util.Map;
+
+public class Road implements ModelElement{
+
+
+    @Override
+    public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) {
+
+    }
+
+    @Override
+    public ViewElement getViewElement() {
+        return ViewElement.Road;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof Road;
+    }
+}
diff --git a/src/main/java/model/Element/Rockerie.java b/src/main/java/model/Element/Rockerie.java
new file mode 100644
index 0000000..cd296f2
--- /dev/null
+++ b/src/main/java/model/Element/Rockerie.java
@@ -0,0 +1,26 @@
+package model.Element;
+
+import util.Position;
+import view.ViewElement;
+
+import java.util.List;
+import java.util.Map;
+
+public class Rockerie implements ModelElement{
+
+
+    @Override
+    public void update(Position position, Map<Position, List<ModelElement>> board, int step, int columnCount, int rowCount) {
+
+    }
+
+    @Override
+    public ViewElement getViewElement() {
+        return ViewElement.Rockerie;
+    }
+    @Override
+    public boolean equals(Object obj) {
+
+        return obj instanceof Rockerie;
+    }
+}
diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java
index 3251952..16f8b2f 100644
--- a/src/main/java/model/FirefighterBoard.java
+++ b/src/main/java/model/FirefighterBoard.java
@@ -1,9 +1,14 @@
 package model;
 
+import model.Element.Fire;
+import model.Element.FireFigther;
+import model.Element.ModelElement;
 import util.Position;
 
 import java.util.*;
 
+import static util.Tools.addElement;
+
 
 public class FirefighterBoard implements Board<List<ModelElement>> {
   private final int columnCount;
@@ -12,6 +17,7 @@ public class FirefighterBoard implements Board<List<ModelElement>> {
   private final int initialFirefighterCount;
   private List<Position> firefighterPositions;
   private Set<Position> firePositions;
+  private Map<Position,List<ModelElement>>board;
   private int step = 0;
   private final Random randomGenerator = new Random();
 
@@ -20,16 +26,29 @@ public class FirefighterBoard implements Board<List<ModelElement>> {
     this.rowCount = rowCount;
     this.initialFireCount = initialFireCount;
     this.initialFirefighterCount = initialFirefighterCount;
+    board=new HashMap<>();
     initializeElements();
   }
 
   public void initializeElements() {
     firefighterPositions = new ArrayList<>();
     firePositions = new HashSet<>();
+
     for (int index = 0; index < initialFireCount; index++)
       firePositions.add(randomPosition());
     for (int index = 0; index < initialFirefighterCount; index++)
       firefighterPositions.add(randomPosition());
+    for (Position firefighterPosition:firefighterPositions
+         ) {
+      addElement(firefighterPosition, board, new FireFigther());
+
+    }
+    for (Position firePosition:firePositions
+    ) {
+      addElement(firePosition, board, new Fire());
+
+    }
+
   }
 
   private Position randomPosition() {
@@ -38,13 +57,7 @@ public class FirefighterBoard implements Board<List<ModelElement>> {
 
   @Override
   public List<ModelElement> getState(Position position) {
-    List<ModelElement> result = new ArrayList<>();
-    for(Position firefighterPosition : firefighterPositions)
-      if (firefighterPosition.equals(position))
-        result.add(ModelElement.FIREFIGHTER);
-    if(firePositions.contains(position))
-      result.add(ModelElement.FIRE);
-    return result;
+    return board.get(position);
   }
 
   @Override
@@ -57,101 +70,49 @@ public class FirefighterBoard implements Board<List<ModelElement>> {
     return columnCount;
   }
 
-  public List<Position> updateToNextGeneration() {
-    List<Position> result = updateFirefighters();
-    result.addAll(updateFires());
-    step++;
-    return result;
-  }
+  public Map<Position, List<ModelElement>> updateToNextGeneration() {
+    Map<Position, List<ModelElement>> copieBord=new HashMap<>();
+    for (Position positionCopie:board.keySet()
+    ) {
+      copieBord.put(positionCopie, board.get(positionCopie));
+    }
 
-  private List<Position> updateFires() {
-    List<Position> result = new ArrayList<>();
-    if (step % 2 == 0) {
-      List<Position> newFirePositions = new ArrayList<>();
-      for (Position fire : firePositions) {
-        newFirePositions.addAll(neighbors(fire));
+
+    for (Position position:copieBord.keySet()
+         ) {
+      for (ModelElement element:copieBord.get(position)
+           ) {
+        element.update(position,board,step,columnCount,rowCount);
       }
-      firePositions.addAll(newFirePositions);
-      result.addAll(newFirePositions);
+
     }
-    return result;
+    step++;
+    return board;
+
 
   }
 
+
+
   @Override
   public int stepNumber() {
     return step;
   }
-
-  private List<Position> updateFirefighters() {
-    List<Position> result = new ArrayList<>();
-    List<Position> firefighterNewPositions = new ArrayList<>();
-    for (Position firefighterPosition : firefighterPositions) {
-      Position newFirefighterPosition = neighborClosestToFire(firefighterPosition);
-      firefighterNewPositions.add(newFirefighterPosition);
-      extinguish(newFirefighterPosition);
-      result.add(firefighterPosition);
-      result.add(newFirefighterPosition);
-      List<Position> neighborFirePositions = neighbors(newFirefighterPosition).stream()
-              .filter(firePositions::contains).toList();
-      for(Position firePosition : neighborFirePositions)
-        extinguish(firePosition);
-      result.addAll(neighborFirePositions);
-    }
-    firefighterPositions = firefighterNewPositions;
-    return result;
-  }
-
+  
   @Override
   public void reset() {
     step = 0;
     initializeElements();
   }
 
-  private void extinguish(Position position) {
-    firePositions.remove(position);
-  }
-
-  private List<Position> neighbors(Position position) {
-    List<Position> list = new ArrayList<>();
-    if (position.row() > 0) list.add(new Position(position.row() - 1, position.column()));
-    if (position.column() > 0) list.add(new Position(position.row(), position.column() - 1));
-    if (position.row() < rowCount - 1) list.add(new Position(position.row() + 1, position.column()));
-    if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1));
-    return list;
-  }
-
-  private Position neighborClosestToFire(Position position) {
-    Set<Position> seen = new HashSet<>();
-    HashMap<Position, Position> firstMove = new HashMap<>();
-    Queue<Position> toVisit = new LinkedList<>(neighbors(position));
-    for (Position initialMove : toVisit)
-      firstMove.put(initialMove, initialMove);
-    while (!toVisit.isEmpty()) {
-      Position current = toVisit.poll();
-      if (firePositions.contains(current))
-        return firstMove.get(current);
-      for (Position adjacent : neighbors(current)) {
-        if (seen.contains(adjacent)) continue;
-        toVisit.add(adjacent);
-        seen.add(adjacent);
-        firstMove.put(adjacent, firstMove.get(current));
-      }
-    }
-    return position;
-  }
-
   @Override
   public void setState(List<ModelElement> state, Position position) {
-    firePositions.remove(position);
-    for (;;) {
-      if (!firefighterPositions.remove(position)) break;
-    }
-    for(ModelElement element : state){
-      switch (element){
-        case FIRE -> firePositions.add(position);
-        case FIREFIGHTER -> firefighterPositions.add(position);
-      }
+    if (position != null) {
+      board.put(position, state);
+    } else {
+      System.err.println("La position spécifiée est null.");
     }
   }
+
+
 }
\ No newline at end of file
diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java
deleted file mode 100644
index 759eee5..0000000
--- a/src/main/java/model/ModelElement.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package model;
-
-public enum ModelElement {
-  FIREFIGHTER, FIRE
-}
diff --git a/src/main/java/util/Tools.java b/src/main/java/util/Tools.java
new file mode 100644
index 0000000..1005a29
--- /dev/null
+++ b/src/main/java/util/Tools.java
@@ -0,0 +1,66 @@
+package util;
+
+import model.Element.Fire;
+import model.Element.FireFigther;
+import model.Element.ModelElement;
+import model.Element.Mountain;
+
+import java.util.*;
+
+public class Tools {
+    public static List<Position> neighbors(Position position , int rowCount , int columnCount) {
+        List<Position> list = new ArrayList<>();
+        if (position.row() > 0) list.add(new Position(position.row() - 1, position.column()));
+        if (position.column() > 0) list.add(new Position(position.row(), position.column() - 1));
+        if (position.row() < rowCount - 1) list.add(new Position(position.row() + 1, position.column()));
+        if (position.column() < columnCount - 1) list.add(new Position(position.row(), position.column() + 1));
+        return list;
+    }
+    public static Position neighborClosestToFire(Position position,Map<Position, List<ModelElement>> board,int rowCount , int columnCount) {
+        Set<Position> seen = new HashSet<>();
+        HashMap<Position, Position> firstMove = new HashMap<>();
+        Queue<Position> toVisit = new LinkedList<>(neighbors(position,rowCount,columnCount));
+        for (Position initialMove : toVisit)
+            firstMove.put(initialMove, initialMove);
+        while (!toVisit.isEmpty()) {
+            Position current = toVisit.poll();
+            if (board.containsKey(current)) {
+                    if (board.get(current).contains(new Fire())){
+                        return firstMove.get(current);
+                    }
+                for (Position adjacent : neighbors(current, rowCount, columnCount)) {
+                    if (seen.contains(adjacent)) {
+                        continue;
+                    }
+                    toVisit.add(adjacent);
+                    seen.add(adjacent);
+                    firstMove.put(adjacent, firstMove.get(current));
+
+                }
+
+            }
+        }
+        return position;
+    }
+    public static void extinguish(Position position,Map<Position, List<ModelElement>> board) {
+        board.remove(position);
+    }
+
+    public static void addElement(Position position, Map<Position, List<ModelElement>> board, ModelElement element) {
+        List<ModelElement> elements = new ArrayList<>();
+        if (board.containsKey(position)) {
+            elements.addAll(board.get(position));
+        }
+        elements.add(element);
+        board.put(position,elements);
+    }
+    public static void removeElement(Position position,Map<Position, List<ModelElement>> board,ModelElement element){
+        List<ModelElement> elements = new ArrayList<>();
+        if (board.containsKey(position)) {
+            elements.addAll(board.get(position));
+        }
+        elements.remove(element);
+        board.put(position,elements);
+    }
+
+}
diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java
index ffb7611..a5b26b5 100644
--- a/src/main/java/view/ViewElement.java
+++ b/src/main/java/view/ViewElement.java
@@ -3,9 +3,11 @@ package view;
 import javafx.scene.paint.Color;
 
 public enum ViewElement {
-  FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE);
+  FIREFIGHTER(Color.BLUE), FIRE(Color.RED),Cloud(Color.GRAY),Rockerie(Color.LIGHTGREY),MotorisedFirefigther(Color.ALICEBLUE),Road(Color.BLACK),Mountain(Color.BROWN), EMPTY(Color.WHITE);
   final Color color;
   ViewElement(Color color) {
     this.color = color;
   }
+
+
 }
diff --git a/src/test/java/model/FirefighterBoardTest.java b/src/test/java/model/FirefighterBoardTest.java
index 25cc8db..4feb1d1 100644
--- a/src/test/java/model/FirefighterBoardTest.java
+++ b/src/test/java/model/FirefighterBoardTest.java
@@ -1,5 +1,6 @@
 package model;
 
+import model.Element.ModelElement;
 import org.junit.jupiter.api.Test;
 import util.Position;
 
-- 
GitLab