From 4be08dcb6a7623041b0598d4ce836d2e34c96962 Mon Sep 17 00:00:00 2001
From: Yanis O <oualanyanis01@gmail.com>
Date: Wed, 27 Nov 2024 13:13:18 +0100
Subject: [PATCH] =?UTF-8?q?Ajout=20du=20sc=C3=A9nario=20Docteur=20Virus=20?=
 =?UTF-8?q?Patient,=20et=20d=C3=A9but=20impl=C3=A9mentation=20de=20la=20lo?=
 =?UTF-8?q?gique=20des=20Patients?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 scenariovirus.txt                             |  15 ++
 src/main/java/controller/Controller.java      |  15 +-
 src/main/java/model/Board.java                |   3 +-
 src/main/java/model/EntitySpawner.java        |  17 +-
 src/main/java/model/Scenario.java             |  15 +-
 .../DoctorVirusPatientScenario.java           |  55 ++++
 .../model/doctorviruspatient/Patient.java     | 254 ++++++++++++++++++
 .../java/model/doctorviruspatient/Virus.java  |  69 +++++
 .../firefighterscenario/FireFighter.java      |   2 +-
 .../MotorizedFireFighter.java                 |   2 +-
 src/main/java/model/rockpapercisor/Cisor.java |  13 +-
 src/main/java/model/rockpapercisor/Paper.java |  12 +-
 src/main/java/model/rockpapercisor/Rock.java  |  13 +-
 src/main/java/util/PositionUtil.java          |  43 ++-
 14 files changed, 468 insertions(+), 60 deletions(-)
 create mode 100644 scenariovirus.txt
 create mode 100644 src/main/java/model/doctorviruspatient/DoctorVirusPatientScenario.java
 create mode 100644 src/main/java/model/doctorviruspatient/Patient.java
 create mode 100644 src/main/java/model/doctorviruspatient/Virus.java

diff --git a/scenariovirus.txt b/scenariovirus.txt
new file mode 100644
index 0000000..d43e533
--- /dev/null
+++ b/scenariovirus.txt
@@ -0,0 +1,15 @@
+Patients : 
+- Interactions et mouvement : Se déplacent et interagissent socialement, augmentant ainsi les chances de transmission du virus. Certains peuvent être asymptomatiques.
+- Réaction en cas de maladie : S'ils se rendent compte qu'ils sont malades, ils cherchent un docteur pour se faire soigner. Sinon, ils continuent leur vie normalement, pouvant transmettre le virus sans le savoir.
+
+
+Virus : 
+- Mouvement et infection : Entité unique sur le plateau qui se déplace aléatoirement, infectant les patients lorsqu'il passe à proximité.
+- Le virus infecte les patients lorsqu'il passe à proximité.
+- Évolue tous les 30 tours pour donner un nouveau variant, lorsqu'un nouveau variant est détecté, les médecins mettent plus de temps à le soigner au début
+
+
+Docteurs : 
+- Traitement des patients : Traitent les patients malades qui se trouvent dans des cases adjacentes à leur position.
+- Statique : Ne se déplacent pas entre les tours, ce qui nécessite que les patients viennent à eux pour être soignés.
+
diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index 7ebb8ba..7ad1c20 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -23,10 +23,9 @@ import model.Board;
 import model.EntityFactory;
 import model.Model;
 import model.Square;
-import model.rockpapercisor.Cisor;
-import model.rockpapercisor.Paper;
-import model.rockpapercisor.Rock;
-import model.rockpapercisor.RockPaperCisorScenario;
+import model.doctorviruspatient.DoctorVirusPatientScenario;
+import model.doctorviruspatient.Patient;
+import model.virus.Virus;
 import util.Position;
 import view.Grid;
 import view.ViewElement;
