From 8e1d13aaaaa24fa4830916834555eb8d8f746b62 Mon Sep 17 00:00:00 2001
From: Yanis O <oualanyanis01@gmail.com>
Date: Wed, 13 Nov 2024 19:09:47 +0100
Subject: [PATCH] =?UTF-8?q?[Ajout]=20Logique=20de=20d=C3=A9placement=20et?=
 =?UTF-8?q?=20d'extinction=20de=20feu=20des=20pompiers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/controller/Controller.java     |  1 -
 src/main/java/model/Board.java               |  4 +
 src/main/java/model/EmptySquare.java         | 10 ++-
 src/main/java/model/Entity.java              |  7 +-
 src/main/java/model/Fire.java                | 28 +++---
 src/main/java/model/FireFighter.java         | 94 +++++++++++++++++---
 src/main/java/model/FireFighterScenario.java | 18 +++-
 src/main/java/util/Matrix.java               | 21 ++++-
 src/main/java/util/PositionUtil.java         | 83 +++++++++++++++++
 9 files changed, 228 insertions(+), 38 deletions(-)

diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index 2450bf5..154a1b8 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -74,7 +74,6 @@ public class Controller {
     int columnCount = board.columnCount();
     int rowCount = board.rowCount();
     ViewElement[][] viewElements = new ViewElement[rowCount][columnCount];
-    System.out.println("columnsCOunt : " + columnCount + " rowCount : " + rowCount);
     for(int column = 0; column < columnCount; column++)
       for(int row = 0; row < rowCount; row++)
         viewElements[row][column] = getViewElement(board.getState(new Position(row, column)));
diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java
index b88601b..1326ce8 100644
--- a/src/main/java/model/Board.java
+++ b/src/main/java/model/Board.java
@@ -67,5 +67,9 @@ public interface Board<S> {
   public void setState(Entity state, Position position, boolean replaceStates);
 
   public boolean doesPositionExist(Position position);
+
+  public void clearCase(Position position);
+
+  public Position getNearestEntity(Position fromPos, Class<?> entityType);
 }
 
diff --git a/src/main/java/model/EmptySquare.java b/src/main/java/model/EmptySquare.java
index 1d5749d..113ea0a 100644
--- a/src/main/java/model/EmptySquare.java
+++ b/src/main/java/model/EmptySquare.java
@@ -10,8 +10,14 @@ public class EmptySquare implements Entity{
 
     private Position position;
     private final Color viewColor = Color.WHITE;
+    private int age;
     public EmptySquare(Position p){
         this.position = p;
+        this.age = -999;
+    }
+    public EmptySquare(Position p, int age){
+        this.position = p;
+        this.age = age;
     }
     @Override
     public List<Position> nextTurn(Board<Entity> board) {
@@ -33,11 +39,11 @@ public class EmptySquare implements Entity{
     }
     @Override
     public int getAge() {
-        return -999;
+        return this.age;
     }
 
     @Override
     public void incrementAge() {
-        return;
+        age = age + 1;
     }
 }
diff --git a/src/main/java/model/Entity.java b/src/main/java/model/Entity.java
index 61626fa..5569aa5 100644
--- a/src/main/java/model/Entity.java
+++ b/src/main/java/model/Entity.java
@@ -6,7 +6,12 @@ import javafx.scene.paint.Color;
 import util.Position;
 
 public interface Entity {
-    // Calcule ce que l'entité va faire au prochain tour, et retourne la liste des positions affectés
+        /**
+     * Exécute un tour de jeu, en vérifiant les cases adjacentes pour des instances de Fire.
+     *
+     * @param b Le plateau de jeu contenant des entités.
+     * @return Une liste de positions affectées durant le tour (que la vue doit mettre à jour).
+     */
     public List<Position> nextTurn(Board<Entity> board);
     public Position getPosition();
     public void setPosition(Position p);
diff --git a/src/main/java/model/Fire.java b/src/main/java/model/Fire.java
index 43f7967..019137e 100644
--- a/src/main/java/model/Fire.java
+++ b/src/main/java/model/Fire.java
@@ -1,10 +1,10 @@
 package model;
+import java.util.ArrayList;
 import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import javafx.scene.paint.Color;
 import util.Position;
+import util.PositionUtil;
 
 public class Fire implements Entity{
     Board<Entity> b;
@@ -24,30 +24,22 @@ public class Fire implements Entity{
 
     @Override
     public List<Position> nextTurn(Board<Entity> board) {
-        age = age +1;
-        List<Position> positions = generateAdjacentPosition();
+        if(board.getStepNumber() % 2 == 0)return new ArrayList<Position>();
+        List<Position> positions = PositionUtil.generateAdjacentPositions(position, board);
         for(Position p : positions){
-            board.setState(new Fire(p, board), p);
+            if(b.getState(p) instanceof EmptySquare){
+                if(b.getState(p).getAge() < b.getStepNumber()){
+                    board.setState(new Fire(p, board), p);
+                }
+            }
             if(!b.doesPositionExist(p)){
                 positions.remove(p);
             }
         }
         return positions;
     }
+    
 
-    private List<Position> generateAdjacentPosition(){
-        int x = position.x();
-        int y = position.y();
-
-        return Stream.of(
-                new Position(x, y + 1),
-                new Position(x + 1, y),
-                new Position(x, y - 1),
-                new Position(x - 1, y)
-            )
-            .filter(p -> b.doesPositionExist(p))
-            .collect(Collectors.toList());
-    }
 
     
     @Override
diff --git a/src/main/java/model/FireFighter.java b/src/main/java/model/FireFighter.java
index 4088d8e..718589d 100644
--- a/src/main/java/model/FireFighter.java
+++ b/src/main/java/model/FireFighter.java
@@ -4,6 +4,7 @@ import java.util.List;
 
 import javafx.scene.paint.Color;
 import util.Position;
+import util.PositionUtil;
 
 public class FireFighter implements Entity{
     private int age;
@@ -22,18 +23,91 @@ public class FireFighter implements Entity{
         this.age = age;
     }
     
-    public List<Position> nextTurn(Board<Entity> b){
-        age++;
-        List<Position> positions = new ArrayList<Position>();
-        positions.add(position);
+    public List<Position> nextTurn(Board<Entity> b) {
+        List<Position> positions = new ArrayList<>();
+    
+        // Générer les positions adjacentes
+        List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, b);
+    
+        // Vérifier s'il y a du feu dans une des positions adjacentes
+        boolean hasFire = adjacentPositions.stream()
+                                           .anyMatch(p -> b.getState(p) instanceof Fire);
+    
+        if (hasFire) {
+            // Si du feu est trouvé, on éteint les feux adjacents
+            positions.addAll(extinguish(adjacentPositions, b));
+        } else {
+            // Chercher la position du feu le plus proche
+            Position nearestFirePos = b.getNearestEntity(position, Fire.class);
+    
+            if (nearestFirePos != null && !nearestFirePos.equals(position)) {
+                // Trouver la meilleure position pour se rapprocher du feu
+                Position nextPos = getNextPositionTowards(position, nearestFirePos, b);
+    
+                if (nextPos != null) {
+                    // Mettre à jour la position du pompier
+                    b.clearCase(position); // Vider l'ancienne case
+                    positions.add(new Position(position.x(), position.y()));
+                    this.position = nextPos;
+                    b.setState(this, nextPos); // Mettre à jour la nouvelle case
+                    positions.add(nextPos);
+                    adjacentPositions = PositionUtil.generateAdjacentPositions(nextPos, b);
+                    positions.addAll(extinguish(adjacentPositions, b));
+                } 
+                // Aucun déplacement possible = le pompier reste sur place
+            }
+        }
+    
         return positions;
-        // Récupérer la position
-        //Si un feu est à proximité : éteindre les feux à x + 1 y, x y+1, x+1 y-1, x-1 y+1 
-        //Sinon
-        //Se déplacer vers le feu le plus proche
-        //Si un feu est à proximité : éteindre les feux à x + 1 y, x y+1, x+1 y-1, x-1 y+1 
-        // Ajouter un feu à x + 1 y, x y+1, x-1 y, x y-1 
     }
+    
+    private List<Position> extinguish(List<Position> adjacentPositions, Board<Entity> b) {
+        List<Position> extinguishedPositions = new ArrayList<>();
+        for (Position p : adjacentPositions) {
+            if (b.getState(p) instanceof Fire) {
+                b.clearCase(p);
+                extinguishedPositions.add(p); // Ajouter la position où le feu a été éteint
+            }
+        }
+        return extinguishedPositions;
+    }
+    
+    private Position getNextPositionTowards(Position currentPos, Position targetPos, Board<Entity> b) {
+        // Générer les 8 positions adjacentes possibles
+        List<Position> possibleMoves = PositionUtil.generateAllAdjacentPositions(currentPos, b);
+    
+        // Filtrer les positions qui sont libres
+        possibleMoves.removeIf(p -> !(b.getState(p) instanceof EmptySquare));
+    
+        // Si aucune position libre n'est disponible, retourner null
+        if (possibleMoves.isEmpty()) {
+            return null;
+        }
+    
+        // Calculer la distance actuelle vers la cible
+        int currentDistance = PositionUtil.getManhattanDistance(currentPos, targetPos);
+    
+        // Choisir la position libre qui réduit le plus la distance vers le feu
+        Position bestMove = null;
+        int minDistance = currentDistance;
+        for (Position move : possibleMoves) {
+            int distance = PositionUtil.getManhattanDistance(move, targetPos);
+            if (distance < minDistance) {
+                minDistance = distance;
+                bestMove = move;
+            }
+        }
+    
+        // Si aucun déplacement ne réduit la distance, annuler le déplacement
+        if (bestMove == null) {
+            return null;
+        }
+        System.out.println("moving from " + position.toString() + " to " + bestMove.toString());
+        return bestMove;
+    }
+    
+    
+    
 
     @Override
     public void setPosition(Position p) {
diff --git a/src/main/java/model/FireFighterScenario.java b/src/main/java/model/FireFighterScenario.java
index 786d169..9c2a923 100644
--- a/src/main/java/model/FireFighterScenario.java
+++ b/src/main/java/model/FireFighterScenario.java
@@ -15,8 +15,12 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity>
   private Matrix<Entity> matrix;
   private int step;
 
+  private int initialFireCount;
+  private int initialFireFightersCount;
   public FireFighterScenario(int columns, int rows, int initialFireCount, int initialFireFightersCount) {
     this.matrix = new Matrix<Entity>(columns, rows);
+    this.initialFireCount = initialFireCount;
+    this.initialFireFightersCount = initialFireFightersCount;
     initScenario(matrix);
     placeInitialActors(initialFireCount, initialFireFightersCount);
     this.step = 0;
@@ -95,6 +99,10 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity>
   public int columnCount() {
     return matrix.getColumns();
   }
+  @Override
+  public void clearCase(Position position){
+    setState(new EmptySquare(position, step+1), position, true);
+  }
 
   public List<Position> updateToNextGeneration() {
     ArrayList<Position> changedPositions = new ArrayList<>();
@@ -103,15 +111,18 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity>
       Entity e = iterator.next();
       if (e instanceof EmptySquare)
         continue;
-      System.out.println("found age : " + e.getAge() + " current age : " + step);
       if (e.getAge() == 0) {
         e.incrementAge();
         continue;
       }
-      ;
+      if(e.getAge() == step+1){
+        continue;
+      }
       List<Position> entityUpdatedPositions = e.nextTurn(this);
+      e.incrementAge();
       changedPositions.addAll(entityUpdatedPositions);
     }
+    matrix.displayMatrix();
     return changedPositions;
   }
 
@@ -142,7 +153,10 @@ public class FireFighterScenario extends EntityScenario implements Board<Entity>
 
 
   public void reset() {
+    step = 0;
     matrix.clear();
+    initScenario(matrix);
+    placeInitialActors(initialFireCount, initialFireFightersCount);
   }
 
   public int stepNumber() {
diff --git a/src/main/java/util/Matrix.java b/src/main/java/util/Matrix.java
index c68517f..53da808 100644
--- a/src/main/java/util/Matrix.java
+++ b/src/main/java/util/Matrix.java
@@ -4,6 +4,9 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
+import model.Fire;
+import model.FireFighter;
+
 public class Matrix<E> implements Iterable<E> {
     private ArrayList<ArrayList<E>> matrix;
     private final int rows;
@@ -36,9 +39,11 @@ public class Matrix<E> implements Iterable<E> {
     }
 
     public void clear() {
-        this.matrix.clear();
+        this.matrix = new ArrayList<>(rows);
+        // Initialiser chaque ligne de la matrice
         for (int i = 0; i < rows; i++) {
             ArrayList<E> row = new ArrayList<>(columns);
+            // Initialiser chaque colonne avec des valeurs nulles
             for (int j = 0; j < columns; j++) {
                 row.add(null);
             }
@@ -56,7 +61,7 @@ public class Matrix<E> implements Iterable<E> {
     public int getRows(){
         return this.rows;
     }
-    /*
+
 
     public void displayMatrix() {
         System.out.print("  ");
@@ -69,7 +74,15 @@ public class Matrix<E> implements Iterable<E> {
             System.out.print("| ");
             for (int j = 0; j < columns; j++) {
                 if (matrix.get(i).get(j) != null) {
-                    System.out.print(" x | ");
+                    if(matrix.get(i).get(j) instanceof Fire){
+                        System.out.print(" F | ");
+                    }   
+                    else if(matrix.get(i).get(j) instanceof FireFighter){
+                        System.out.print(" ff | ");
+                    }else{
+                        System.out.print("  | ");
+                    }
+                    
                 } else {
                     System.out.print("   | ");
                 }
@@ -82,7 +95,7 @@ public class Matrix<E> implements Iterable<E> {
             System.out.println();
         }
     }
-        */
+
 
     private void validateIndex(int x, int y) {
         if (x < 0 || x >= rows || y < 0 || y >= columns) {
diff --git a/src/main/java/util/PositionUtil.java b/src/main/java/util/PositionUtil.java
index 7b2b235..48f5436 100644
--- a/src/main/java/util/PositionUtil.java
+++ b/src/main/java/util/PositionUtil.java
@@ -2,8 +2,31 @@ package util;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import model.Board;
+import model.Entity;
 
 public class PositionUtil {
+    /**
+     * Calcule et retourne une liste de positions situées à une distance de
+     * Manhattan spécifique à partir d'une position donnée.
+     * La distance de Manhattan entre deux points (x1, y1) et (x2, y2) est donnée
+     * par |x1 - x2| + |y1 - y2|.
+     * Cette méthode génère toutes les positions possibles à cette distance dans une
+     * grille de taille spécifiée.
+     *
+     * @param fromPos  la position de départ à partir de laquelle la distance est
+     *                 calculée.
+     * @param distance la distance de Manhattan à utiliser pour trouver les
+     *                 positions.
+     * @param rows     le nombre de lignes dans la grille.
+     * @param cols     le nombre de colonnes dans la grille.
+     * @return une liste de positions à la distance de Manhattan spécifiée de la
+     *         position initiale, qui se trouvent également dans les limites de la
+     *         grille.
+     */
     public static List<Position> getPositionsAtManhattanDistance(Position fromPos, int distance, int rows, int cols) {
         List<Position> positions = new ArrayList<>();
         int x0 = fromPos.x();
@@ -27,4 +50,64 @@ public class PositionUtil {
 
         return positions;
     }
+
+    /**
+     * Génère une liste de positions adjacentes à une position donnée, en vérifiant
+     * si chaque position est valide dans le contexte du jeu.
+     *
+     * @param position la position de départ pour laquelle générer les positions
+     *                 adjacentes.
+     * @param board    l'objet représentant le plateau de jeu qui permet de vérifier
+     *                 si une position existe.
+     * @return une liste des positions adjacentes valides.
+     */
+    public static List<Position> generateAdjacentPositions(Position position, Board<Entity> board) {
+        int x = position.x();
+        int y = position.y();
+
+        return Stream.of(
+                new Position(x, y + 1),
+                new Position(x + 1, y),
+                new Position(x, y - 1),
+                new Position(x - 1, y))
+                .filter(p -> board.doesPositionExist(p))
+                .collect(Collectors.toList());
+    }
+
+    // Méthode pour générer toutes les positions adjacentes (y compris les
+    // diagonales)
+    public static List<Position> generateAllAdjacentPositions(Position position, Board<Entity> board) {
+        int x = position.x();
+        int y = position.y();
+
+        List<Position> positions = new ArrayList<>();
+
+        // Liste des 8 déplacements possibles
+        int[][] deltas = {
+                { 1, 0 }, // x+1, y
+                { -1, 0 }, // x-1, y
+                { 0, 1 }, // x, y+1
+                { 0, -1 }, // x, y-1
+                { 1, 1 }, // x+1, y+1
+                { -1, -1 }, // x-1, y-1
+                { 1, -1 }, // x+1, y-1
+                { -1, 1 } // x-1, y+1
+        };
+
+        for (int[] delta : deltas) {
+            int newX = x + delta[0];
+            int newY = y + delta[1];
+            Position p = new Position(newX, newY);
+            if (board.doesPositionExist(p)) {
+                positions.add(p);
+            }
+        }
+
+        return positions;
+    }
+
+    public static int getManhattanDistance(Position p1, Position p2) {
+        return Math.abs(p1.x() - p2.x()) + Math.abs(p1.y() - p2.y());
+    }
+
 }
\ No newline at end of file
-- 
GitLab