From d87cdf7272a565c2996f8bd7ef13f1ee960085f2 Mon Sep 17 00:00:00 2001
From: Yanis O <oualanyanis01@gmail.com>
Date: Sun, 24 Nov 2024 02:17:52 +0100
Subject: [PATCH] [Ajout] Scenario du Pierre Feuille Ciseaux

---
 src/main/java/controller/Controller.java      |  15 +-
 src/main/java/model/Board.java                |   2 +-
 .../java/model/EntityNotFoundException.java   |   7 +
 src/main/java/model/Scenario.java             |  78 ++---------
 .../firefighterscenario/FireFighter.java      |   7 +-
 .../FireFighterScenario.java                  |   7 +-
 .../MotorizedFireFighter.java                 |   7 +-
 src/main/java/model/rockpapercisor/Cisor.java | 132 ++++++++++++++++++
 src/main/java/model/rockpapercisor/Paper.java | 115 +++++++++++++++
 src/main/java/model/rockpapercisor/Rock.java  | 115 +++++++++++++++
 .../RockPaperCisorScenario.java               |  32 ++++-
 src/main/java/model/virus/Patient.java        |   2 +-
 src/main/java/util/PositionUtil.java          | 127 +++++++++++++++++
 13 files changed, 568 insertions(+), 78 deletions(-)
 create mode 100644 src/main/java/model/EntityNotFoundException.java
 create mode 100644 src/main/java/model/rockpapercisor/Cisor.java
 create mode 100644 src/main/java/model/rockpapercisor/Paper.java
 create mode 100644 src/main/java/model/rockpapercisor/Rock.java

diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index db76418..0785db2 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -23,12 +23,9 @@ import model.Board;
 import model.EntityFactory;
 import model.Model;
 import model.Square;
-import model.firefighterscenario.Cloud;
-import model.firefighterscenario.Fire;
-import model.firefighterscenario.FireFighter;
-import model.firefighterscenario.MotorizedFireFighter;
-import model.firefighterscenario.Mountain;
-import model.firefighterscenario.Rockery;
+import model.rockpapercisor.Cisor;
+import model.rockpapercisor.Paper;
+import model.rockpapercisor.Rock;
 import model.rockpapercisor.RockPaperCisorScenario;
 import util.Position;
 import view.Grid;
@@ -133,13 +130,17 @@ public class Controller {
     grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight);
     
     Map<EntityFactory, Integer> entityCounts = new HashMap<EntityFactory, Integer>();
-
+    /*
     entityCounts.put((pos, b) -> new Fire(pos), initialFireCount);
     entityCounts.put((pos, b) -> new FireFighter(pos,b), initialFirefighterCount);
     entityCounts.put((pos, b) -> new MotorizedFireFighter(pos, b), initialMotorizedFirefightersCount);
     entityCounts.put((pos, b) -> new Cloud(pos, b), initialcloudCount);
     entityCounts.put((pos, b) -> new Mountain(pos), initialmountaincount);
     entityCounts.put((pos, b) -> new Rockery(pos), 3);
+    */
+    entityCounts.put((pos, b) -> new Rock(pos), 100);
+    entityCounts.put((pos, b) -> new Cisor(pos), 100);
+    entityCounts.put((pos, b) -> new Paper(pos), 100);
     Model model = new RockPaperCisorScenario(columnCount, rowCount, entityCounts);
     this.setModel(model);
     repaintGrid();
diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java
index ba9d84b..be1fcb8 100644
--- a/src/main/java/model/Board.java
+++ b/src/main/java/model/Board.java
@@ -63,7 +63,7 @@ public interface Board<S> {
 
   public void clearCaseFrom(Entity entity, Position position);
 
-  public Position getNearestEntity(Position fromPos, Class<?> entityType);
+  public Position getNearestEntity(Position fromPos, Class<?> entityType) throws EntityNotFoundException;
 
   public boolean doesSquareContainEntity(Position squarePos, Class<?> entityType);
 
diff --git a/src/main/java/model/EntityNotFoundException.java b/src/main/java/model/EntityNotFoundException.java
new file mode 100644
index 0000000..9902ad9
--- /dev/null
+++ b/src/main/java/model/EntityNotFoundException.java
@@ -0,0 +1,7 @@
+package model;
+
+class EntityNotFoundException extends Exception {
+    public EntityNotFoundException(String message) {
+        super(message);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/model/Scenario.java b/src/main/java/model/Scenario.java
index eda8cc5..6f04bbc 100644
--- a/src/main/java/model/Scenario.java
+++ b/src/main/java/model/Scenario.java
@@ -3,15 +3,9 @@ package model;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 
 import app.SimulatorApplication;
-import model.firefighterscenario.Fire;
-import model.firefighterscenario.Mountain;
-import model.firefighterscenario.Road;
-import model.firefighterscenario.Rockery;
 import util.Matrix;
-import util.PathGenerator;
 import util.Position;
 import util.PositionUtil;
 
@@ -46,7 +40,6 @@ public class Scenario implements Board<Square>{
   public void placeInitialEntities(Map<EntityFactory, Integer> initialMap) {
     EntitySpawner spawner = new EntitySpawner(this);
     spawner.spawnEntities(initialMap);
-    generateRoads();
     
   }
 
@@ -95,31 +88,31 @@ public class Scenario implements Board<Square>{
     matrix.get(position.x(), position.y()).getEntities().removeIf(element -> element.equals(entity));
   }
 
-  public Position getNearestEntity(Position fromPos, Class<?> entityType) {
+  public Position getNearestEntity(Position fromPos, Class<?> entityType) throws EntityNotFoundException {
     int rows = matrix.getRows();
     int cols = matrix.getColumns();
-    Position nearestPosition = fromPos;
 
     // Définir la distance maximale possible
     int maxDistance = rows + cols;
     // Parcourir les distances croissantes à partir de 1
     for (int distance = 1; distance < maxDistance; distance++) {
-      List<Position> positionsAtDistance = PositionUtil.getPositionsAtManhattanDistance(fromPos, distance, rows, cols);
-
-      for (Position currentPos : positionsAtDistance) {
-        Square currentSquare = matrix.get(currentPos.x(), currentPos.y());
-        for (Entity currentEntity : currentSquare.getEntities()) {
-          if (entityType.isInstance(currentEntity)) {
-            // Dès qu'une entité est trouvée à cette distance, elle est la plus proche
-            // possible
-            return currentPos;
-          }
+        List<Position> positionsAtDistance = PositionUtil.getPositionsAtManhattanDistance(fromPos, distance, rows, cols);
+
+        for (Position currentPos : positionsAtDistance) {
+            Square currentSquare = matrix.get(currentPos.x(), currentPos.y());
+            for (Entity currentEntity : currentSquare.getEntities()) {
+                if (entityType.isInstance(currentEntity)) {
+                    // Dès qu'une entité est trouvée à cette distance, elle est la plus proche possible
+                    return currentPos;
+                }
+            }
         }
-      }
     }
 
-    return nearestPosition; // Retourne null si aucune entité n'est trouvée
-  }
+    // Lever une exception si aucune entité n'est trouvée
+    throw new EntityNotFoundException("Aucune entité de type " + entityType.getSimpleName() + " trouvée à proximité de " + fromPos);
+}
+
 
   public void reset() {
     step = 0;
@@ -163,45 +156,4 @@ public class Scenario implements Board<Square>{
     return true;
   }
 
-  private void generateRoads() {
-    if(columnCount() < 10 || rowCount() < 10){
-      return;
-    }
-    Random random = new Random();
-
-    // Get board dimensions
-    int rowCount = rowCount();      // Number of rows (vertical axis)
-    int columnCount = columnCount(); // Number of columns (horizontal axis)
-
-    // Decide randomly whether to set x or y to 0
-    boolean setXToZero = random.nextBoolean();
-
-    int x = 0;
-    int y = 0;
-
-    if (setXToZero) {
-        // x is set to 0, y is random within column bounds
-        x = 0;
-        y = random.nextInt(columnCount);
-    } else {
-        // y is set to 0, x is random within row bounds
-        x = random.nextInt(rowCount);
-        y = 0;
-    }
-
-    Position startPosition = new Position(x, y);
-    PathGenerator pathGenerator = new PathGenerator(this, startPosition, 4, columnCount());
-    // Call generateEntitiesInLine to place the roads
-    List<Position> snake = pathGenerator.generate();
-    for(Position p : snake){
-      List<Entity> entitiesAtSquare = List.copyOf(getStates(p).getEntities());
-      for(Entity e: entitiesAtSquare){
-        if(e instanceof Mountain || e instanceof Rockery || e instanceof Fire){
-          clearCaseFrom(e, e.getPosition());
-        }
-      }
-      addEntityAtSquare(new Road(p), p);
-    }
-}
-
 }
diff --git a/src/main/java/model/firefighterscenario/FireFighter.java b/src/main/java/model/firefighterscenario/FireFighter.java
index 8adfeba..8238c6e 100644
--- a/src/main/java/model/firefighterscenario/FireFighter.java
+++ b/src/main/java/model/firefighterscenario/FireFighter.java
@@ -107,7 +107,12 @@ public class FireFighter implements Entity {
         List<Position> positions = new ArrayList<>();
     
         // Find the nearest fire
-        Position nearestFirePos = b.getNearestEntity(position, Fire.class);
+        Position nearestFirePos;
+        try {
+            nearestFirePos = b.getNearestEntity(position, Fire.class);
+        } catch (Exception e) {
+            return List.of();
+        }
         if (nearestFirePos != null) {
             // Get the next position towards the fire
             Position nextPos = getNextPositionTowards(position, nearestFirePos, b);
diff --git a/src/main/java/model/firefighterscenario/FireFighterScenario.java b/src/main/java/model/firefighterscenario/FireFighterScenario.java
index 6604278..259c69f 100644
--- a/src/main/java/model/firefighterscenario/FireFighterScenario.java
+++ b/src/main/java/model/firefighterscenario/FireFighterScenario.java
@@ -24,9 +24,12 @@ public class FireFighterScenario extends Scenario implements Model{
   public List<Position> updateToNextGeneration() {
     ArrayList<Position> changedPositions = new ArrayList<>();
     Iterator<Square> iterator = getMatrix().iterator();
-
+    List<Entity> updatedEntities = new ArrayList<Entity>();
+    int i = 0;
     while (iterator.hasNext()) {
       Square s = iterator.next();
+      System.out.println("i : " + i);
+      i++;
       if (s.isEmpty())
         continue;
       if (s.getMaxAge() == 0) {
@@ -38,10 +41,12 @@ public class FireFighterScenario extends Scenario implements Model{
       }
       List<Entity> entities = new ArrayList<>(s.getEntities());
       for (Entity e : entities) {
+        if(updatedEntities.contains(e))continue;
         if (e.getAge() >= stepNumber() - 1) {
           continue;
         }
         e.incrementAge();
+        updatedEntities.add(e);
         changedPositions.addAll(e.nextTurn(this));
       }
     }
diff --git a/src/main/java/model/firefighterscenario/MotorizedFireFighter.java b/src/main/java/model/firefighterscenario/MotorizedFireFighter.java
index 3564d38..7487e31 100644
--- a/src/main/java/model/firefighterscenario/MotorizedFireFighter.java
+++ b/src/main/java/model/firefighterscenario/MotorizedFireFighter.java
@@ -54,7 +54,12 @@ public class MotorizedFireFighter extends FireFighter {
         List<Position> positions = new ArrayList<>();
 
         // Find the nearest fire
-        Position nearestFirePos = b.getNearestEntity(getPosition(), Fire.class);
+        Position nearestFirePos;
+        try {
+            nearestFirePos = b.getNearestEntity(getPosition(), Fire.class);
+        } catch (Exception e) {
+            return List.of();
+        }
         if (nearestFirePos != null) {
             // Get the next position after moving up to two steps towards the fire
             Position nextPos = getNextPositionTowards(getPosition(), nearestFirePos, b, 2);
diff --git a/src/main/java/model/rockpapercisor/Cisor.java b/src/main/java/model/rockpapercisor/Cisor.java
new file mode 100644
index 0000000..b35b5a6
--- /dev/null
+++ b/src/main/java/model/rockpapercisor/Cisor.java
@@ -0,0 +1,132 @@
+package model.rockpapercisor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import javafx.scene.paint.Color;
+import model.Board;
+import model.Entity;
+import model.Square;
+import util.Position;
+import util.PositionUtil;
+
+public class Cisor implements Entity {
+    private final int priority = 0;
+    Position position;
+    private int age;
+    private final Color viewColor = Color.RED;
+
+    public Cisor(Position p) {
+        this.position = p;
+    }
+
+    public Cisor(Position p, int age) {
+        this.position = p;
+        this.age = age;
+    }
+
+    @Override
+    public List<Position> nextTurn(Board<Square> board) {
+        Position target = null;
+        try {
+            target = board.getNearestEntity(position, Paper.class);
+        } catch (Exception e) {
+
+        }
+
+        Position ennemy = null;
+        try {
+            ennemy = board.getNearestEntity(position, Rock.class);
+        } catch (Exception ignored) {
+            // Si aucune entité Rock n'est trouvée, ennemy reste null.
+        }
+        if(ennemy == null && target == null){
+            System.err.println("all null");
+            return List.of();
+        }
+        Position nextPos = null;
+        // Vérifier la proximité d'un ennemi avant de choisir la direction.
+        if (ennemy != null && PositionUtil.getManhattanDistance(position, ennemy) < 5) {
+            nextPos = PositionUtil.getNextPositionAwayFrom(position, ennemy, board);
+        } else if(target != null){
+            nextPos = PositionUtil.getNextPositionTowards(position, target, board);
+        }
+
+        if (nextPos != null && board.doesPositionExist(nextPos)) {
+            board.addEntityAtSquare(this, nextPos);
+            board.clearCaseFrom(this, position);
+            Position oldPosition = new Position(position.x(), position.y());
+            this.position = nextPos;
+            if (board.doesSquareContainEntity(nextPos, Paper.class)) {
+                List<Entity> entities = board.getStates(nextPos).getEntities();
+                entities.removeIf(p -> p instanceof Paper);
+            }
+
+            List<Position> result = new ArrayList<>();
+            if (target != null)
+                result.add(target);
+            if (oldPosition != null)
+                result.add(oldPosition);
+            if (position != null)
+                result.add(position);
+            if (ennemy != null)
+                result.add(ennemy);
+            return result;
+
+        }
+        return List.of();
+    }
+
+    @Override
+    public Position getPosition() {
+        return this.position;
+    }
+
+    @Override
+    public void setPosition(Position p) {
+        this.position = p;
+
+    }
+
+    @Override
+    public int getAge() {
+        return this.age;
+    }
+
+    @Override
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    @Override
+    public void incrementAge() {
+        this.age += 1;
+    }
+
+    @Override
+    public Color getViewColor() {
+        return this.viewColor;
+    }
+
+    @Override
+    public int getPriority() {
+        return this.priority;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null || getClass() != obj.getClass())
+            return false;
+        Cisor cisor = (Cisor) obj;
+        return age == cisor.age &&
+                Objects.equals(position, cisor.position);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(position, age);
+    }
+}
diff --git a/src/main/java/model/rockpapercisor/Paper.java b/src/main/java/model/rockpapercisor/Paper.java
new file mode 100644
index 0000000..9f84aa2
--- /dev/null
+++ b/src/main/java/model/rockpapercisor/Paper.java
@@ -0,0 +1,115 @@
+package model.rockpapercisor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.scene.paint.Color;
+import model.Board;
+import model.Entity;
+import model.Square;
+import util.Position;
+import util.PositionUtil;
+
+public class Paper implements Entity {
+    private final int priority = 0;
+    Position position;
+    private int age;
+    private final Color viewColor = Color.GRAY;
+
+    public Paper(Position p) {
+        this.position = p;
+    }
+
+    public Paper(Position p, int age) {
+        this.position = p;
+        this.age = age;
+    }
+
+    @Override
+    public List<Position> nextTurn(Board<Square> board) {
+        Position target = null;
+        try {
+            target = board.getNearestEntity(position, Rock.class);
+        } catch (Exception e) {
+            
+        }
+
+        Position ennemy = null;
+        try {
+            ennemy = board.getNearestEntity(position, Cisor.class);
+        } catch (Exception ignored) {
+            // Si aucune entité Cisor n'est trouvée, ennemy reste null.
+        }
+        if(ennemy == null && target == null){
+            System.err.println("all null");
+            return List.of();
+        }
+        Position nextPos = null;
+        // Vérifier la proximité d'un ennemi avant de choisir la direction.
+        if (ennemy != null && PositionUtil.getManhattanDistance(position, ennemy) < 5) {
+            nextPos = PositionUtil.getNextPositionAwayFrom(position, ennemy, board);
+        } else if(target != null){
+            nextPos = PositionUtil.getNextPositionTowards(position, target, board);
+        }
+
+        if (nextPos != null && board.doesPositionExist(nextPos)) {
+            board.addEntityAtSquare(this, nextPos);
+            board.clearCaseFrom(this, position);
+            Position oldPosition = new Position(position.x(), position.y());
+            this.position = nextPos;
+            if (board.doesSquareContainEntity(nextPos, Rock.class)) {
+                List<Entity> entities = board.getStates(nextPos).getEntities();
+                entities.removeIf(p -> p instanceof Rock);
+            }
+
+            List<Position> result = new ArrayList<>();
+            if (target != null)
+                result.add(target);
+            if (oldPosition != null)
+                result.add(oldPosition);
+            if (position != null)
+                result.add(position);
+            if (ennemy != null)
+                result.add(ennemy);
+            return result;
+
+        }
+        return List.of();
+    }
+
+    @Override
+    public Position getPosition() {
+        return this.position;
+    }
+
+    @Override
+    public void setPosition(Position p) {
+        this.position = p;
+
+    }
+
+    @Override
+    public int getAge() {
+        return this.age;
+    }
+
+    @Override
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    @Override
+    public void incrementAge() {
+        this.age += 1;
+    }
+
+    @Override
+    public Color getViewColor() {
+        return this.viewColor;
+    }
+
+    @Override
+    public int getPriority() {
+        return this.priority;
+    }
+}
diff --git a/src/main/java/model/rockpapercisor/Rock.java b/src/main/java/model/rockpapercisor/Rock.java
new file mode 100644
index 0000000..b8db7b8
--- /dev/null
+++ b/src/main/java/model/rockpapercisor/Rock.java
@@ -0,0 +1,115 @@
+package model.rockpapercisor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.scene.paint.Color;
+import model.Board;
+import model.Entity;
+import model.Square;
+import util.Position;
+import util.PositionUtil;
+
+public class Rock implements Entity {
+    private final int priority = 0;
+    Position position;
+    private int age;
+    private final Color viewColor = Color.CHOCOLATE;
+
+    public Rock(Position p) {
+        this.position = p;
+    }
+
+    public Rock(Position p, int age) {
+        this.position = p;
+        this.age = age;
+    }
+
+    @Override
+    public List<Position> nextTurn(Board<Square> board) {
+        Position target = null;
+        try {
+            target = board.getNearestEntity(position, Cisor.class);
+        } catch (Exception e) {
+
+        }
+
+        Position ennemy = null;
+        try {
+            ennemy = board.getNearestEntity(position, Paper.class);
+        } catch (Exception ignored) {
+            // Si aucune entité Paper n'est trouvée, ennemy reste null.
+        }
+        if(ennemy == null && target == null){
+            System.err.println("all null");
+            return List.of();
+        }
+        Position nextPos = null;
+        // Vérifier la proximité d'un ennemi avant de choisir la direction.
+        if (ennemy != null && PositionUtil.getManhattanDistance(position, ennemy) < 5) {
+            nextPos = PositionUtil.getNextPositionAwayFrom(position, ennemy, board);
+        } else if(target != null){
+            nextPos = PositionUtil.getNextPositionTowards(position, target, board);
+        }
+
+        if (nextPos != null && board.doesPositionExist(nextPos)) {
+            board.addEntityAtSquare(this, nextPos);
+            board.clearCaseFrom(this, position);
+            Position oldPosition = new Position(position.x(), position.y());
+            this.position = nextPos;
+            if (board.doesSquareContainEntity(nextPos, Cisor.class)) {
+                List<Entity> entities = board.getStates(nextPos).getEntities();
+                entities.removeIf(p -> p instanceof Cisor);
+            }
+
+            List<Position> result = new ArrayList<>();
+            if (target != null)
+                result.add(target);
+            if (oldPosition != null)
+                result.add(oldPosition);
+            if (position != null)
+                result.add(position);
+            if (ennemy != null)
+                result.add(ennemy);
+            return result;
+
+        }
+        return List.of();
+    }
+
+    @Override
+    public Position getPosition() {
+        return this.position;
+    }
+
+    @Override
+    public void setPosition(Position p) {
+        this.position = p;
+
+    }
+
+    @Override
+    public int getAge() {
+        return this.age;
+    }
+
+    @Override
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    @Override
+    public void incrementAge() {
+        this.age += 1;
+    }
+
+    @Override
+    public Color getViewColor() {
+        return this.viewColor;
+    }
+
+    @Override
+    public int getPriority() {
+        return this.priority;
+    }
+}
diff --git a/src/main/java/model/rockpapercisor/RockPaperCisorScenario.java b/src/main/java/model/rockpapercisor/RockPaperCisorScenario.java
index 2d977b1..cdae81b 100644
--- a/src/main/java/model/rockpapercisor/RockPaperCisorScenario.java
+++ b/src/main/java/model/rockpapercisor/RockPaperCisorScenario.java
@@ -1,9 +1,12 @@
 package model.rockpapercisor;
 
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import model.Board;
+import model.Entity;
 import model.EntityFactory;
 import model.Model;
 import model.Scenario;
@@ -15,9 +18,32 @@ public class RockPaperCisorScenario extends Scenario implements Model{
         super(columns, rows, initialMap);
     }
 
-    public List<Position> updateToNextGeneration(){
-        return List.of();
-    }
+    public List<Position> updateToNextGeneration() {
+        ArrayList<Position> changedPositions = new ArrayList<>();
+        Iterator<Square> iterator = getMatrix().iterator();
+        while (iterator.hasNext()) {
+          Square s = iterator.next();
+          if (s.isEmpty())
+            continue;
+          if (s.getMaxAge() == 0) {
+            s.incrementAllAges();
+            continue;
+          }
+          if(s.getMaxAge()>stepNumber()+1){
+            continue;
+          }
+          List<Entity> entities = new ArrayList<>(s.getEntities());
+          for (Entity e : entities) {
+            e.incrementAge();
+            changedPositions.addAll(e.nextTurn(this));
+          }
+        }
+        
+        // Increment the step counter
+        this.step = this.step + 1;
+        System.out.println("-----------");
+        return changedPositions;
+      }
 
     @Override
     public Board<Square> getBoard() {
diff --git a/src/main/java/model/virus/Patient.java b/src/main/java/model/virus/Patient.java
index 28c7c7c..204d18a 100644
--- a/src/main/java/model/virus/Patient.java
+++ b/src/main/java/model/virus/Patient.java
@@ -1,4 +1,4 @@
-package model.rockpapercisor;
+package model.virus;
 
 import java.util.List;
 
diff --git a/src/main/java/util/PositionUtil.java b/src/main/java/util/PositionUtil.java
index 0a3f901..39a8910 100644
--- a/src/main/java/util/PositionUtil.java
+++ b/src/main/java/util/PositionUtil.java
@@ -2,11 +2,14 @@ package util;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Random;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import model.Board;
 import model.Square;
+import model.firefighterscenario.FireFighter;
+import model.firefighterscenario.Mountain;
 
 public class PositionUtil {
     /**
@@ -153,4 +156,128 @@ public class PositionUtil {
         return positions;
     }
 
+
+    public static Position getNextPositionTowards(Position currentPos, Position targetPos, Board<Square> b) {
+        // Generate adjacent positions
+        List<Position> possibleMoves = PositionUtil.generateAllAdjacentPositions(currentPos, b);
+    
+        // Filter out positions that are not empty or contain obstacles
+        possibleMoves.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
+    
+        // If no possible moves, return null
+        if (possibleMoves.isEmpty()) {
+            return null;
+        }
+    
+        // Calculate the current distance to the target
+        int currentDistance = PositionUtil.getManhattanDistance(currentPos, targetPos);
+    
+        // Initialize variables to find the best moves
+        int minDistance = Integer.MAX_VALUE;
+        List<Position> bestMoves = new ArrayList<>();
+    
+        for (Position move : possibleMoves) {
+            int distance = PositionUtil.getManhattanDistance(move, targetPos);
+    
+            // Skip positions occupied by other firefighters
+            if (b.doesSquareContainEntity(move, FireFighter.class)) {
+                continue;
+            }
+    
+            // Find positions that minimize the distance
+            if (distance < minDistance) {
+                minDistance = distance;
+                bestMoves.clear();
+                bestMoves.add(move);
+            } else if (distance == minDistance) {
+                bestMoves.add(move);
+            }
+        }
+    
+        // If no better move is found, consider moves that maintain the same distance
+        if (bestMoves.isEmpty()) {
+            minDistance = currentDistance;
+            for (Position move : possibleMoves) {
+                int distance = PositionUtil.getManhattanDistance(move, targetPos);
+                if (distance == minDistance) {
+                    bestMoves.add(move);
+                }
+            }
+        }
+    
+        // If still no move is found, stay in the current position
+        if (bestMoves.isEmpty()) {
+            return currentPos;
+        }
+    
+        // Select a move from the best moves (e.g., randomly or based on additional criteria)
+        Random r = new Random();
+        
+        Position nextMove = bestMoves.get(r.nextInt(bestMoves.size()));
+    
+        return nextMove;
+    }
+
+    public static Position getNextPositionAwayFrom(Position currentPos, Position targetPos, Board<Square> b) {
+        // Générer les positions adjacentes
+        List<Position> possibleMoves = PositionUtil.generateAllAdjacentPositions(currentPos, b);
+    
+        // Filtrer les positions qui ne sont pas vides ou contiennent des obstacles
+        possibleMoves.removeIf(p -> b.doesSquareContainEntity(p, Mountain.class));
+    
+        // Si aucune possibilité de déplacement, retourner null
+        if (possibleMoves.isEmpty()) {
+            return null;
+        }
+    
+        // Calculer la distance actuelle par rapport à la cible
+        int currentDistance = PositionUtil.getManhattanDistance(currentPos, targetPos);
+    
+        // Initialiser les variables pour trouver les meilleurs déplacements
+        int maxDistance = Integer.MIN_VALUE;
+        List<Position> bestMoves = new ArrayList<>();
+    
+        for (Position move : possibleMoves) {
+            int distance = PositionUtil.getManhattanDistance(move, targetPos);
+    
+            // Ignorer les positions occupées par d'autres entités, comme les pompiers
+            if (b.doesSquareContainEntity(move, FireFighter.class)) {
+                continue;
+            }
+    
+            // Trouver les positions qui maximisent la distance
+            if (distance > maxDistance) {
+                maxDistance = distance;
+                bestMoves.clear();
+                bestMoves.add(move);
+            } else if (distance == maxDistance) {
+                bestMoves.add(move);
+            }
+        }
+    
+        // Si aucun meilleur déplacement n'est trouvé, considérer les mouvements qui maintiennent la même distance
+        if (bestMoves.isEmpty()) {
+            maxDistance = currentDistance;
+            for (Position move : possibleMoves) {
+                int distance = PositionUtil.getManhattanDistance(move, targetPos);
+                if (distance == maxDistance) {
+                    bestMoves.add(move);
+                }
+            }
+        }
+    
+        // Si toujours aucun mouvement n'est trouvé, rester à la position actuelle
+        if (bestMoves.isEmpty()) {
+            return currentPos;
+        }
+    
+        // Sélectionner un mouvement parmi les meilleurs mouvements (par exemple aléatoirement ou selon des critères supplémentaires)
+        Random r = new Random();
+    
+        Position nextMove = bestMoves.get(r.nextInt(bestMoves.size()));
+    
+        return nextMove;
+    }
+    
+
 }
\ No newline at end of file
-- 
GitLab