@@ -138,14 +137,18 @@ public class Controller {
     entityCounts.put((pos, b) -> new Mountain(pos), initialmountaincount);
     entityCounts.put((pos, b) -> new Rockery(pos), 3);
     */
+    /*
     entityCounts.put((pos, b) -> new Rock(pos), 10);
     entityCounts.put((pos, b) -> new Cisor(pos), 10);
     entityCounts.put((pos, b) -> new Paper(pos), 10);
-    Model model = new RockPaperCisorScenario(columnCount, rowCount, entityCounts);
+    */
+    entityCounts.put((pos, b) -> new Patient(pos), 10);
+    entityCounts.put((pos, b) -> new Virus(pos), 1);
+    Model model = new DoctorVirusPatientScenario(columnCount, rowCount, entityCounts);
     this.setModel(model);
     repaintGrid();
   }
-
+  
   public void oneStepButtonAction() {
     this.pause();
     updateBoard();
diff --git a/src/main/java/model/Board.java b/src/main/java/model/Board.java
index be1fcb8..6fc78dd 100644
--- a/src/main/java/model/Board.java
+++ b/src/main/java/model/Board.java
@@ -1,5 +1,6 @@
 package model;
 
+import java.util.List;
 import java.util.Map;
 
 import util.Position;
@@ -63,7 +64,7 @@ public interface Board<S> {
 
   public void clearCaseFrom(Entity entity, Position position);
 
-  public Position getNearestEntity(Position fromPos, Class<?> entityType) throws EntityNotFoundException;
+  public Position getNearestEntity(Position fromPos, Class<?> entityType, List<Entity> exclusionList);
 
   public boolean doesSquareContainEntity(Position squarePos, Class<?> entityType);
 
diff --git a/src/main/java/model/EntitySpawner.java b/src/main/java/model/EntitySpawner.java
index c8f0de6..bd6fa6e 100644
--- a/src/main/java/model/EntitySpawner.java
+++ b/src/main/java/model/EntitySpawner.java
@@ -12,6 +12,7 @@ import java.util.Set;
 
 import util.Direction;
 import util.Position;
+import util.PositionUtil;
 
 public class EntitySpawner {
     private final Board<Square> board;
@@ -120,7 +121,7 @@ public class EntitySpawner {
         int roadLength = 1;
     
         // Déterminer la direction interdite (opposée à la direction initiale)
-        Direction forbiddenDirection = getOppositeDirection(initialDirection);
+        Direction forbiddenDirection = PositionUtil.getOppositeDirection(initialDirection);
     
         // Initialiser la direction courante
         Direction currentDirection = initialDirection;
@@ -163,7 +164,7 @@ public class EntitySpawner {
     
                     // Mettre à jour la direction courante
                     currentDirection = newDirection;
-                    forbiddenDirection = getOppositeDirection(currentDirection);
+                    forbiddenDirection = PositionUtil.getOppositeDirection(currentDirection);
                     stepsInCurrentDirection = 0;
                     continue; // Recommencer avec la nouvelle direction
                 } else {
@@ -185,7 +186,7 @@ public class EntitySpawner {
     
                 // Mettre à jour la direction courante
                 currentDirection = newDirection;
-                forbiddenDirection = getOppositeDirection(currentDirection);
+                forbiddenDirection = PositionUtil.getOppositeDirection(currentDirection);
                 stepsInCurrentDirection = 0;
             }
         }
@@ -249,15 +250,7 @@ public class EntitySpawner {
         }
     }
     
-    private static Direction getOppositeDirection(Direction direction) {
-        switch (direction) {
-            case NORTH: return Direction.SOUTH;
-            case SOUTH: return Direction.NORTH;
-            case EAST:  return Direction.WEST;
-            case WEST:  return Direction.EAST;
-            default:    throw new IllegalArgumentException("Direction non supportée : " + direction);
-        }
-    }
+
     
     
     
diff --git a/src/main/java/model/Scenario.java b/src/main/java/model/Scenario.java
index 6f04bbc..e58abb8 100644
--- a/src/main/java/model/Scenario.java
+++ b/src/main/java/model/Scenario.java
@@ -88,29 +88,28 @@ 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) throws EntityNotFoundException {
+  public Position getNearestEntity(Position fromPos, Class<?> entityType, List<Entity> exclusionList) {
     int rows = matrix.getRows();
     int cols = matrix.getColumns();
-
     // 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) {
+          if(isPositionEmpty(currentPos))continue;
             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
+                if (entityType.isInstance(currentEntity) && exclusionList != null && !exclusionList.contains(currentEntity)) {
+                    // Vérifie si l'entité actuelle n'est pas dans la liste des exclusions
+                    // Dès qu'une entité éligible est trouvée à cette distance, elle est la plus proche possible
                     return currentPos;
                 }
             }
         }
     }
-
-    // Lever une exception si aucune entité n'est trouvée
-    throw new EntityNotFoundException("Aucune entité de type " + entityType.getSimpleName() + " trouvée à proximité de " + fromPos);
+    return null; // Retourne null si aucune entité éligible n'est trouvée
 }
 
 
