Skip to content
Snippets Groups Projects
Commit 35c55f6c authored by AREZKI Celia's avatar AREZKI Celia
Browse files

Merge remote-tracking branch 'origin/main'

# Conflicts:
#	src/main/java/model/FirefighterBoard.java
parents 47698c64 61b24491
Branches
No related tags found
No related merge requests found
Pipeline #40334 failed
Showing
with 445 additions and 66 deletions
File added
File added
......@@ -4,4 +4,5 @@ public class SimulatorMain {
public static void main(String[] args){
SimulatorApplication.main(args);
}
}
package controller;
import util.Position;
import view.ViewElement;
import java.util.*;
public class CloudController {
private final int rowCount;
private final int columnCount;
private final Set<Position> clouds = new HashSet<>();
public CloudController(int rowCount, int columnCount) {
this.rowCount = rowCount;
this.columnCount = columnCount;
}
public void addCloud(Position position) {
clouds.add(position);
}
public Set<Position> getCloudPositions() {
return clouds;
}
public void moveClouds() {
Set<Position> newCloudPositions = new HashSet<>();
Random random = new Random();
for (Position cloud : clouds) {
int newRow = cloud.row() + random.nextInt(3) - 1; // Mouvement aléatoire (-1, 0, 1)
int newCol = cloud.column() + random.nextInt(3) - 1;
// S'assurer que les nuages restent dans les limites de la grille
newRow = Math.max(0, Math.min(rowCount - 1, newRow));
newCol = Math.max(0, Math.min(columnCount - 1, newCol));
newCloudPositions.add(new Position(newRow, newCol));
}
clouds.clear();
clouds.addAll(newCloudPositions);
}
public void extinguishFires(ViewElement[][] grid) {
for (Position cloud : clouds) {
if (grid[cloud.row()][cloud.column()] == ViewElement.FIRE) {
grid[cloud.row()][cloud.column()] = ViewElement.EMPTY; // Éteindre le feu
}
}
}
}
......@@ -40,7 +40,7 @@ public class Controller {
@FXML
private Grid<ViewElement> grid;
private Timeline timeline;
private Board<List<ModelElement>> board;
private FirefighterBoard board;
@FXML
private void initialize() {
......
......@@ -4,62 +4,9 @@ import util.Position;
import java.util.List;
/**
* This interface represents a generic board for modeling various state-based systems.
*
* @param <S> The type of state represented on the board.
*/
public interface Board<S> {
/**
* Get the state of the board at a specific position.
*
* @param position The position on the board for which to retrieve the state.
* @return The state at the specified position.
*/
S getState(Position position);
/**
* Set the state of a specific position on the board to the specified state.
*
* @param state The state to set for the given position.
* @param position The position on the board for which to set the state.
*/
void setState(S state, Position position);
/**
* Get the number of rows in the board.
*
* @return The number of rows in the board.
*/
int rowCount();
/**
* Get the number of columns in the board.
*
* @return The number of columns in the board.
*/
int columnCount();
/**
* Update the board to its next generation or state. This method may modify the
* internal state of the board and return a list of positions that have changed
* during the update.
*
* @return A list of positions that have changed during the update.
*/
List<Position> updateToNextGeneration();
public interface Board<S> {
/**
* Reset the board to its initial state.
*/
void reset();
/**
* Get the current step number or generation of the board.
*
* @return The current step number or generation.
*/
int stepNumber();
}
package model;
import util.Position;
import java.util.List;
public interface BoardBehavior {
public int stepNumber(); // Numéro de l'étape actuelle.
public List<Position> updateToNextGeneration();
public void reset();
public interface BoardBehavior<S> extends Board<S>{
/**
* Get the current step number or generation of the board.
*
* @return The current step number or generation.
*/
int stepNumber();
/**
* Update the board to its next generation or state. This method may modify the
* internal state of the board and return a list of positions that have changed
* during the update.
*
* @return A list of positions that have changed during the update.
*/
List<Position> updateToNextGeneration();
/**
* Reset the board to its initial state.
*/
void reset();
}
......@@ -4,9 +4,39 @@ import util.Position;
import java.util.List;
public interface BoardProperties {
/**
* Interface représentant les propriétés d'un tableau générique pour la gestion de l'état.
*
* @param <S> Le type d'état utilisé pour les éléments du tableau.
*/
public interface BoardProperties<S> extends Board<S> {
/**
* Retourne le nombre de lignes du tableau.
*
* @return Le nombre de lignes.
*/
int rowCount(); // Nombre de lignes.
/**
* Retourne le nombre de colonnes du tableau.
*
* @return Le nombre de colonnes.
*/
int columnCount(); // Nombre de colonnes.
List<ModelElement> getState(Position position); // État des éléments sur une position donnée.
void setState(List<ModelElement> state, Position position);
/**
* Retourne l'état des éléments situés à une position spécifique du tableau.
*
* @param position La position sur le tableau pour laquelle récupérer l'état.
* @return L'état des éléments à la position donnée.
*/
S getState(Position position); // État des éléments sur une position donnée.
/**
* Définit l'état des éléments à une position spécifique du tableau.
*
* @param state L'état à définir pour la position donnée.
* @param position La position sur le tableau pour laquelle définir l'état.
*/
void setState(S state, Position position);
}
package model;
import util.Position;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ClassicFireFighter extends FirefighterManager{
public ClassicFireFighter(List<Position> firefighterPositions) {
super(firefighterPositions);
}
@Override
public List<Position> updateFirefighters(int step, Map<Position, List<Position>> neighbors) {
List<Position> modifiedPositions = new ArrayList<>();
for (Position firefighterPosition : firefighterPositions) {
Position newFirefighterPosition = moveToTarget(firefighterPosition, fireManager.getFirePosition(), neighbors);
setFirefighterPosition(firefighterPosition, newFirefighterPosition);
if (fireManager.isOnFire(newFirefighterPosition)) {
extinguishFire(newFirefighterPosition);
}
modifiedPositions.add(firefighterPosition);
modifiedPositions.add(newFirefighterPosition);
}
return modifiedPositions;
}
}
package model;
import util.Position;
import java.util.List;
import java.util.Map;
public interface FireBehavior {
public List<Position> updateFires(int step, Map<Position, List<Position>> neighbors);
void extinguishFire(Position position);
}
package model;
import util.Position;
import view.ViewElement;
import java.util.*;
public class FireManager implements FireBehavior, FireProperties{
private Set<Position> firePositions;
private FirefighterManager firefighterManager;
public FireManager(Set<Position> firePositions,FirefighterManager firefighterManager) {
this.firePositions = firePositions;
this.firefighterManager=firefighterManager;
}
// Initialize fire positions randomly
public void initializeFires(int fireCount, int rowCount, int columnCount, Random random) {
firePositions.clear();
for (int i = 0; i < fireCount; i++) {
firePositions.add(new Position(random.nextInt(rowCount), random.nextInt(columnCount)));
}
}
@Override
public List<Position> updateFires(int step, Map<Position, List<Position>> neighbors) {
List<Position> newFirePositions = new ArrayList<>();
if (step % 2 == 0) { // Le feu se propage tous les deux pas
for (Position fire : firePositions) {
for (Position neighbor : neighbors.get(fire)) {
// Vérifier si le voisin est déjà en feu ou s'il y a un pompier
if (!firePositions.contains(neighbor) && !firefighterManager.getFirefighterPositions().contains(neighbor)) {
newFirePositions.add(neighbor);
}
}
}
firePositions.addAll(newFirePositions);
}
return newFirePositions;
}
public void spreadFire(ViewElement[][] grid) {
int rows = grid.length;
int columns = grid[0].length;
// Créez un tableau pour suivre les tours avant que le feu se propage sur les rocailles
int[][] fireCooldown = new int[rows][columns];
// Initialisation du tableau de cooldown des rocailles à 0
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (grid[i][j] == ViewElement.ROCKY) {
fireCooldown[i][j] = 4; // Le feu prend 4 tours pour se propager sur les rocailles
} else {
fireCooldown[i][j] = 0; // Aucune attente pour les autres cases
}
}
}
ViewElement[][] newGrid = new ViewElement[rows][columns];
for (int i = 0; i < rows; i++) {
System.arraycopy(grid[i], 0, newGrid[i], 0, columns);
}
// Propagation du feu
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (grid[i][j] == ViewElement.FIRE) {
// Propager le feu sur les voisins si possible
for (Position neighbor : getNeighbors(i, j, rows, columns)) {
if (grid[neighbor.row()][neighbor.column()] == ViewElement.EMPTY) {
newGrid[neighbor.row()][neighbor.column()] = ViewElement.FIRE;
}
// Empêcher la propagation sur les montagnes
if (grid[neighbor.row()][neighbor.column()] == ViewElement.MOUNTAIN) {
newGrid[neighbor.row()][neighbor.column()] = ViewElement.MOUNTAIN;
}
// Propagation du feu sur les rocailles après 4 tours
if (grid[neighbor.row()][neighbor.column()] == ViewElement.ROCKY && fireCooldown[neighbor.row()][neighbor.column()] == 0) {
newGrid[neighbor.row()][neighbor.column()] = ViewElement.FIRE;
}
}
}
}
}
// Mise à jour de la grille après propagation
for (int i = 0; i < rows; i++) {
System.arraycopy(newGrid[i], 0, grid[i], 0, columns);
}
// Décrémenter le cooldown des rocailles chaque tour
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (fireCooldown[i][j] > 0) {
fireCooldown[i][j]--; // Décrémenter le compteur de cooldown
}
}
}
}
private List<Position> getNeighbors(int row, int column, int rows, int columns) {
List<Position> neighbors = new ArrayList<>();
if (row > 0) neighbors.add(new Position(row - 1, column));
if (row < rows - 1) neighbors.add(new Position(row + 1, column));
if (column > 0) neighbors.add(new Position(row, column - 1));
if (column < columns - 1) neighbors.add(new Position(row, column + 1));
return neighbors;
}
// Extinguish a fire at a specific position
@Override
public void extinguishFire(Position position) {
firePositions.remove(position);
}
// Query if a position is on fire
@Override
public boolean isOnFire(Position position) {
return firePositions.contains(position);
}
@Override
public Set<Position> getFirePosition()
{ return new HashSet<>(firePositions);}
}
package model;
import util.Position;
import java.util.Set;
public interface FireProperties {
public boolean isOnFire(Position position);
Set<Position> getFirePosition();
}
package model;
import util.Position;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface FirefighterBehavior {
Position moveToTarget(Position currentPosition, Collection<Position> firePositions,
Map<Position, List<Position>> neighbors); // Déplacer un pompier vers une cible.
void extinguishFire(Position firePosition); // Éteindre un feu à une position donnée.
// public List<Position> updateFirefighters(int step, Map<Position, List<Position>> neighbors);
}
package model;
import util.Position;
import util.TargetStrategy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public abstract class FirefighterManager implements FirefighterBehavior, FirefighterProperties {
protected List<Position> firefighterPositions;
FireManager fireManager;
public void setFireManager(FireManager fireManager) {
this.fireManager = fireManager;
}
public FirefighterManager(List<Position> firefighterPositions) {
this.firefighterPositions = firefighterPositions;
}
@Override
public Position moveToTarget(Position currentPosition, Collection<Position> firePositions, Map<Position, List<Position>> neighbors) {
TargetStrategy targetStrategy = new TargetStrategy();
return targetStrategy.neighborClosestToFire(currentPosition, firePositions, neighbors);
}
@Override
public void extinguishFire(Position firePosition) {
fireManager.extinguishFire(firePosition);
}
@Override
public List<Position> getFirefighterPositions() {
return firefighterPositions;
}
@Override
public void setFirefighterPosition(Position oldPosition, Position newPosition) {
firefighterPositions.remove(oldPosition);
firefighterPositions.add(newPosition);
}
public abstract List<Position> updateFirefighters(int step, Map<Position, List<Position>> neighbors) ;
}
package model;
import util.Position;
import java.util.List;
public interface FirefighterProperties {
List<Position> getFirefighterPositions();
void setFirefighterPosition(Position oldPosition, Position newPosition);
}
package model;
import util.Position;
import java.util.*;
public class MotorizedFirefighter extends FirefighterManager {
private Random random =new Random();
public MotorizedFirefighter(List<Position> firefighterPositions) {
super(firefighterPositions);
}
@Override
public List<Position> updateFirefighters(int step, Map<Position, List<Position>> neighbors) {
List<Position> modifiedPositions = new ArrayList<>();
for (Position firefighterPosition : firefighterPositions) {
// Déplacement motorisé, on se déplace de deux cases
Position newFirefighterPosition = moveToTarget(firefighterPosition, fireManager.getFirePosition(), neighbors);
setFirefighterPosition(firefighterPosition, newFirefighterPosition);
// Vérifier si un feu est à la nouvelle position et l'éteindre
if (fireManager.isOnFire(newFirefighterPosition)) {
extinguishFire(newFirefighterPosition);
}
modifiedPositions.add(firefighterPosition);
modifiedPositions.add(newFirefighterPosition);
}
return modifiedPositions;
}
@Override
public Position moveToTarget(Position currentPosition, Collection<Position> firePositions, Map<Position, List<Position>> neighbors) {
// Logique spécifique pour le déplacement motorisé (deux cases)
List<Position> possibleMoves = new ArrayList<>();
for (Position neighbor : neighbors.get(currentPosition)) {
for (Position secondNeighbor : neighbors.get(neighbor)) {
if (!secondNeighbor.equals(currentPosition)) {
possibleMoves.add(secondNeighbor);
}
}
}
if (!possibleMoves.isEmpty()) {
return possibleMoves.get(random.nextInt(possibleMoves.size()));
} else {
return currentPosition;
}
}
}
package util;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class MotorizedStrategy implements Strategy{
@Override
public Position neighborClosestToTarget(Position position, Collection<Position> targets, Map<Position, List<Position>> neighbors) {
TargetStrategy normalStrategy = new TargetStrategy();
Position firstMove = normalStrategy.neighborClosestToTarget(position, targets, neighbors);
// Si un premier mouvement est trouvé, on simule un second déplacement
if (firstMove != null && neighbors.containsKey(firstMove)) {
return normalStrategy.neighborClosestToTarget(firstMove, targets, neighbors);
}
return position;
}
}
package util;
import view.ViewElement;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public interface Strategy {
Position neighborClosestToTarget(Position position, Collection<Position> targets, Map<Position, List<Position>> neighbors, ViewElement[][] grid);
}
package util;
import util.Position;
import view.ViewElement;
import java.util.*;
public class TargetStrategy {
public class TargetStrategy implements Strategy{
/**
......@@ -12,8 +13,8 @@ public class TargetStrategy {
* @param targets positions that are targeted.
* @return the position next to the current position that is on the path to the closest target.
*/
public Position neighborClosestToFire(Position position, Collection<Position> targets,
Map<Position, List<Position>> neighbors) {
public Position neighborClosestToTarget(Position position, Collection<Position> targets,
Map<Position, List<Position>> neighbors, ViewElement[][] grid) {
Set<Position> seen = new HashSet<Position>();
HashMap<Position, Position> firstMove = new HashMap<Position, Position>();
Queue<Position> toVisit = new LinkedList<Position>(neighbors.get(position));
......@@ -21,6 +22,7 @@ public class TargetStrategy {
firstMove.put(initialMove, initialMove);
while (!toVisit.isEmpty()) {
Position current = toVisit.poll();
if (grid[current.row()][current.column()] == ViewElement.MOUNTAIN) continue;
if (targets.contains(current))
return firstMove.get(current);
for (Position adjacent : neighbors.get(current)) {
......
......@@ -96,4 +96,5 @@ public class FirefighterGrid extends Canvas implements Grid<ViewElement>{
private void clearBox(int row, int column){
getGraphicsContext2D().clearRect(column * boxWidth,row * boxHeight, boxWidth, boxHeight);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment