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