Skip to content
Snippets Groups Projects
Commit 9a68c04f authored by RADELLAH Badr's avatar RADELLAH Badr
Browse files

Ajout du code initial du modèle Firefighter avec ses composants principaux...

Ajout du code initial du modèle Firefighter avec ses composants principaux (Board, Cloud, Fire, Firefighter, MotorizedFirefighter, etc.), ainsi que des classes utilitaires et des interfaces pour la vue (Grid et FirefighterGrid). Le code nécessite encore des ajustements et des améliorations pour être complètement fonctionnel.
parent 9d23ba40
No related branches found
No related tags found
No related merge requests found
Pipeline #39491 passed
Showing
with 256 additions and 34 deletions
No preview for this file type
No preview for this file type
File deleted
File deleted
File deleted
File deleted
File deleted
File deleted
No preview for this file type
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;
}
}
......@@ -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
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;
}
protected void setPositions(List<Position> positions) {
this.positions = positions;
}
}
......@@ -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);
}
......
package model;
public enum ModelElement {
FIREFIGHTER, FIRE
FIREFIGHTER, FIRE, CLOUD, MOUNTAIN,ROCK
}
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;
}
}
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 + '}';
}
}
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)
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment