From 9a68c04f9ee53ab6b4a2c346ab8fb46812ed0018 Mon Sep 17 00:00:00 2001 From: badrr <badr.radellah@etu.univ-amu.fr> Date: Mon, 18 Nov 2024 21:39:52 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20du=20code=20initial=20du=20mod=C3=A8le?= =?UTF-8?q?=20Firefighter=20avec=20ses=20composants=20principaux=20(Board,?= =?UTF-8?q?=20Cloud,=20Fire,=20Firefighter,=20MotorizedFirefighter,=20etc.?= =?UTF-8?q?),=20ainsi=20que=20des=20classes=20utilitaires=20et=20des=20int?= =?UTF-8?q?erfaces=20pour=20la=20vue=20(Grid=20et=20FirefighterGrid).=20Le?= =?UTF-8?q?=20code=20n=C3=A9cessite=20encore=20des=20ajustements=20et=20de?= =?UTF-8?q?s=20am=C3=A9liorations=20pour=20=C3=AAtre=20compl=C3=A8tement?= =?UTF-8?q?=20fonctionnel.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .gradle/8.10.2/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .gradle/8.8/checksums/checksums.lock | Bin 17 -> 0 bytes .../8.8/dependencies-accessors/gc.properties | 0 .../8.8/executionHistory/executionHistory.bin | Bin 19652 -> 0 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 0 bytes .gradle/8.8/fileChanges/last-build.bin | Bin 1 -> 0 bytes .gradle/8.8/fileHashes/fileHashes.bin | Bin 18697 -> 0 bytes .gradle/8.8/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .gradle/8.8/gc.properties | 0 .../buildOutputCleanup.lock | Bin 17 -> 17 bytes src/main/java/model/Cloud.java | 46 ++++++++++++++++ src/main/java/model/Fire.java | 14 +++-- src/main/java/model/Firefighter.java | 46 ++++++++++++---- src/main/java/model/FirefighterBoard.java | 49 ++++++++++++++++-- src/main/java/model/ModelElement.java | 2 +- src/main/java/model/MotorizedFirefighter.java | 41 +++++++++++++++ src/main/java/util/Position.java | 44 +++++++++++++++- src/main/java/util/TargetStrategy.java | 48 +++++++++++------ 19 files changed, 256 insertions(+), 34 deletions(-) delete mode 100644 .gradle/8.8/checksums/checksums.lock delete mode 100644 .gradle/8.8/dependencies-accessors/gc.properties delete mode 100644 .gradle/8.8/executionHistory/executionHistory.bin delete mode 100644 .gradle/8.8/executionHistory/executionHistory.lock delete mode 100644 .gradle/8.8/fileChanges/last-build.bin delete mode 100644 .gradle/8.8/fileHashes/fileHashes.bin delete mode 100644 .gradle/8.8/fileHashes/fileHashes.lock delete mode 100644 .gradle/8.8/gc.properties create mode 100644 src/main/java/model/Cloud.java create mode 100644 src/main/java/model/MotorizedFirefighter.java diff --git a/.gradle/8.10.2/executionHistory/executionHistory.lock b/.gradle/8.10.2/executionHistory/executionHistory.lock index 66d287d3b823619b05e3e0405201e0476d56d0bb..5b91c9b6e3b22a57af3710176e3952da3c4870ee 100644 GIT binary patch literal 17 UcmZR+l_mROZDjon1_+P>05~@Ui~s-t literal 17 TcmZR+l_mROZDjon1}FdkI2{CX diff --git a/.gradle/8.10.2/fileHashes/fileHashes.lock b/.gradle/8.10.2/fileHashes/fileHashes.lock index 6ff3a415c6023cab4336fc709e46d5153dca2c9a..85111997a4d19a06a7f07551c92ddaa3bf725601 100644 GIT binary patch literal 17 UcmZR!SrmR}pBH-<0|aaa054etVE_OC literal 17 TcmZR!SrmR}pBH-<0~7!NE~W#n diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock deleted file mode 100644 index 8a45a7084553486969a0e333e25707ca7f09aa8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 TcmZP$p5)?V>oR*L0~7!NCd~sb diff --git a/.gradle/8.8/dependencies-accessors/gc.properties b/.gradle/8.8/dependencies-accessors/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/8.8/executionHistory/executionHistory.bin b/.gradle/8.8/executionHistory/executionHistory.bin deleted file mode 100644 index 31d2a1839cbee614a0ff816d1d8bba3e57db218d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19652 zcmZ=^V2}{_4+RVeAc|m)vPMH-Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zMnhmU1V%$(Gz3ONU^E0qLtr!nhD!*9GB7Z3K|CX&!vtdRmoqRJ@GvkiFd8IFM=<d& zn+FnQVDNB+P9MN21_lOAh}<YS8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRDLco}Tfu)Lpfu#t9XJ-{<nH!aw zmM0e_rkiHur01lV6(%O-CKsCsNTmfOuPl3M6W$S<_iN3kV>>x8gc#Q67p3c^7bT|T zr0OLWWa^b97H1dhl@}!z6r>jEg+u6gm(=9^qQsKa6oI$*@7-H`V(U7YA16d36F)v> zqSyq6<Bai6rI|S?!O2CL1tsw+@kOP1@yR*)#id25hAJ?YQM_qls)f0wp^1f|rKv%R zrMY>Ukx{a-scA||in(#BiG{$k?Dvy)eO-IQ;QlMuQ(u@HxOx(ck~1>PQk@cuQ#sZV z<5QJ@#F7k<@`>(2jxIi~@u9)4LGd2`zOFE{Knj@qpaG<xl383*JP|||WhRxDWaj6A zG*fC9ih)=xoQ7;+a7Ln$sabGoE(40TkjjEoj%`Hw*(I~M1m=8@wiYK(zX`}zgcjv6 z@69MFDJZtm*Dp>jD$7hxErz9<{GxPlFu+VG)`uh~T?;)6-K5Msy{gQDK8R3QYEf}! zejam+g`P!!UTR5seo=NvW^QVJX$cDhgSx<svc#Osl*E!$WEX`N<uEd^^du#gBxgX9 z2;(+qtC-N@)S}{;q{Nh>q8P`50++;+#2BCa<iwnqkks6Q7*GV|<R`~KEH2keN-SXz zIJ{=Z{O{a9Vi~==?moH^`Skp%kG&g>u8XmBWF;24W#*(Z?j_Y^U64hftdf;j#2|3~ zRf&0G@CM%YVCN$*Yh7L+TL!XV?`0;I{(_?Xg4Cjt%+zAAMMoIPwh3VpgTSMhxxr0^ zRm=Ybyu0%KfWPQLu!X-ES-OkCxe097CQ_{`XAtNL`=)v7z;WUG^RjmorR>-KvjXIk M&(1823=Ayw0M_mA8vp<R diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock deleted file mode 100644 index 28dcf5f95f3b8611411e632c8e70bb832e839ade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZQx{quCscg9OS3=qH!07QcYSO5S3 diff --git a/.gradle/8.8/fileChanges/last-build.bin b/.gradle/8.8/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin deleted file mode 100644 index 54cad51c13f406f7c097b1a5990d97a41d4bf162..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18697 zcmZ=^V2}{_4+RVeAc|m)vPMH-Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zMnhmU1V%$(Gz3ONU^E0qLtr!nhD!*9GB7Z3K|CX&!vtdRmoqRJ@Gvkiuw43@*7nLN zl@TP$z~JEsoj&;gKH`s^$`eKwsCY3<Ts-)L@}!unpP}N{VdB}W_4CVp{xU<wm%_wh zGy?-eAw+JJ91Vfd5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c z4S~@R7!85Z5Eu=C(GVC7fzc44Bm|5Z7#K7e7#I{mSm5xQ9rM3)|A=Mu?z;QvM&wfl z2FA&PdqVvoHgJbCFfiz$>Nx+Z#5^&018;k<^O2XeF0Uavg54lGR_?{r@hE0)a8qH` z@;?FZu6#e>FACM+2+_gt3sXl|*f-5n2aXHhpO?L(C}qDkL`O&sM28}1UxFS0$A5T% diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock deleted file mode 100644 index 3b21749594fbc6d5f3d5df219da1355f3213846b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZS9Uz`8Gc}t%h0|c-E05seLHvj+t diff --git a/.gradle/8.8/gc.properties b/.gradle/8.8/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 964c60967a2b63f66ae399dfea332826c256aeeb..bf3eeeb207ed57830e31cda038181f21f98cf9cd 100644 GIT binary patch literal 17 UcmZRMh_{lPws>110|c}I04b{j`2YX_ literal 17 UcmZRMh_{lPws>110|f8`04X#Bf&c&j diff --git a/src/main/java/model/Cloud.java b/src/main/java/model/Cloud.java new file mode 100644 index 0000000..ad88e36 --- /dev/null +++ b/src/main/java/model/Cloud.java @@ -0,0 +1,46 @@ +package model; + +import util.Position; +import java.util.List; +import java.util.Random; +import java.util.Set; + +public class Cloud { + private List<Position> positions; + + public Cloud(List<Position> initialPositions) { + this.positions = initialPositions; + } + + /** + * Déplace chaque nuage vers une position aléatoire parmi les positions possibles. + * + * @param possiblePositions Ensemble des positions possibles. + * @return Liste des nouvelles positions des nuages. + */ + public List<Position> moveRandomly(Set<Position> possiblePositions) { + Random random = new Random(); + for (int i = 0; i < positions.size(); i++) { + // Choisir une position aléatoire dans l'ensemble des positions possibles + Position newPosition = possiblePositions.stream() + .skip(random.nextInt(possiblePositions.size())) + .findFirst() + .orElse(positions.get(i)); + positions.set(i, newPosition); + } + return positions; + } + + /** + * Éteint les feux situés sur les positions occupées par les nuages. + * + * @param fire L'objet Fire à modifier. + */ + public void extinguishFire(Fire fire) { + positions.forEach(fire::extinguish); + } + + public List<Position> getPositions() { + return positions; + } +} diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java index 335315e..28bc66b 100644 --- a/src/main/java/model/Fire.java +++ b/src/main/java/model/Fire.java @@ -17,13 +17,21 @@ public class Fire { return positions; } - public List<Position> spread(Set<Position> neighbors) { - // Logique de propagation de l'incendie - List<Position> newFirePositions = new ArrayList<>(neighbors); + public List<Position> spread(Set<Position> allPositions, Set<Position> roadPositions) { + List<Position> newFirePositions = new ArrayList<>(); + for (Position position : positions) { + for (Position neighbor : allPositions) { + if (!roadPositions.contains(neighbor) && !positions.contains(neighbor)) { + newFirePositions.add(neighbor); + } + } + } positions.addAll(newFirePositions); return newFirePositions; } + + public void extinguish(Position position) { positions.remove(position); }} \ No newline at end of file diff --git a/src/main/java/model/Firefighter.java b/src/main/java/model/Firefighter.java index 70237fb..0538a32 100644 --- a/src/main/java/model/Firefighter.java +++ b/src/main/java/model/Firefighter.java @@ -1,37 +1,65 @@ package model; import util.Position; - import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; -import model.TargetStrategy; +import util.TargetStrategy; public class Firefighter { private List<Position> positions; private TargetStrategy targetStrategy; + // Constructor public Firefighter(List<Position> initialPositions, TargetStrategy targetStrategy) { this.positions = initialPositions; this.targetStrategy = targetStrategy; } - public List<Position> moveToClosestFire(Set<Position> firePositions, Map<Position, List<Position>> neighbors) { + public boolean canFireSpreadToRock(Position position, int currentStepNumber, FirefighterBoard board) { + List<ModelElement> elements = board.getState(position); + if (elements.contains(ModelElement.ROCK)) { + return currentStepNumber >= 4; + } + return false; + } + + public List<Position> moveToClosestFire(Set<Position> firePositions, + Map<Position, List<Position>> neighbors, + Set<Position> roadPositions) { List<Position> modifiedPositions = new ArrayList<>(); List<Position> newPositions = new ArrayList<>(); - for (Position position : positions) { - Position newPosition = targetStrategy.neighborClosestToFire(position, firePositions, neighbors); - newPositions.add(newPosition); + for (Position position : getPositions()) { + Position firstStep = getTargetStrategy().neighborClosestToFire(position, firePositions, neighbors, roadPositions); + + Position secondStep = (firstStep != null) + ? getTargetStrategy().neighborClosestToFire(firstStep, firePositions, neighbors, roadPositions) + : null; + + Position newPosition = (secondStep != null) ? secondStep : firstStep; + modifiedPositions.add(position); - modifiedPositions.add(newPosition); + if (firstStep != null) modifiedPositions.add(firstStep); + if (secondStep != null) modifiedPositions.add(secondStep); + + newPositions.add(newPosition); } - this.positions = newPositions; + + setPositions(newPositions); return modifiedPositions; } + public TargetStrategy getTargetStrategy() { + return targetStrategy; + } + public List<Position> getPositions() { return positions; } -} \ No newline at end of file + + protected void setPositions(List<Position> positions) { + this.positions = positions; + } +} diff --git a/src/main/java/model/FirefighterBoard.java b/src/main/java/model/FirefighterBoard.java index c84740f..6b72729 100644 --- a/src/main/java/model/FirefighterBoard.java +++ b/src/main/java/model/FirefighterBoard.java @@ -2,8 +2,7 @@ package model; import util.Position; import java.util.*; -import model.TargetStrategy; - +import util.TargetStrategy; public class FirefighterBoard implements Board<List<ModelElement>> { private final int columnCount; @@ -12,6 +11,10 @@ public class FirefighterBoard implements Board<List<ModelElement>> { private final int initialFirefighterCount; private final Position[][] positions; private final Map<Position, List<Position>> neighbors = new HashMap<>(); + private Cloud clouds; + private Firefighter motorizedFirefighter; + private Set<Position> mountainPositions = new HashSet<>(); + private Set<Position> roadPositions = new HashSet<>(); private Fire fire; private Firefighter firefighter; @@ -28,6 +31,14 @@ public class FirefighterBoard implements Board<List<ModelElement>> { initializeElements(); } + private boolean canFireSpreadToRock(Position position, int currentStepNumber) { + List<ModelElement> elements = getState(position); + if (elements.contains(ModelElement.ROCK)) { + return currentStepNumber >= 4; + } + return false; + } + private void initializePositions() { for (int column = 0; column < columnCount; column++) for (int row = 0; row < rowCount; row++) @@ -58,6 +69,10 @@ public class FirefighterBoard implements Board<List<ModelElement>> { initialFirefighterPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); } + for (int i = 0; i < 10; i++) { + roadPositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount))); + } + fire = new Fire(initialFirePositions); firefighter = new Firefighter(initialFirefighterPositions, new TargetStrategy()); } @@ -65,6 +80,7 @@ public class FirefighterBoard implements Board<List<ModelElement>> { @Override public List<ModelElement> getState(Position position) { List<ModelElement> elements = new ArrayList<>(); + if (mountainPositions.contains(position)) elements.add(ModelElement.MOUNTAIN); if (fire.getPositions().contains(position)) elements.add(ModelElement.FIRE); if (firefighter.getPositions().contains(position)) elements.add(ModelElement.FIREFIGHTER); return elements; @@ -72,15 +88,38 @@ public class FirefighterBoard implements Board<List<ModelElement>> { @Override public List<Position> updateToNextGeneration() { - List<Position> modifiedPositions = firefighter.moveToClosestFire(fire.getPositions(), neighbors); - modifiedPositions.addAll(fire.spread(neighbors.keySet())); + List<Position> modifiedPositions = new ArrayList<>(); + Set<Position> newFires = new HashSet<>(); + + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + Position position = positions[row][column]; + List<ModelElement> elements = getState(position); + + if (elements.contains(ModelElement.ROCK)) { + for (Position adj : neighbors.get(position)) { + List<ModelElement> adjElements = getState(adj); + if (adjElements.contains(ModelElement.FIRE) && canFireSpreadToRock(position, step)) { + newFires.add(position); + } + } + } + } + } + + for (Position firePos : newFires) { + List<ModelElement> elements = getState(firePos); + elements.add(ModelElement.FIRE); + setState(elements, firePos); + modifiedPositions.add(firePos); + } + step++; return modifiedPositions; } @Override public void setState(List<ModelElement> state, Position position) { - // Mise à jour des états (feu ou pompier) en fonction de la liste `state` if (state.contains(ModelElement.FIRE)) fire.getPositions().add(position); if (state.contains(ModelElement.FIREFIGHTER)) firefighter.getPositions().add(position); } diff --git a/src/main/java/model/ModelElement.java b/src/main/java/model/ModelElement.java index 759eee5..e5f5417 100644 --- a/src/main/java/model/ModelElement.java +++ b/src/main/java/model/ModelElement.java @@ -1,5 +1,5 @@ package model; public enum ModelElement { - FIREFIGHTER, FIRE + FIREFIGHTER, FIRE, CLOUD, MOUNTAIN,ROCK } diff --git a/src/main/java/model/MotorizedFirefighter.java b/src/main/java/model/MotorizedFirefighter.java new file mode 100644 index 0000000..c88a823 --- /dev/null +++ b/src/main/java/model/MotorizedFirefighter.java @@ -0,0 +1,41 @@ +package model; + +import util.Position; + +import java.util.*; +import util.TargetStrategy; + +public class MotorizedFirefighter extends Firefighter { + + public MotorizedFirefighter(List<Position> initialPositions, TargetStrategy targetStrategy) { + super(initialPositions, targetStrategy); + } + + @Override + public List<Position> moveToClosestFire(Set<Position> firePositions, + Map<Position, List<Position>> neighbors, + Set<Position> roadPositions) { + List<Position> modifiedPositions = new ArrayList<>(); + List<Position> newPositions = new ArrayList<>(); + + for (Position position : getPositions()) { + Position firstStep = getTargetStrategy().neighborClosestToFire(position, firePositions, neighbors, roadPositions); + + Position secondStep = (firstStep != null) + ? getTargetStrategy().neighborClosestToFire(firstStep, firePositions, neighbors, roadPositions) + : null; + + Position newPosition = (secondStep != null) ? secondStep : firstStep; + + modifiedPositions.add(position); + if (firstStep != null) modifiedPositions.add(firstStep); + if (secondStep != null) modifiedPositions.add(secondStep); + + newPositions.add(newPosition); + } + + setPositions(newPositions); + return modifiedPositions; + } + +} diff --git a/src/main/java/util/Position.java b/src/main/java/util/Position.java index 31dc4c1..5220fa0 100644 --- a/src/main/java/util/Position.java +++ b/src/main/java/util/Position.java @@ -1,5 +1,47 @@ package util; -public record Position(int row, int column) { +import java.util.Objects; +public class Position { + private final int row; + private final int column; + + public Position(int row, int column) { + this.row = row; + this.column = column; + } + + public int row() { + return row; + } + + public int column() { + return column; + } + + public int getRow() { + return row; + } + + public int getColumn() { + return column; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Position position = (Position) o; + return row == position.row && column == position.column; + } + + @Override + public int hashCode() { + return Objects.hash(row, column); + } + + @Override + public String toString() { + return "Position{" + "row=" + row + ", column=" + column + '}'; + } } diff --git a/src/main/java/util/TargetStrategy.java b/src/main/java/util/TargetStrategy.java index 5831867..629b6f6 100644 --- a/src/main/java/util/TargetStrategy.java +++ b/src/main/java/util/TargetStrategy.java @@ -1,4 +1,4 @@ -package model; +package util; import util.Position; @@ -6,30 +6,48 @@ import java.util.*; public class TargetStrategy { - /** - * @param position current position. - * @param targets positions that are targeted. - * @return the position next to the current position that is on the path to the closest target. + * Trouve la case adjacente la plus proche du feu en respectant les routes. + * + * @param position Position actuelle. + * @param targets Positions des feux. + * @param neighbors Carte des voisins pour chaque position. + * @param roadPositions Positions représentant les routes. + * @return La position voisine qui se rapproche le plus d'un feu, respectant les routes. */ - Position neighborClosestToFire(Position position, Collection<Position> targets, - Map<Position,List<Position>>neighbors) { - Set<Position> seen = new HashSet<Position>(); - HashMap<Position, Position> firstMove = new HashMap<Position, Position>(); - Queue<Position> toVisit = new LinkedList<Position>(neighbors.get(position)); - for (Position initialMove : toVisit) - firstMove.put(initialMove, initialMove); + public Position neighborClosestToFire(Position position, Collection<Position> targets, + Map<Position, List<Position>> neighbors, + Set<Position> roadPositions) { + Set<Position> seen = new HashSet<>(); + Map<Position, Position> firstMove = new HashMap<>(); + Queue<Position> toVisit = new LinkedList<>(neighbors.get(position)); + + // Initialisation des mouvements possibles + for (Position initialMove : toVisit) { + if (roadPositions.contains(initialMove)) { + firstMove.put(initialMove, initialMove); + } + } + + // Parcours en largeur (BFS) pour trouver le feu le plus proche while (!toVisit.isEmpty()) { Position current = toVisit.poll(); - if (targets.contains(current)) + + // Si la position actuelle est un feu, on retourne le premier mouvement vers cette position + if (targets.contains(current)) { return firstMove.get(current); + } + + // Ajout des voisins non visités qui sont sur les routes for (Position adjacent : neighbors.get(current)) { - if (seen.contains(adjacent)) continue; + if (seen.contains(adjacent) || !roadPositions.contains(adjacent)) continue; toVisit.add(adjacent); seen.add(adjacent); firstMove.put(adjacent, firstMove.get(current)); } } + + // Si aucun feu n'est trouvé, retourner la position actuelle return position; } -} \ No newline at end of file +} -- GitLab