diff --git a/src/main/java/model/doctorviruspatient/DoctorVirusPatientScenario.java b/src/main/java/model/doctorviruspatient/DoctorVirusPatientScenario.java
new file mode 100644
index 0000000..b22bf73
--- /dev/null
+++ b/src/main/java/model/doctorviruspatient/DoctorVirusPatientScenario.java
@@ -0,0 +1,55 @@
+package model.doctorviruspatient;
+
+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;
+import model.Square;
+import util.Position;
+
+public class DoctorVirusPatientScenario extends Scenario implements Model{
+    public DoctorVirusPatientScenario(int columns, int rows, Map<EntityFactory, Integer> initialMap) {
+        super(columns, rows, initialMap);
+    }
+
+    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;
+        return changedPositions;
+      }
+
+
+      
+    @Override
+    public Board<Square> getBoard() {
+        return this;
+    }
+
+
+}
diff --git a/src/main/java/model/doctorviruspatient/Patient.java b/src/main/java/model/doctorviruspatient/Patient.java
new file mode 100644
index 0000000..0d17595
--- /dev/null
+++ b/src/main/java/model/doctorviruspatient/Patient.java
@@ -0,0 +1,254 @@
+package model.doctorviruspatient;
+
+import java.util.ArrayList;
+import java.util.Collections;
+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 Patient implements Entity {
+    private final int priority = 0;
+    Position position;
+    private int age;
+    private final Color viewColor = Color.BLUE;
+    private Virus carriedVirus;
+    List<Entity> visitedPatients;
+    private static int patientsCount = 0;
+    private int patientID;
+    private Position ennemy;
+    private boolean wandering;
+
+    public Patient(Position p) {
+        this.wandering = true;
+        patientID = patientsCount;
+        patientsCount += 1;
+        this.visitedPatients = new ArrayList<Entity>();
+        this.position = p;
+    }
+
+    public Patient(Position p, int age) {
+        this.wandering = true;
+        patientID = patientsCount;
+        patientsCount += 1;
+        this.visitedPatients = new ArrayList<Entity>();
+        this.position = p;
+        this.age = age;
+    }
+
+    @Override
+    public List<Position> nextTurn(Board<Square> board) {
+        updateWanderingStatus(board);
+    
+        if (wandering) {
+            return performWandering(board);
+        }
+    
+        resetVisitedPatientsIfNecessary();
+    
+        Position target = determineTarget(board);
+    
+        if (target == null) {
+            visitedPatients.clear();
+            return List.of();
+        }
+    
+        Position nextPos = determineNextPosition(target, board);
+    
+        if (nextPos != null && board.doesPositionExist(nextPos)) {
+            
+            List<Position> adjacentPositions = PositionUtil.generateAllAdjacentPositions(nextPos, board);
+            List<Position> result = interactWithAdjacentPositions(adjacentPositions, board);
+            result.addAll(moveToPosition(nextPos, board));
+            result.addAll(adjacentPositions);
+            result.add(position);
+            return result;
+        }
+    
+        return List.of();
+    }
+    
+    
+    private void updateWanderingStatus(Board<Square> board) {
+    if (board.getStepNumber() % 8 == 0) {
+        wandering = false;
+    }
+}
+
+private List<Position> performWandering(Board<Square> board) {
+    List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, board);
+    Collections.shuffle(adjacentPositions);
+
+    Position oldPosition = position;
+    Position newPosition = adjacentPositions.get(0);
+
+    moveEntityOnBoard(oldPosition, newPosition, board);
+    return List.of(newPosition, oldPosition);
+}
+
+private void resetVisitedPatientsIfNecessary() {
+    if (visitedPatients.size() - 1 >= patientsCount) {
+        visitedPatients.clear();
+    }
+}
+
+private Position determineTarget(Board<Square> board) {
+    return board.getNearestEntity(position, Patient.class, getVisitedPatients());
+}
+
+private Position determineNextPosition(Position target, Board<Square> board) {
+    int enemyDistance = PositionUtil.getManhattanDistance(target, position);
+
+    if (ennemy != null && enemyDistance < 2) {
+        return PositionUtil.getNextPositionAwayFrom(position, target, board);
+    } else if (target != null) {
+        return PositionUtil.getNextPositionTowards(position, target, board);
+    }
+    return null;
+}
+
+private List<Position> moveToPosition(Position nextPos, Board<Square> board) {
+    if (!board.isPositionFree(nextPos, priority)) {
+        nextPos = findAlternativePosition(nextPos, board);
+    }
+
+    if (nextPos != null) {
+        Position oldPosition = position;
+        moveEntityOnBoard(oldPosition, nextPos, board);
+    }
+    
+    return List.of(new Position(this.position.x(), this.position.y()), nextPos);
+}
+
+private Position findAlternativePosition(Position currentPos, Board<Square> board) {
+    List<Position> adjacentPositions = PositionUtil.generateAdjacentPositions(position, board);
+    for (Position p : adjacentPositions) {
+        if (ennemy != null) {
+            Position awayPos = PositionUtil.getNextPositionAwayFrom(p, ennemy, board);
+            if (p.equals(awayPos)) {
+                // Si la position reste la même après avoir tenté de s'éloigner, on continue
+                continue;
+            }
+        }
+        if (board.isPositionFree(p, priority)) {
+            return p;
+        }
+    }
+    return null;
+}
+
+
+private void moveEntityOnBoard(Position oldPosition, Position newPosition, Board<Square> board) {
+    board.clearCaseFrom(this, oldPosition);
+    board.addEntityAtSquare(this, newPosition);
+    this.position = newPosition;
+}
+
+private List<Position> interactWithAdjacentPositions(List<Position> adjacentPositions, Board<Square> board) {
+    List<Position> result = new ArrayList<>();
+    for (Position p : adjacentPositions) {
+        if (board.doesSquareContainEntity(p, Patient.class)) {
+            handleEncounterWithPatient(p, board);
+            if (isInfected()) {
+                result.addAll(adjacentPositions);
+            }
+        }
+    }
+    return result;
+}
+
+private void handleEncounterWithPatient(Position p, Board<Square> board) {
+    this.wandering = true;
+    Patient patient = (Patient) board.getStates(p).getEntities().stream()
+        .filter(entity -> entity instanceof Patient)
+        .findFirst()
+        .orElse(null);
+
+    if (patient != null) {
+        this.ennemy = patient.getPosition();
+        visitedPatients.add(patient);
+    }
+}
+
+
+    @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;
+    }
+
+    public boolean isInfected(){
+        return this.carriedVirus != null;
+    }
+
+    public void infect(Virus virus){
+        this.carriedVirus = virus;
+    }
+
+    public Virus getVirus(){
+        return this.carriedVirus;
+    }
+    
+    public List<Entity> getVisitedPatients(){
+        return this.visitedPatients;
+    }
+
+    public boolean hasVisited(Patient patient){
+        return this.getVisitedPatients().contains(patient);
+    }
+
+    public int getPatientId(){
+        return this.patientID;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if(obj instanceof Patient){
+            Patient other = (Patient) obj;
+            return this.patientID == other.getPatientId();
+        }else{
+            return false;
+        }
+        
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(patientID);
+    }
+}
diff --git a/src/main/java/model/doctorviruspatient/Virus.java b/src/main/java/model/doctorviruspatient/Virus.java
new file mode 100644
index 0000000..8ea8b6b
--- /dev/null
+++ b/src/main/java/model/doctorviruspatient/Virus.java
@@ -0,0 +1,69 @@
+package model.doctorviruspatient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javafx.scene.paint.Color;
+import model.Board;
+import model.Entity;
+import model.Square;
+import model.rockpapercisor.Rock;
+import util.Position;
+import util.PositionUtil;
+
+public class Virus implements Entity {
+    private final int priority = 0;
+    Position position;
+    private int age;
+    private final Color viewColor = Color.LIMEGREEN;
+
+    public Virus(Position p) {
+        this.position = p;
+    }
+
+    public Virus(Position p, int age) {
+        this.position = p;
+        this.age = age;
+    }
+
+    @Override
+    public List<Position> nextTurn(Board<Square> board) {
+        
+    }
+
+    @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/firefighterscenario/FireFighter.java b/src/main/java/model/firefighterscenario/FireFighter.java
index 8238c6e..37e658f 100644
--- a/src/main/java/model/firefighterscenario/FireFighter.java
+++ b/src/main/java/model/firefighterscenario/FireFighter.java
@@ -109,7 +109,7 @@ public class FireFighter implements Entity {
         // Find the nearest fire
         Position nearestFirePos;
         try {
-            nearestFirePos = b.getNearestEntity(position, Fire.class);
+            nearestFirePos = b.getNearestEntity(position, Fire.class, null);
         } catch (Exception e) {
             return List.of();
         }
diff --git a/src/main/java/model/firefighterscenario/MotorizedFireFighter.java b/src/main/java/model/firefighterscenario/MotorizedFireFighter.java
index 7487e31..b870768 100644
--- a/src/main/java/model/firefighterscenario/MotorizedFireFighter.java
+++ b/src/main/java/model/firefighterscenario/MotorizedFireFighter.java
@@ -56,7 +56,7 @@ public class MotorizedFireFighter extends FireFighter {
         // Find the nearest fire
         Position nearestFirePos;
         try {
-            nearestFirePos = b.getNearestEntity(getPosition(), Fire.class);
+            nearestFirePos = b.getNearestEntity(getPosition(), Fire.class, null);
         } catch (Exception e) {
             return List.of();
         }
diff --git a/src/main/java/model/rockpapercisor/Cisor.java b/src/main/java/model/rockpapercisor/Cisor.java
index efbcfa7..10566b8 100644
--- a/src/main/java/model/rockpapercisor/Cisor.java
+++ b/src/main/java/model/rockpapercisor/Cisor.java
@@ -29,18 +29,11 @@ public class Cisor implements Entity {
     @Override
     public List<Position> nextTurn(Board<Square> board) {
         Position target = null;
-        try {
-            target = board.getNearestEntity(position, Paper.class);
-        } catch (Exception e) {
-
-        }
+        target = board.getNearestEntity(position, Paper.class, null);
 
         Position ennemy = null;
-        try {
-            ennemy = board.getNearestEntity(position, Rock.class);
-        } catch (Exception ignored) {
-            // Si aucune entité Rock n'est trouvée, ennemy reste null.
-        }
+
+        ennemy = board.getNearestEntity(position, Rock.class, null);
         if(ennemy == null && target == null){
             return List.of();
         }
diff --git a/src/main/java/model/rockpapercisor/Paper.java b/src/main/java/model/rockpapercisor/Paper.java
index 2d28a91..1c9117c 100644
--- a/src/main/java/model/rockpapercisor/Paper.java
+++ b/src/main/java/model/rockpapercisor/Paper.java
@@ -28,18 +28,10 @@ public class Paper implements Entity {
     @Override
     public List<Position> nextTurn(Board<Square> board) {
         Position target = null;
-        try {
-            target = board.getNearestEntity(position, Rock.class);
-        } catch (Exception e) {
-            
-        }
+        target = board.getNearestEntity(position, Rock.class, null);
 
         Position ennemy = null;
-        try {
-            ennemy = board.getNearestEntity(position, Cisor.class);
-        } catch (Exception ignored) {
-            // Si aucune entité Cisor n'est trouvée, ennemy reste null.
-        }
+        ennemy = board.getNearestEntity(position, Cisor.class, null);
         if(ennemy == null && target == null){
             return List.of();
         }
diff --git a/src/main/java/model/rockpapercisor/Rock.java b/src/main/java/model/rockpapercisor/Rock.java
index 57a0d3e..1671a13 100644
--- a/src/main/java/model/rockpapercisor/Rock.java
+++ b/src/main/java/model/rockpapercisor/Rock.java
@@ -28,18 +28,11 @@ public class Rock implements Entity {
     @Override
     public List<Position> nextTurn(Board<Square> board) {
         Position target = null;
-        try {
-            target = board.getNearestEntity(position, Cisor.class);
-        } catch (Exception e) {
-
-        }
+        target = board.getNearestEntity(position, Cisor.class, null);
 
         Position ennemy = null;
-        try {
-            ennemy = board.getNearestEntity(position, Paper.class);
-        } catch (Exception ignored) {
-            // Si aucune entité Paper n'est trouvée, ennemy reste null.
-        }
+        ennemy = board.getNearestEntity(position, Paper.class, null);
+
         if(ennemy == null && target == null){
             return List.of();
         }
diff --git a/src/main/java/util/PositionUtil.java b/src/main/java/util/PositionUtil.java
index 39a8910..096c290 100644
--- a/src/main/java/util/PositionUtil.java
+++ b/src/main/java/util/PositionUtil.java
@@ -278,6 +278,47 @@ public class PositionUtil {
     
         return nextMove;
     }
-    
+    public static Direction getOppositeDirection(Direction direction) {
+        switch (direction) {
+            case NORTH: return Direction.SOUTH;
+            case SOUTH: return Direction.NORTH;
+            case EAST:  return Direction.WEST;
+            case WEST:  return Direction.EAST;
+            default:    throw new IllegalArgumentException("Direction non supportée : " + direction);
+        }
+    }
+
+    /**
+ * Détermine la direction principale (NORTH, SOUTH, EAST, WEST) de toPos par rapport à fromPos.
+ *
+ * @param fromPos la position de départ.
+ * @param toPos   la position de destination.
+ * @return la direction principale de toPos par rapport à fromPos.
+ */
+public static Direction getDirectionFromTwoPoints(Position fromPos, Position toPos) {
+    int deltaX = toPos.x() - fromPos.x();
+    int deltaY = toPos.y() - fromPos.y();
+
+    if (deltaX == 0 && deltaY == 0) {
+        return null; // Les positions sont identiques
+    }
+
+    if (Math.abs(deltaX) > Math.abs(deltaY)) {
+        // Mouvement principalement vers l'Est ou l'Ouest
+        if (deltaX > 0) {
+            return Direction.EAST;
+        } else {
+            return Direction.WEST;
+        }
+    } else {
+        // Mouvement principalement vers le Nord ou le Sud
+        if (deltaY > 0) {
+            return Direction.SOUTH;
+        } else {
+            return Direction.NORTH;
+        }
+    }
+}
+
 
 }
\ No newline at end of file
-- 
GitLab