diff --git a/.gradle/8.10.2/executionHistory/executionHistory.bin b/.gradle/8.10.2/executionHistory/executionHistory.bin index 98ecd17592fd3aea79dac8e7c51ce70587ca4063..356014674fb63d4fdcabb77d2a8a71be252803d0 100644 Binary files a/.gradle/8.10.2/executionHistory/executionHistory.bin and b/.gradle/8.10.2/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.10.2/executionHistory/executionHistory.lock b/.gradle/8.10.2/executionHistory/executionHistory.lock index 52c071fa673591c7f2f70311c123de4770de3fe3..364735a916720d347b85ceef00df9a9a2254aa90 100644 Binary files a/.gradle/8.10.2/executionHistory/executionHistory.lock and b/.gradle/8.10.2/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.bin b/.gradle/8.10.2/fileHashes/fileHashes.bin index 4f24b129676b1fd085520e112d41d12ace6d74a1..c66a162ad97620144152aa3cbeb67b4087a68adb 100644 Binary files a/.gradle/8.10.2/fileHashes/fileHashes.bin and b/.gradle/8.10.2/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.10.2/fileHashes/fileHashes.lock b/.gradle/8.10.2/fileHashes/fileHashes.lock index d5daea42486733d983bfb0d4c13ff94e293d5b04..fd6eb11de62d8a1380c454eda64c76dbbd9426dd 100644 Binary files a/.gradle/8.10.2/fileHashes/fileHashes.lock and b/.gradle/8.10.2/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.10.2/fileHashes/resourceHashesCache.bin b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin index a04a18530400cb9aff321ea672c2050665862ff2..bc8e5d2dfc298a80508290e67d34e5f0a7146d78 100644 Binary files a/.gradle/8.10.2/fileHashes/resourceHashesCache.bin and b/.gradle/8.10.2/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 0652d045544b5231cee8310fa15244604bef24ff..bdb8cb7aea7f8ef6495de3bf0c9c77121eb66ae2 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index 5255978d1ddb4dd589fea8326d1aeb547bbb620c..1d6bd7f9b379124754ac0373b7e217eec9eb7551 100644 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/Project Repports/Diagram b/Project Repports/Diagram new file mode 100644 index 0000000000000000000000000000000000000000..6f0ca776096d54b1b3ea78c84f4e0a13d2b73430 --- /dev/null +++ b/Project Repports/Diagram @@ -0,0 +1,191 @@ +@startuml + +' Enum: ModelElement +enum ModelElement { + FIREFIGHTER + FIRE + CLOUD + ROAD + EMPTY + MOUNTAIN + FIRETRUCK + ROCKS +} + +' Class: Position +class Position { + - row: int + - column: int + + Position(row: int, column: int) + + getRow(): int + + getColumn(): int +} + +' Interface: Strategy +interface Strategy { + + update(): List<Position> + + getModelPositions(): List<Position> + + getFirePositions(): Set<Position> +} + +' Class: FireTruckMovementStrategy +class FireTruckMovementStrategy { + - targetStrategy: TargetStrategy + - fireTruckPositions: List<Position> + - firePositions: Set<Position> + - neighbors: Map<Position, List<Position>> + + FireTruckMovementStrategy(firefighterPositions: List<Position>, firePositions: Set<Position>, neighbors: Map<Position, List<Position>>) + + update(): List<Position> + + nextValidPosition(currentPosition: Position): Position + + extinguishNearbyFires(position: Position, modifiedPositions: List<Position>) + + extinguishAll(positions: List<Position>) +} + +' Class: SimpleFireSpreadStrategy +class SimpleFireSpreadStrategy { + - firePositions: Set<Position> + - neighbors: Map<Position, List<Position>> + - mountainPositions: Set<Position> + - roadPositions: Set<Position> + - rocksPositions: Set<Position> + - step: int + + SimpleFireSpreadStrategy(firePositions: Set<Position>, neighbors: Map<Position, List<Position>>, mountainPositions: Set<Position>, roadPositions: Set<Position>, rocksPositions: Set<Position>, step: int) + + update(): List<Position> + + spreadFire(firePosition: Position, newFirePositions: Set<Position>) + + canPropagateTo(newPosition: Position): boolean +} + +' Class: Initializer +class Initializer { + - columnCount: int + - rowCount: int + - initialFireCount: int + - initialFirefighterCount: int + - initialRoadCount: int + - initialCloudCount: int + - initialMountainCount: int + - initialFireTruckCount: int + - initialRocksCount: int + - positions: Position[][] + - neighbors: Map<Position, List<Position>> + - firePositions: Set<Position> + - firefighterPositions: List<Position> + - RoadPositions: List<Position> + - cloudPositions: List<Position> + - mountainsPositions: Set<Position> + - FireTruckPositions: List<Position> + - rocksPositions: Set<Position> + - randomGenerator: Random + + Initializer(columnCount: int, rowCount: int, initialFireCount: int, initialFirefighterCount: int, initialRoadCount: int, initialCloudCount: int, initialMountainCount: int, initialRocksCount: int, initialFireTruckCount: int) + + initializePositions(): void + + initializeNeighbors(): void + + initializeElements(): void + + addRandomPositions(targetCollection: Collection<Position>, count: int) +} + +' Class: NeighborManager +class NeighborManager { + - neighbors: Map<Position, List<Position>> + + NeighborManager(rowCount: int, columnCount: int) + + getNeighbors(): Map<Position, List<Position>> + + getAdjacentPositions(position: Position): List<Position> +} + +' Class: TargetStrategy +class TargetStrategy { + + calculateTarget(fireTruckPosition: Position, firePositions: Set<Position>): Position +} + +' Class: Board +class Board { + - positions: Position[][] + - modelElements: Map<Position, ModelElement> + + Board(rowCount: int, columnCount: int) + + setModelElement(position: Position, element: ModelElement): void + + getModelElement(position: Position): ModelElement +} + +' Class: BoardManager +class BoardManager { + - board: Board + - initializer: Initializer + + BoardManager(board: Board, initializer: Initializer) + + initializeBoard(): void + + updateBoard(): void +} + +' Class: CloudStrategy +class CloudStrategy { + - cloudPositions: Set<Position> + + CloudStrategy(cloudPositions: Set<Position>) + + updateCloud(): Set<Position> + + addCloudPosition(position: Position): void +} + +' Class: FirefighterBoard +class FirefighterBoard { + - firefighterPositions: List<Position> + + FirefighterBoard(firefighterPositions: List<Position>) + + updateFirefighterPositions(): void + + addFirefighter(position: Position): void +} + +' Class: FirefighterMovementStrategy +class FirefighterMovementStrategy { + - firefighterPositions: List<Position> + - neighbors: Map<Position, List<Position>> + + FirefighterMovementStrategy(firefighterPositions: List<Position>, neighbors: Map<Position, List<Position>>) + + update(): List<Position> + + nextValidPosition(currentPosition: Position): Position + + moveToNextPosition(): Position +} + +' Relationship: FireTruckMovementStrategy implements Strategy +FireTruckMovementStrategy -|> Strategy : implements + +' Relationship: SimpleFireSpreadStrategy implements Strategy +SimpleFireSpreadStrategy -|> Strategy : implements + +' Relationship: Initializer uses NeighborManager +Initializer --> NeighborManager : uses + +' Relationship: FireTruckMovementStrategy and SimpleFireSpreadStrategy depend on Position +FireTruckMovementStrategy --> Position : depends on +SimpleFireSpreadStrategy --> Position : depends on + +' Relationship: FireTruckMovementStrategy and SimpleFireSpreadStrategy depend on neighbors +FireTruckMovementStrategy --> Map : depends on +SimpleFireSpreadStrategy --> Map : depends on + +' Relationship: FireTruckMovementStrategy uses TargetStrategy +FireTruckMovementStrategy --> TargetStrategy : uses + +' Relationship: ModelElement is an enum +ModelElement ..> FireTruckMovementStrategy : used by +ModelElement ..> SimpleFireSpreadStrategy : used by + +' Relationship: Position used by Initializer for grid setup +Position --> Initializer : used by + +' Relationship: Position used by FireTruckMovementStrategy and SimpleFireSpreadStrategy +Position --> FireTruckMovementStrategy : used by +Position --> SimpleFireSpreadStrategy : used by + +' Relationship: Board is used by BoardManager +Board --> BoardManager : used by + +' Relationship: CloudStrategy uses Position +CloudStrategy --> Position : uses + +' Relationship: BoardManager uses Board and Initializer +BoardManager --> Board : uses +BoardManager --> Initializer : uses + +' Relationship: FirefighterMovementStrategy uses Position +FirefighterMovementStrategy --> Position : uses + +' Relationship: FirefighterMovementStrategy and FirefighterBoard use Board +FirefighterBoard --> Board : uses +FirefighterMovementStrategy --> Board : uses + +@enduml diff --git a/Project Repports/Diagram Projet Programation.pdf b/Project Repports/Diagram Projet Programation.pdf deleted file mode 100644 index 1b75234c19257ca2faa1c442f1bfae06db4a02cc..0000000000000000000000000000000000000000 Binary files a/Project Repports/Diagram Projet Programation.pdf and /dev/null differ diff --git a/Project Repports/Rapport2.md b/Project Repports/Rapport2.md index c38b2351e4d6e320f412112c45d7519806ff9331..186571a99cfce74e74582c65dba9396c15c34b4f 100644 --- a/Project Repports/Rapport2.md +++ b/Project Repports/Rapport2.md @@ -2,5 +2,5 @@ Dans ce TP nous avons ajouter deux classes SimpleFireFighterStrategy et SimpleFireSpreadStrategy qui implementent leurs Strategy respectivent De plus nous avons essayé de faire le FirefighterBoard qui soit compatible avec Controller nous avons ajouté de plus des getters dans util.Position - -on va finir le FirefighterBoard la semaine prochaine ainsi que implementer util.TargetStrategy dans notre code \ No newline at end of file + +Nous allons finir le FirefighterBoard la semaine prochaine ainsi que implementer util.TargetStrategy dans notre code \ No newline at end of file diff --git a/Project Repports/Rapport3.md b/Project Repports/Rapport3.md index b46572a04ab0fad5df0b4710f24bf32c9f80ae78..54a4e3da9025e6e9dca9842ec7a325a61e70d13c 100644 --- a/Project Repports/Rapport3.md +++ b/Project Repports/Rapport3.md @@ -8,6 +8,10 @@ pas ce passer. Avant la prochaine seance nous allons corriger le code en sorte que ça fonctionne correctement refactorisation totale du code -j'ai enlever les classes Manager et je les ai implementer dans les startegy de plus -j'ai ajouter une interface globale nomme Strategy et une classe Initializer -afin de reduire le code dans les autre classe et faciliter l'implementation de codes additionelle \ No newline at end of file +nous avions enlevé les classes Manager et je les ai implementer dans les startegy de plus +nous avions ajouté une interface globale nomme Strategy et une classe Initializer +afin de reduire le code dans les autre classe et faciliter l'implementation de codes additionelle + +Rami à ajouter les Roads et les firetrucks dans le code et il c'est assurer de leurs bon fonctionnement +Chadi a ajouter la trategy des nuages ainsi que les montagnes et les rocks +nous somme entrain de verifier que tout fonctionne comme il le faut \ No newline at end of file diff --git a/README.md b/README.md index 07b93ef8ffbfe4519227ec5b3281aa47c05b88d9..4977b12b235ce405c3c77c3015a9aa96d3ded5ea 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,69 @@ Project members : member 1 : Mansour Chadi -member 2 : Chahine Rami \ No newline at end of file +member 2 : Chahine Rami + + +Objectif du Projet + +Ce projet a pour objectif de refactoriser un code initial qui ne respectait pas les principes SOLID, afin de le rendre plus lisible, modulaire, et extensible. La refactorisation vise à diviser le code en plusieurs sous-parties bien définies, en respectant des concepts de conception logicielle modernes, notamment les principes SOLID. + +Par ailleurs, de nouvelles fonctionnalités ont été ajoutées au jeu, notamment : + + L'introduction d'éléments tels que des nuages, des rocailles, des routes et des montagnes. + L'ajout de pompiers équipés de motos pour une mobilité accrue. + +Approche Initiale et Révision du Plan + + Approche Initiale : + Lors de la première phase, nous avons introduit des classes Manager pour gérer les pompiers et les incendies. + Ces classes étaient accompagnées d'interfaces Strategy permettant d'implémenter différents types de mouvements et comportements. + Cependant, cette approche s'est révélée complexe et peu fonctionnelle, + en raison d'une mauvaise séparation des responsabilités et d'une gestion inefficace des dépendances. + + Nouvelle Approche : + Face à ces difficultés, nous avons opté pour une refonte complète du système. + Nous avons simplifié l'architecture en nous concentrant uniquement sur les stratégies de mouvements. + Cette approche, plus simple, s'est avérée non seulement fonctionnelle, mais aussi plus facile à modifier et à étendre. + +Avantages de la Nouvelle Architecture + +La nouvelle architecture a démontré son efficacité lors de l'ajout des nouvelles fonctionnalités : + + Modularité accrue : Chaque fonctionnalité est encapsulée dans des classes ou stratégies indépendantes. + Facilité de modification : L'ajout de nouveaux éléments comme les nuages, les rocailles, + ou les motos n'a pas nécessité de réécriture majeure du code existant. + Respect des principes SOLID : + Single Responsibility Principle : Chaque classe ou stratégie a une responsabilité unique et clairement définie. + Open/Closed Principle : Le système est ouvert à l'extension mais fermé à la modification. + Liskov Substitution Principle : Les stratégies implémentent des interfaces communes et peuvent être utilisées de manière interchangeable. + Interface Segregation Principle : Les interfaces sont petites et spécifiques aux besoins de chaque composant. + Dependency Inversion Principle : Les dépendances sont abstraites et injectées, ce qui réduit le couplage. + +Fonctionnalités Clés + +Voici un aperçu des fonctionnalités intégrées grâce à cette refactorisation : + + Stratégies de Propagation du Feu : + Différents types de terrains influencent la propagation des flammes : + Les montagnes bloquent complètement le feu. + Les rocailles ralentissent sa propagation, ne brûlant qu'à des intervalles précis. + Les routes empêchent la propagation. + + Gestion des Pompiers : + Les pompiers peuvent se déplacer rapidement grâce à des motos, permettant une intervention plus efficace. + Les stratégies de mouvement tiennent compte des obstacles comme les montagnes et les rocailles. + + Ajout d’éléments naturels : + Les nuages peuvent interagir avec le terrain et affecter les conditions du feu. + Les différents types de terrains apportent une dimension stratégique au jeu. + + Visualisation Améliorée : + Le système de rendu utilise une grille pour afficher clairement chaque élément (feu, pompiers, routes, etc.), + avec des couleurs spécifiques pour une meilleure lisibilité. + +Conclusion + +Cette refactorisation a permis de transformer un code monolithique et difficile à maintenir en un système modulaire et extensible. +Les bénéfices se sont manifestés lors de l'ajout rapide et efficace de nouvelles fonctionnalités. +En adoptant une architecture basée sur les stratégies et les principes SOLID, le projet est désormais mieux structuré, plus facile à comprendre et prêt pour des extensions futures. \ No newline at end of file diff --git a/build/classes/java/main/app/SimulatorApplication.class b/build/classes/java/main/app/SimulatorApplication.class index 3e04e3ad61ce4bc7716996607d7ef0c8de245fe9..64108db13ab8040948211250032367c6392ccdcb 100644 Binary files a/build/classes/java/main/app/SimulatorApplication.class and b/build/classes/java/main/app/SimulatorApplication.class differ diff --git a/build/classes/java/main/controller/Controller.class b/build/classes/java/main/controller/Controller.class index 1de3f5cc54f95ac002b8a057f15747eec7898cae..1f4f51d3c4da6dd5faadbc1331eafad5adb41878 100644 Binary files a/build/classes/java/main/controller/Controller.class and b/build/classes/java/main/controller/Controller.class differ diff --git a/build/classes/java/main/model/FirefighterBoard$1.class b/build/classes/java/main/model/FirefighterBoard$1.class index 36139e86884c256a348af7e1b2a13b5fa944c975..119af8394727bb7d71d86b6a356f890372fb769b 100644 Binary files a/build/classes/java/main/model/FirefighterBoard$1.class and b/build/classes/java/main/model/FirefighterBoard$1.class differ diff --git a/build/classes/java/main/model/FirefighterBoard.class b/build/classes/java/main/model/FirefighterBoard.class index 8cf7ed6fc58761fc264227b5206c3422d3e2f0e1..f61f42ca6ccdd9a05f2f36b96e3ac19a79295c29 100644 Binary files a/build/classes/java/main/model/FirefighterBoard.class and b/build/classes/java/main/model/FirefighterBoard.class differ diff --git a/build/classes/java/main/model/ModelElement.class b/build/classes/java/main/model/ModelElement.class index ab695532d616c8cf4fa9ac577236893340a8bc44..a754112236156144fdccdb51883328300f1874a3 100644 Binary files a/build/classes/java/main/model/ModelElement.class and b/build/classes/java/main/model/ModelElement.class differ diff --git a/build/classes/java/main/model/SimpleFireSpreadStrategy.class b/build/classes/java/main/model/SimpleFireSpreadStrategy.class index 595ad5f73d206af2527a6fdd05093fffdca17a2e..99f37d9599a845f4357686ac641025aef33c3430 100644 Binary files a/build/classes/java/main/model/SimpleFireSpreadStrategy.class and b/build/classes/java/main/model/SimpleFireSpreadStrategy.class differ diff --git a/build/classes/java/main/view/FirefighterGrid.class b/build/classes/java/main/view/FirefighterGrid.class index 18e46ef5be06988a93fa104fac2993de3f3c5349..621f52487062cf2afe1a5bf3435cf8b098e69dcc 100644 Binary files a/build/classes/java/main/view/FirefighterGrid.class and b/build/classes/java/main/view/FirefighterGrid.class differ diff --git a/build/classes/java/main/view/ViewElement.class b/build/classes/java/main/view/ViewElement.class index 6e0ba4cb9d010f7ec89661d33c7f27a0eeba7153..9e776bc14ee8cfc60beaf454877354f5567ee0ca 100644 Binary files a/build/classes/java/main/view/ViewElement.class and b/build/classes/java/main/view/ViewElement.class differ diff --git a/build/classes/java/test/model/FirefighterBoardTest.class b/build/classes/java/test/model/FirefighterBoardTest.class index a0d71f0e7a0e444e0331454984cd677da7957fb9..700fb0a6e745978391eecb01f5d4ea423662260d 100644 Binary files a/build/classes/java/test/model/FirefighterBoardTest.class and b/build/classes/java/test/model/FirefighterBoardTest.class differ diff --git a/build/libs/firefighter-all.jar b/build/libs/firefighter-all.jar index 4d96d916601c71cff5491caa76660f7f282a2ed4..619374e47ddcafe0763e346a06e42f6272b0da1b 100644 Binary files a/build/libs/firefighter-all.jar and b/build/libs/firefighter-all.jar differ diff --git a/build/libs/firefighter.jar b/build/libs/firefighter.jar index d8dab65624dde65d70f5b73fdf1561585519888a..af06c4dfce194c8db370026c2252a79fff7393a4 100644 Binary files a/build/libs/firefighter.jar and b/build/libs/firefighter.jar differ diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index 48e50bc390ac5092c726fc747b9c7671c94c9b48..a076ff2fe10d371efcb37f1bf51bb59b15becc60 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java index 12878f7c6f4c083a7a742c397ecc44f355e33023..8900e4bd34e6c066eeb8bce3f24a9e03c274bf0e 100644 --- a/src/main/java/app/SimulatorApplication.java +++ b/src/main/java/app/SimulatorApplication.java @@ -19,6 +19,11 @@ public class SimulatorApplication extends javafx.application.Application { private static final int BOX_HEIGHT = 30; public static final int INITIAL_FIRE_COUNT = 5; public static final int INITIAL_FIREFIGHTER_COUNT = 4; + public static final int INITIAL_ROAD_COUNT = 10; + public static final int INITIAL_CLOUD_COUNT = 3; + public static final int INITIAL_MOUTAIN_COUNT = 5; + public static final int INITIAL_FIRE_TRUCK_COUNT = 2; + public static final int INITIAL_ROCKS_COUNT = 3; private Stage primaryStage; private Parent view; @@ -46,7 +51,7 @@ public class SimulatorApplication extends javafx.application.Application { Controller controller = loader.getController(); controller.initialize(BOX_WIDTH, BOX_HEIGHT, COLUMN_COUNT, ROW_COUNT, - INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT); + INITIAL_FIRE_COUNT, INITIAL_FIREFIGHTER_COUNT, INITIAL_ROAD_COUNT,INITIAL_CLOUD_COUNT, INITIAL_MOUTAIN_COUNT, INITIAL_ROCKS_COUNT, INITIAL_FIRE_TRUCK_COUNT); } private void showScene() { diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java index fa5224d2c629e1966f2d405e9d1300652eddff9d..b4d158c58e47569f10a25d9bec15741d10259110 100644 --- a/src/main/java/controller/Controller.java +++ b/src/main/java/controller/Controller.java @@ -33,9 +33,9 @@ public class Controller { @FXML private FirefighterGrid grid; - public void initialize(int boxWidth, int boxHeight, int columns, int rows, int fireCount, int firefighterCount) { + public void initialize(int boxWidth, int boxHeight, int columns, int rows, int fireCount, int firefighterCount, int initialRoadCount,int initialcloudCount, int initialMountainsCount, int initialRocksCount, int initialFiretruckCount) { // Initialize the simulation board and connect it to the grid - board = new FirefighterBoard(columns, rows, fireCount, firefighterCount); + board = new FirefighterBoard(columns, rows, fireCount, firefighterCount, initialRoadCount,initialcloudCount, initialMountainsCount, initialRocksCount, initialFiretruckCount); grid.initialize(columns, rows, boxWidth, boxHeight, board); // Initialize timeline for automatic progression diff --git a/src/main/java/model/CloudStrategy.java b/src/main/java/model/CloudStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..49ee8acedc2bd8e1a32a69fccf21330f39dffc6b --- /dev/null +++ b/src/main/java/model/CloudStrategy.java @@ -0,0 +1,66 @@ +package model; + +import util.Position; + +import java.util.*; + +public class CloudStrategy implements Strategy { + private List<Position> cloudPositions; + private final Set<Position> firePositions; + private final Map<Position, List<Position>> neighbors; + private final Random random = new Random(); + private final int maxRows; + private final int maxCols; + + public CloudStrategy(List<Position> cloudPositions, Set<Position> firePositions, Map<Position, List<Position>> neighbors, int maxRows, int maxCols) { + + this.cloudPositions = cloudPositions; + this.firePositions = firePositions; + this.neighbors = neighbors; + this.maxRows = maxRows; + this.maxCols = maxCols; + } + + @Override + public List<Position> update() { + List<Position> modifiedCloudPositions = new ArrayList<>(); + List<Position> newCloudPositions = new ArrayList<>(); + + for (Position cloudPosition : cloudPositions) { + Position newCloudPosition = randomPos(cloudPosition); + newCloudPositions.add(newCloudPosition); + modifiedCloudPositions.add(cloudPosition); + modifiedCloudPositions.add(newCloudPosition); + extinguishFiures(newCloudPosition, modifiedCloudPositions); + } + cloudPositions = newCloudPositions; + return modifiedCloudPositions; + } + + @Override + public List<Position> getModelPositions() { + return cloudPositions; + } + + @Override + public Set<Position> getFirePositions() { + return firePositions; + } + private void extinguishFiures(Position position, List<Position> modifiedCloudPositions) { + List<Position> positions = new ArrayList<>(neighbors.getOrDefault(position, Collections.emptyList())); + positions.add(position); + List<Position> firePos = positions.stream().filter(firePositions :: contains).toList(); + firePositions.removeAll(firePos); + modifiedCloudPositions.addAll(firePos); + } + private Position randomPos(Position cloudPosition) { + int row = random.nextInt(3)-1; + int col = random.nextInt(3)-1; + int newRow = cloudPosition.getRow() + row; + int newCol = cloudPosition.getCol() + col; + if (newRow>=0 && newRow<maxRows && newCol>=0 && newCol<maxCols) { + return new Position(newRow, newCol); + } + return cloudPosition; + } +} diff --git a/src/main/java/model/FireTruckmovmentStrategy.java b/src/main/java/model/FireTruckmovmentStrategy.java new file mode 100644 index 0000000000000000000000000000000000000000..3f8a9f0ca9010d954c5f0301650b2fd31329d44f --- /dev/null +++ b/src/main/java/model/FireTruckmovmentStrategy.java @@ -0,0 +1,68 @@ +package model; + +import util.Position; +import util.TargetStrategy; + +import java.util.*; + +public class FireTruckmovmentStrategy implements Strategy { + private final TargetStrategy targetStrategy = new TargetStrategy(); + private List<Position> fireTruckPositions; + private final Set<Position> firePositions; + private final Map<Position, List<Position>> neighbors; + + public FireTruckmovmentStrategy(List<Position> firefighterPositions, Set<Position> firePositions, Map<Position, List<Position>> neighbors) { + this.fireTruckPositions = firefighterPositions; + this.firePositions = firePositions; + this.neighbors = neighbors; + } + + @Override + public List<Position> update() { + List<Position> modifiedPositions = new ArrayList<>(); + List<Position> newFirefTruckPositions = new ArrayList<>(); + + for (Position fireTruckPosition : fireTruckPositions) { + Position firstStep = nextValidPosition(fireTruckPosition ); // 1er etape + extinguishNearbyFires(firstStep, modifiedPositions); + + Position secondStep = nextValidPosition(firstStep); // 2eme etape + extinguishNearbyFires(secondStep, modifiedPositions); + + newFirefTruckPositions.add(secondStep); + modifiedPositions.add(fireTruckPosition ); + modifiedPositions.add(firstStep); + modifiedPositions.add(secondStep); + } + + fireTruckPositions = newFirefTruckPositions; + return modifiedPositions; + } + + private Position nextValidPosition(Position currentPosition) { + return targetStrategy.neighborClosestToFire(currentPosition, firePositions, neighbors); + } + + private void extinguishNearbyFires(Position position, List<Position> modifiedPositions) { + List<Position> firesToExtinguish = new ArrayList<>(neighbors.getOrDefault(position, List.of())); + firesToExtinguish.add(position); + firesToExtinguish.removeIf(pos -> !firePositions.contains(pos)); + + extinguishAll(firesToExtinguish); + modifiedPositions.addAll(firesToExtinguish); + } + + private void extinguishAll(List<Position> positions) { + firePositions.removeAll(positions); + } + + @Override + public List<Position> getModelPositions() { + return fireTruckPositions; + } + + @Override + public Set<Position> getFirePositions() { + return firePositions; + } +} \ No newline at end of file diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java index 5181cb6ec19926bff50a1d45432c038965e97f72..6ab8b8facd4c41c768ae89cc7a7a3e408653d272 100644 --- a/src/main/java/model/FirefighterBoard.java +++ b/src/main/java/model/FirefighterBoard.java @@ -4,30 +4,53 @@ import util.Position; import javafx.util.Pair; 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; + private final int initialRoadCount; + private final int initialcloudCount; + private final int initialmountainsCount; + private final int initialFireTruckCount; + private final int initialrocksCount; private List<Position> firefighterPositions; private Set<Position> firePositions; + private final Set<Position> roadPositions; private final Map<Position, List<Position>> neighbors; private final Position[][] positions; + private List<Position> cloudPositions; + private Set<Position> moutainsPositions; + private Set<Position> rocksPositions; + private List<Position> fireTruckPositions; private int step = 0; // Constructor for FirefighterBoard - public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { + public FirefighterBoard(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount, int initialRoadCount, + int initialcloudCount, int initialmountainsCount, int initialrocksCount,int initialFireTruckCount ) { this.columnCount = columnCount; this.rowCount = rowCount; this.initialFireCount = initialFireCount; this.initialFirefighterCount = initialFirefighterCount; + this.initialRoadCount = initialRoadCount; + this.initialcloudCount = initialcloudCount; + this.initialmountainsCount = initialmountainsCount; + this.initialrocksCount = initialrocksCount; + this.initialFireTruckCount = initialFireTruckCount; this.positions = new Position[rowCount][columnCount]; this.firefighterPositions = new ArrayList<>(); this.firePositions = new HashSet<>(); this.neighbors = new HashMap<>(); + this.cloudPositions = new ArrayList<>(); + this.moutainsPositions = new HashSet<>(); + this.roadPositions = new HashSet<>(); + this.rocksPositions = new HashSet<>(); + this.fireTruckPositions = new ArrayList<>(); initializeBoard(); } @@ -44,6 +67,27 @@ public class FirefighterBoard implements Board<List<ModelElement>> { for (int i = 0; i < initialFirefighterCount; i++) { firefighterPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); } + // Initialize road positions + for (int i = 0; i < initialRoadCount; i++) { + roadPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); + } + // Initialize road positions + for (int i = 0; i < initialcloudCount; i++) { + cloudPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); + } + // Initialize Moutains Positions + for (int i = 0; i < initialmountainsCount; i++) { + moutainsPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); + } + // Initialize rocks positions + for (int i = 0; i < initialrocksCount; i++) { + rocksPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); + } + // Initialize FireTruck Positions + for (int i = 0; i < initialFireTruckCount; i++) { + fireTruckPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); + } + // Initialize neighbors map for (int row = 0; row < rowCount; row++) { @@ -78,7 +122,32 @@ public class FirefighterBoard implements Board<List<ModelElement>> { result.add(ModelElement.FIREFIGHTER); } } - default -> { + case CLOUD -> { + if (cloudPositions.contains(position)) { + result.add(ModelElement.CLOUD); + } + } + case ROAD -> { + if (roadPositions.contains(position)) { + result.add(ModelElement.ROAD); + } + } + case MOUTAIN -> { + if (moutainsPositions.contains(position)) { + result.add(ModelElement.MOUTAIN); + } + } + case ROCKS -> { + if (rocksPositions.contains(position)) { + result.add(ModelElement.ROCKS); + } + } + case FIRETRUCK -> { + if (fireTruckPositions.contains(position)) { + result.add(ModelElement.FIRETRUCK); + } + } + default ->{ } } } @@ -103,21 +172,39 @@ public class FirefighterBoard implements Board<List<ModelElement>> { @Override public void reset() { step = 0; - firefighterPositions.clear(); - firePositions.clear(); + Initializer initializer = new Initializer(columnCount,rowCount,initialFireCount,initialFirefighterCount, + initialRoadCount,initialcloudCount, initialmountainsCount, initialFireTruckCount,initialrocksCount); + + resetPos(firePositions,initializer.getFirePositions()); + resetPos(firefighterPositions,initializer.getFirefighterPositions()); + resetPos(cloudPositions,initializer.getCloudPositions()); + resetPos(moutainsPositions,initializer.getMountainsPositions()); + resetPos(roadPositions,initializer.getRoadPositions()); + resetPos(rocksPositions,initializer.getRocksPositions()); + resetPos(fireTruckPositions,initializer.getFireTruckPositions()); + + neighbors.clear(); + neighbors.putAll(initializer.getNeighbors()); initializeBoard(); } + private <S> void resetPos(Collection<S> currentPositions, Collection<S> newPositions) { + currentPositions.clear(); + currentPositions.addAll(newPositions); + } @Override public void setState(List<ModelElement> state, Position position) { firePositions.remove(position); firefighterPositions.remove(position); + fireTruckPositions.remove(position); for (ModelElement element : state) { switch (element) { case FIRE -> firePositions.add(position); case FIREFIGHTER -> firefighterPositions.add(position); + case CLOUD -> cloudPositions.add(position); + case FIRETRUCK -> fireTruckPositions.add(position); } } } @@ -125,15 +212,19 @@ public class FirefighterBoard implements Board<List<ModelElement>> { @Override public List<Position> updateToNextGeneration() { List<ModelElement> elements = List.of( - ModelElement.FIRE, - ModelElement.FIREFIGHTER + ModelElement.FIRE, + ModelElement.FIREFIGHTER, + ModelElement.CLOUD, + ModelElement.FIRETRUCK ); List<Position> modifiedPositions = new ArrayList<>(); for(ModelElement element : elements) { Strategy strategy = switch(element) { - case FIRE -> new SimpleFireSpreadStrategy(firePositions, neighbors,step); + case FIRE -> new SimpleFireSpreadStrategy(firePositions, neighbors,moutainsPositions,roadPositions, rocksPositions,step); case FIREFIGHTER -> new FirefighterMovementStrategy(firefighterPositions,firePositions,neighbors); + case CLOUD -> new CloudStrategy(cloudPositions,firePositions,neighbors,rowCount,columnCount); + case FIRETRUCK -> new FireTruckmovmentStrategy(fireTruckPositions,firePositions,neighbors); default -> throw new IllegalStateException("Type de modèle inconnu : " + element); }; modifiedPositions.addAll(strategy.update()); @@ -141,44 +232,40 @@ public class FirefighterBoard implements Board<List<ModelElement>> { switch (element) { case FIRE -> firePositions = strategy.getFirePositions(); case FIREFIGHTER -> firefighterPositions = strategy.getModelPositions(); + case CLOUD -> cloudPositions = strategy.getModelPositions(); + case FIRETRUCK -> fireTruckPositions = strategy.getModelPositions(); } } step++; return modifiedPositions; } - private Set<Position> spreadFire() { - Set<Position> newFirePositions = new HashSet<>(); - for (Position firePosition : firePositions) { - newFirePositions.addAll(neighbors.get(firePosition)); // Spread fire to neighbors - } - return newFirePositions; - } - - private void extinguishNearbyFire(List<Position> modifiedPositions) { - for (Position firefighterPosition : firefighterPositions) { - List<Position> nearbyFires = neighbors.get(firefighterPosition); - for (Position neighbor : nearbyFires) { - if (firePositions.contains(neighbor)) { - firePositions.remove(neighbor); // Extinguish fire in neighboring positions - modifiedPositions.add(neighbor); - } - } - } - } - public List<Pair<Position, ModelElement>> getUpdatedElements() { List<Pair<Position, ModelElement>> updatedElements = new ArrayList<>(); - + System.out.println(initialFireCount); // Add fire positions for (Position firePosition : firePositions) { updatedElements.add(new Pair<>(firePosition, ModelElement.FIRE)); } - // Add firefighter positions for (Position firefighterPosition : firefighterPositions) { updatedElements.add(new Pair<>(firefighterPosition, ModelElement.FIREFIGHTER)); } + for (Position cloudPosition : cloudPositions) { + updatedElements.add(new Pair<>(cloudPosition, ModelElement.CLOUD)); + } + for (Position roadPosition : roadPositions) { + updatedElements.add(new Pair<>(roadPosition, ModelElement.ROAD)); + } + for (Position moutainPosition : moutainsPositions){ + updatedElements.add(new Pair<>(moutainPosition, ModelElement.MOUTAIN)); + } + for (Position FireTruckPosition : fireTruckPositions){ + updatedElements.add(new Pair<>(FireTruckPosition, ModelElement.FIRETRUCK)); + } + for (Position rockPosition : rocksPositions){ + updatedElements.add(new Pair<>(rockPosition,ModelElement.ROCKS)); + } return updatedElements; } @@ -193,149 +280,3 @@ public class FirefighterBoard implements Board<List<ModelElement>> { -/* -import util.*; - -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; - private final TargetStrategy targetStrategy = new TargetStrategy(); - private List<Position> firefighterPositions; - private Set<Position> firePositions; - 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; - 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() { - 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()); - } - - 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 (Position firefighterPosition : firefighterPositions) - if (firefighterPosition.equals(position)) - result.add(ModelElement.FIREFIGHTER); - if (firePositions.contains(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; - } - - private List<Position> updateFires() { - List<Position> modifiedPositions = new ArrayList<>(); - if (step % 2 == 0) { - List<Position> newFirePositions = new ArrayList<>(); - for (Position fire : firePositions) { - newFirePositions.addAll(neighbors.get(fire)); - } - firePositions.addAll(newFirePositions); - modifiedPositions.addAll(newFirePositions); - } - return modifiedPositions; - - } - - @Override - public int stepNumber() { - return step; - } - - private List<Position> updateFirefighters() { - List<Position> modifiedPosition = new ArrayList<>(); - List<Position> firefighterNewPositions = new ArrayList<>(); - for (Position firefighterPosition : firefighterPositions) { - Position newFirefighterPosition = - targetStrategy.neighborClosestToFire(firefighterPosition, - firePositions, neighbors); - firefighterNewPositions.add(newFirefighterPosition); - extinguish(newFirefighterPosition); - modifiedPosition.add(firefighterPosition); - modifiedPosition.add(newFirefighterPosition); - List<Position> neighborFirePositions = neighbors.get(newFirefighterPosition).stream() - .filter(firePositions::contains).toList(); - for (Position firePosition : neighborFirePositions) - extinguish(firePosition); - modifiedPosition.addAll(neighborFirePositions); - } - firefighterPositions = firefighterNewPositions; - return modifiedPosition; - } - - @Override - public void reset() { - step = 0; - initializeElements(); - } - - private void extinguish(Position position) { - firePositions.remove(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); - } - } - } -}*/ \ No newline at end of file diff --git a/src/main/java/model/FirefighterMovementStrategy.java b/src/main/java/model/FirefighterMovementStrategy.java index b8c4f3b5131548522bd513ba2c45e4dbad80524d..c6ca54c774f0671a9bf05cabdb410a34b5df518a 100644 --- a/src/main/java/model/FirefighterMovementStrategy.java +++ b/src/main/java/model/FirefighterMovementStrategy.java @@ -19,7 +19,7 @@ public class FirefighterMovementStrategy implements Strategy { @Override public List<Position> update() { -List<Position> modifiedPositions = new ArrayList<>(); + List<Position> modifiedPositions = new ArrayList<>(); List<Position> newFirefighterPositions = new ArrayList<>(); for (Position firefighterPosition : firefighterPositions) { diff --git a/src/main/java/model/Initializer.java b/src/main/java/model/Initializer.java index 373eb05ba57e27989095c591c562e7129b132491..38d44f464a6be37e5a98670c3e3565ce3429e601 100644 --- a/src/main/java/model/Initializer.java +++ b/src/main/java/model/Initializer.java @@ -4,34 +4,57 @@ import util.Position; import java.util.*; +import static app.SimulatorApplication.*; + public class Initializer { private final int columnCount; private final int rowCount; private final int initialFireCount; private final int initialFirefighterCount; + private final int initialRoadCount; + private final int initialcloudCount; + private final int initialMoutainCount; + private final int initialFireTruckCount; + private final int initialRocksCount; + private final Position[][] positions; private final Map<Position, List<Position>> neighbors; + private List<Position> RoadPositions; private final List<Position> firefighterPositions; private final Set<Position> firePositions; + private final List<Position> cloudPositions; + private final Set<Position> mountainsPositions; + private final List<Position> FireTruckPositions; + private final Set<Position> rocksPositions; private int step = 0; private final Random randomGenerator = new Random(); - public Initializer(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount) { + + public Initializer(int columnCount, int rowCount, int initialFireCount, int initialFirefighterCount, int initialRoadCount, + int initialcloudCount, int initialMoutainCount, int initialRocksCount,int initialFireTruckCount) { this.columnCount = columnCount; this.rowCount = rowCount; this.initialFireCount = initialFireCount; this.initialFirefighterCount = initialFirefighterCount; + this.initialRoadCount = initialRoadCount; + this.initialcloudCount = initialcloudCount; + this.initialMoutainCount = initialMoutainCount; + this.initialRocksCount = initialRocksCount; + this.initialFireTruckCount = initialFireTruckCount; this.positions = new Position[rowCount][columnCount]; this.neighbors = new HashMap<>(); this.firePositions = new HashSet<>(); this.firefighterPositions = new ArrayList<>(); + this.RoadPositions = new ArrayList<>(); + this.cloudPositions = new ArrayList<>(); + this.mountainsPositions = new HashSet<>(); + this.FireTruckPositions = new ArrayList<>(); + this.rocksPositions = new HashSet<>(); + - initializePositions(); - initializeNeighbors(); - initializeElements(); } private void initializePositions() { for (int row = 0; row < rowCount; row++) { @@ -53,6 +76,13 @@ public class Initializer { } } private void initializeElements() { + initializeFirePositions(); + initializeFirefighters(); + initializeRoadPositions(); + initializeCloudsPositions(); + initializeMoutainsPositions(); + initializeFireTruckPositions(); + initializeRocksPositions(); } private void initializeFirePositions() { @@ -61,6 +91,18 @@ public class Initializer { private void initializeFirefighters() { addRandomPositions(firefighterPositions, initialFirefighterCount); } + private void initializeRoadPositions() { + addRandomPositions(RoadPositions, initialRoadCount);} + private void initializeCloudsPositions() { + addRandomPositions(cloudPositions, initialcloudCount); + } + private void initializeFireTruckPositions() { + addRandomPositions(FireTruckPositions, initialFireTruckCount); + } + + private void initializeMoutainsPositions() {addRandomPositions(mountainsPositions, initialMoutainCount);} + private void initializeRocksPositions() {addRandomPositions(rocksPositions, initialRocksCount);} + private void addRandomPositions(Collection<Position> targetCollection, int count) { while (targetCollection.size() < count) { @@ -108,6 +150,21 @@ public class Initializer { public Set<Position> getFirePositions() { return firePositions; } + public List<Position> getRoadPositions() { + return RoadPositions; + } + public List<Position> getCloudPositions() { + return cloudPositions; + } + public Set<Position> getMountainsPositions() { + return mountainsPositions; + } + public List<Position> getFireTruckPositions() { + return FireTruckPositions; + } + public Set<Position> getRocksPositions() { + return rocksPositions; + } public int getStep() {return step;} } diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index 5212cc5dc358e893318e4c01fb2926782f07b496..4fec322be591854f3bc25fe18d457b98fb9e4781 100644 --- a/src/main/java/model/ModelElement.java +++ b/src/main/java/model/ModelElement.java @@ -2,7 +2,7 @@ package model; public enum ModelElement { - FIREFIGHTER("blue"), FIRE("red"); + FIREFIGHTER("blue"), FIRE("red"), CLOUD("darkgrey"),ROAD("grey"),EMPTY("white"), MOUTAIN("brown"),FIRETRUCK("orange"),ROCKS("lightBrown"); private final String color; diff --git a/src/main/java/model/SimpleFireSpreadStrategy.java b/src/main/java/model/SimpleFireSpreadStrategy.java index b8f9e863c81fd4dc39c42301da89345524b2d43d..84e2c39aa5c3e8bc7b07b7526c02466237f1c8d5 100644 --- a/src/main/java/model/SimpleFireSpreadStrategy.java +++ b/src/main/java/model/SimpleFireSpreadStrategy.java @@ -6,11 +6,17 @@ import java.util.*; public class SimpleFireSpreadStrategy implements Strategy { private final Set<Position> firePositions; private final Map<Position, List<Position>> neighbors; + private final Set<Position> mountainPositions; + private final Set<Position> roadPositions; + private final Set<Position> rocksPositions; private final int step; - public SimpleFireSpreadStrategy(Set<Position> firePositions, Map<Position, List<Position>> neighbors, int step) { + public SimpleFireSpreadStrategy(Set<Position> firePositions, Map<Position, List<Position>> neighbors,Set<Position> moutainsPositions,Set<Position> roadPositions,Set<Position> rocksPositions, int step) { this.firePositions = firePositions; this.neighbors = neighbors; + this.mountainPositions = moutainsPositions; + this.roadPositions = roadPositions; + this.rocksPositions = rocksPositions; this.step = step; } @@ -37,7 +43,13 @@ public class SimpleFireSpreadStrategy implements Strategy { } } } - private boolean canPropagateTo(Position firePosition) { + private boolean canPropagateTo(Position newPosition) { + if(mountainPositions.contains(newPosition) || roadPositions.contains(newPosition)){ + return false; + } + if (rocksPositions.contains(newPosition)){ + return step % 4 ==0; + } return true; } diff --git a/src/main/java/view/FirefighterGrid.java b/src/main/java/view/FirefighterGrid.java index ab926abfa39a23b8fdf3fb818e03f25bd1f78c53..6eff12e52fa24c5808f8d5a00252b7c24523c14c 100644 --- a/src/main/java/view/FirefighterGrid.java +++ b/src/main/java/view/FirefighterGrid.java @@ -23,41 +23,45 @@ public class FirefighterGrid extends Canvas { this.boxWidth = boxWidth; this.boxHeight = boxHeight; this.board = board; - setWidth(columns * boxWidth); // Set canvas width based on grid size - setHeight(rows * boxHeight); // Set canvas height based on grid size + setWidth(columns * boxWidth); + setHeight(rows * boxHeight); } - // Repaint the grid and all elements (fire and firefighter) public void repaint() { - if (board == null) return; // Exit if board is not set + if (board == null) return; GraphicsContext gc = getGraphicsContext2D(); - gc.clearRect(0, 0, getWidth(), getHeight()); // Clear the canvas before drawing + gc.clearRect(0, 0, getWidth(), getHeight()); - // Iterate over the list of updated elements (positions and elements like fire or firefighter) for (Pair<Position, ModelElement> pair : board.getUpdatedElements()) { Position position = pair.getKey(); // Get the Position from the Pair ModelElement element = pair.getValue(); // Get the ModelElement (either FIRE or FIREFIGHTER) - // Set the color based on the element type if (element == ModelElement.FIRE) { gc.setFill(Color.RED); // Fire is red - } else if (element == ModelElement.FIREFIGHTER) { + }else if (element == ModelElement.FIREFIGHTER) { gc.setFill(Color.BLUE); // Firefighter is blue + }else if (element== ModelElement.ROAD){ + gc.setFill(Color.WHITE); + }else if (element == ModelElement.CLOUD) { + gc.setFill(Color.YELLOW); + }else if (element == ModelElement.FIRETRUCK) { + gc.setFill(Color.ORANGE); + }else if (element == ModelElement.MOUTAIN) { + gc.setFill(Color.GREEN); + } else if (element == ModelElement.ROCKS) { + gc.setFill(Color.LIGHTSKYBLUE); } else { gc.setFill(Color.WHITE); // Empty space is white } - // Draw the element on the grid at the appropriate position gc.fillRect(position.getCol() * boxWidth, position.getRow() * boxHeight, boxWidth, boxHeight); gc.setStroke(Color.LIGHTGRAY); // Grid border color gc.strokeRect(position.getCol() * boxWidth, position.getRow() * boxHeight, boxWidth, boxHeight); } - // Optionally, draw the grid lines on top of the elements drawGridLines(gc); } - // Helper method to draw the grid lines private void drawGridLines(GraphicsContext gc) { gc.setStroke(Color.GRAY); for (int col = 0; col < columns; col++) { @@ -67,4 +71,12 @@ public class FirefighterGrid extends Canvas { gc.strokeLine(0, row * boxHeight, getWidth(), row * boxHeight); // Horizontal lines } } + + public int getColumns() { + return columns; + } + + public int getRows() { + return rows; + } } diff --git a/src/main/java/view/ViewElement.java b/src/main/java/view/ViewElement.java index f0a7922c36e72b5c7419e01f27d5845f770e9b9e..384dd61254e15b4f85a2edbc534387f0f2882f15 100644 --- a/src/main/java/view/ViewElement.java +++ b/src/main/java/view/ViewElement.java @@ -3,7 +3,7 @@ package view; import javafx.scene.paint.Color; public enum ViewElement { - FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE); + ROAD(Color.GRAY), FIREFIGHTER(Color.BLUE), FIRE(Color.RED), EMPTY(Color.WHITE),CLAUD(Color.YELLOW),FIRETRUCK(Color.ORANGE),ROCKS(Color.LIGHTSKYBLUE); final Color color; diff --git a/src/test/java/model/FirefighterBoardTest.java b/src/test/java/model/FirefighterBoardTest.java index 25cc8dbca8acea698879df68a5006a179f281ecc..a9fcc623d6bf20f9e15781f2e22b79451b4c6be2 100644 --- a/src/test/java/model/FirefighterBoardTest.java +++ b/src/test/java/model/FirefighterBoardTest.java @@ -10,17 +10,17 @@ import static org.assertj.core.api.Assertions.*; public class FirefighterBoardTest { @Test void testColumnCount(){ - Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3); + Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3,10,5,3,3,3); assertThat(board.columnCount()).isEqualTo(20); } @Test void testRowCount(){ - Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3); + Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3,10,5,3,3,3); assertThat(board.rowCount()).isEqualTo(10); } @Test void testStepNumber(){ - Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3); + Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 1, 3,10,5,3,3,3); for(int index = 0; index < 10; index++){ assertThat(board.stepNumber()).isEqualTo(index); board.updateToNextGeneration(); @@ -29,7 +29,7 @@ public class FirefighterBoardTest { } @Test void testGetState_afterSet(){ - Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 0, 0); + Board<List<ModelElement>> board = new FirefighterBoard(20, 10, 0, 0,0,0,0,0,0); Position position = new Position(1,2); assertThat(board.getState(position)).isEmpty(); board.setState(List.of(ModelElement.FIRE), position); diff --git a/src/test/java/view/FirefighterGridTest.java b/src/test/java/view/FirefighterGridTest.java index 4b45ebdca3b936b42c2b322b1294488341d180bb..68b6211ff9a6972e62a40a3498489ca3277d39fb 100644 --- a/src/test/java/view/FirefighterGridTest.java +++ b/src/test/java/view/FirefighterGridTest.java @@ -7,14 +7,14 @@ import static org.assertj.core.api.Assertions.assertThat; public class FirefighterGridTest { @Test void testColumnCount(){ - Grid<ViewElement> grid = new FirefighterGrid(); - grid.setDimensions(20,10,10,10); - assertThat(grid.columnCount()).isEqualTo(20); + FirefighterGrid grid = new FirefighterGrid(); + grid.initialize(20,10,10,10,null); + assertThat(grid.getColumns()).isEqualTo(20); } @Test void testRowCount(){ - Grid<ViewElement> grid = new FirefighterGrid(); - grid.setDimensions(20,10,10,10); - assertThat(grid.rowCount()).isEqualTo(10); + FirefighterGrid grid = new FirefighterGrid(); + grid.initialize(20,10,10,10,null); + assertThat(grid.getRows()).isEqualTo(10); } }