diff --git a/src/main/java/app/SimulatorApplication.java b/src/main/java/app/SimulatorApplication.java
index 076797034356054523760c0b7cca79e2446b762a..e599a547f731aa93c242499313608944adfc7883 100644
--- a/src/main/java/app/SimulatorApplication.java
+++ b/src/main/java/app/SimulatorApplication.java
@@ -13,16 +13,16 @@ import javafx.stage.Stage;
 public class SimulatorApplication extends javafx.application.Application {
   private static final String VIEW_RESOURCE_PATH = "/view/view.fxml";
   private static final String APP_NAME = "Firefighter simulator";
-  private static final int ROW_COUNT = 40;
-  private static final int COLUMN_COUNT = 40;
-  private static final int BOX_WIDTH = 15;
-  private static final int BOX_HEIGHT = 15;
-  public static final int INITIAL_FIRE_COUNT = 4;
-  public static final int INITIAL_FIREFIGHTER_COUNT = 18;
-  public static final int INITIAL_MOTORIZED_FIREFIGHTER_COUNT = 5;
-  public static final int INITIAL_CLOUD_COUNT = 9;
-  public static final int INITIAL_MOUNTAIN_COUNT= 18;
-  public static final int TURNS_FOR_SPAWNING_AIRTANKER = 8;
+  private static final int ROW_COUNT = 80;
+  private static final int COLUMN_COUNT = 80;
+  private static final int BOX_WIDTH = 8;
+  private static final int BOX_HEIGHT = 8;
+  public static final int INITIAL_FIRE_COUNT = 6;
+  public static final int INITIAL_FIREFIGHTER_COUNT = 32;
+  public static final int INITIAL_MOTORIZED_FIREFIGHTER_COUNT = 10;
+  public static final int INITIAL_CLOUD_COUNT = 15;
+  public static final int INITIAL_MOUNTAIN_COUNT= 28;
+  public static final int TURNS_FOR_SPAWNING_AIRTANKER = 4;
 
   private Stage primaryStage;
   private Parent view;
diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index ae28563066b8de289df950dac99fb61a437c3379..f77e3487811237db97b10afc8d9fa3fd221a28c9 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -128,7 +128,7 @@ public class Controller {
       int rowCount, int initialFireCount, int initialFirefighterCount, int initialMotorizedFirefightersCount, int initialcloudCount, int initialmountaincount, int turnsForSpawningAirTanker) {
     grid.setDimensions(columnCount, rowCount, squareWidth, squareHeight);
     Board<Square> model = new FireFighterScenario(columnCount, rowCount);
-    Map<EntityFactory, Integer> entityCounts = new HashMap<>();
+    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);
diff --git a/src/main/java/model/EntitySpawner.java b/src/main/java/model/EntitySpawner.java
index 475625f36ee2ac40cb629dfc0906adb01371aca7..c8f0de6aaa1e51b620125129ff323268c92f6d96 100644
--- a/src/main/java/model/EntitySpawner.java
+++ b/src/main/java/model/EntitySpawner.java
@@ -1,12 +1,16 @@
 package model;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
+import java.util.Set;
 
+import util.Direction;
 import util.Position;
 
 public class EntitySpawner {
@@ -68,4 +72,198 @@ public class EntitySpawner {
         }
         return positions;
     }
+
+    public static void generateEntitiesInLine(Board<Square> board, Position anchor, EntityFactory entityFactory) {
+        int xIncrement = 0;
+        int yIncrement = 0;
+    
+        // Determine increments based on which coordinate is zero
+        if (anchor.x() == 0 && anchor.y() >= 0) {
+            // Starting from the left edge (x == 0), increment x to move right
+            xIncrement = 1;
+        } else if (anchor.y() == 0 && anchor.x() >= 0) {
+            // Starting from the top edge (y == 0), increment y to move down
+            yIncrement = 1;
+        } else {
+            // If neither x nor y is 0, cannot determine direction
+            throw new IllegalArgumentException("Anchor position must have x or y equal to 0");
+        }
+    
+        int x = anchor.x();
+        int y = anchor.y();
+    
+        // Continue until we reach the edge of the board
+        while (board.doesPositionExist(new Position(x, y))) {
+            Position pos = new Position(x, y);
+            // Create a new entity for each position
+            Entity entity = entityFactory.create(pos, board);
+            entity.setPosition(pos); // Set the position if not already set in the factory
+            board.addEntityAtSquare(entity, pos);
+    
+            x += xIncrement;
+            y += yIncrement;
+        }
+    }
+    
+    public static List<Position> generateEntitiesInRandomLine(Board<Square> board, Position anchor, int maxStepsInDirection, int minimumRoadLength) {
+        Random random = new Random();
+        List<Position> path = new ArrayList<>();
+        int x = anchor.x();
+        int y = anchor.y();
+    
+        // Toutes les directions possibles
+        List<Direction> allDirections = Arrays.asList(Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST);
+    
+        // Choisir une direction initiale aléatoire
+        Direction initialDirection = allDirections.get(random.nextInt(allDirections.size()));
+        path.add(new Position(x, y)); // Ajouter la position de l'ancre au chemin
+        int roadLength = 1;
+    
+        // Déterminer la direction interdite (opposée à la direction initiale)
+        Direction forbiddenDirection = getOppositeDirection(initialDirection);
+    
+        // Initialiser la direction courante
+        Direction currentDirection = initialDirection;
+        int stepsInCurrentDirection = 0;
+    
+        // Ensemble des directions définitivement exclues (direction initiale)
+        Set<Direction> permanentlyExcludedDirections = new HashSet<>();
+        permanentlyExcludedDirections.add(initialDirection);
+    
+        // Ensemble des directions temporairement exclues (initialement vide)
+        Set<Direction> temporarilyExcludedDirections = new HashSet<>();
+    
+        while (true) {
+            // Calculer la prochaine position dans la direction courante
+            int nextX = x + getXIncrement(currentDirection);
+            int nextY = y + getYIncrement(currentDirection);
+            Position nextPos = new Position(nextX, nextY);
+    
+            if (board.doesPositionExist(nextPos)) {
+                // Ajouter la position au chemin
+                path.add(nextPos);
+                x = nextX;
+                y = nextY;
+                roadLength++;
+                stepsInCurrentDirection++;
+            } else {
+                // La position dans la direction courante est invalide
+                if (roadLength < minimumRoadLength) {
+                    // Exclure temporairement la direction courante
+                    temporarilyExcludedDirections.add(currentDirection);
+    
+                    // Choisir une nouvelle direction valide
+                    Direction newDirection = chooseNewDirection(allDirections, currentDirection, forbiddenDirection, 
+                            permanentlyExcludedDirections, temporarilyExcludedDirections, board, x, y, random);
+    
+                    if (newDirection == null) {
+                        // Aucune direction valide disponible pour atteindre la longueur minimale
+                        break;
+                    }
+    
+                    // Mettre à jour la direction courante
+                    currentDirection = newDirection;
+                    forbiddenDirection = getOppositeDirection(currentDirection);
+                    stepsInCurrentDirection = 0;
+                    continue; // Recommencer avec la nouvelle direction
+                } else {
+                    // La longueur minimale est atteinte, arrêter la génération
+                    break;
+                }
+            }
+    
+            // Vérifier s'il est temps de changer de direction
+            if (stepsInCurrentDirection >= maxStepsInDirection) {
+                // Choisir une nouvelle direction
+                Direction newDirection = chooseNewDirection(allDirections, currentDirection, forbiddenDirection, 
+                        permanentlyExcludedDirections, temporarilyExcludedDirections, board, x, y, random);
+    
+                if (newDirection == null) {
+                    // Aucune direction valide disponible
+                    break;
+                }
+    
+                // Mettre à jour la direction courante
+                currentDirection = newDirection;
+                forbiddenDirection = getOppositeDirection(currentDirection);
+                stepsInCurrentDirection = 0;
+            }
+        }
+    
+        return path;  // Retourner la liste des positions formant le serpent
+    }
+    
+    /**
+     * Choisit une nouvelle direction valide en tenant compte des exclusions permanentes et temporaires.
+     *
+     * @param allDirections Toutes les directions possibles.
+     * @param currentDirection La direction actuelle.
+     * @param forbiddenDirection La direction opposée à la direction actuelle (interdite).
+     * @param permanentlyExcludedDirections Les directions définitivement exclues.
+     * @param temporarilyExcludedDirections Les directions temporairement exclues.
+     * @param board Le plateau de jeu.
+     * @param x La coordonnée X actuelle.
+     * @param y La coordonnée Y actuelle.
+     * @param random Une instance de Random pour le choix aléatoire.
+     * @return La nouvelle direction choisie ou null si aucune direction valide n'est disponible.
+     */
+    private static Direction chooseNewDirection(List<Direction> allDirections, Direction currentDirection, Direction forbiddenDirection,
+                                               Set<Direction> permanentlyExcludedDirections, Set<Direction> temporarilyExcludedDirections,
+                                               Board<Square> board, int x, int y, Random random) {
+        // Créer une liste de directions valides en excluant :
+        // - La direction actuelle
+        // - La direction interdite (opposée à la direction actuelle)
+        // - Les directions définitivement exclues
+        // - Les directions temporairement exclues
+        List<Direction> validDirections = new ArrayList<>(allDirections);
+        validDirections.remove(currentDirection);
+        validDirections.remove(forbiddenDirection);
+        validDirections.removeAll(permanentlyExcludedDirections);
+        validDirections.removeAll(temporarilyExcludedDirections);
+    
+        // Filtrer les directions qui permettent de continuer le chemin
+        validDirections.removeIf(dir -> !board.doesPositionExist(new Position(x + getXIncrement(dir), y + getYIncrement(dir))));
+    
+        if (validDirections.isEmpty()) {
+            // Aucune direction valide disponible
+            return null;
+        }
+    
+        // Choisir une nouvelle direction aléatoirement
+        return validDirections.get(random.nextInt(validDirections.size()));
+    }
+    
+    private static int getXIncrement(Direction direction) {
+        switch (direction) {
+            case NORTH: return -1;
+            case SOUTH: return 1;
+            default:    return 0;
+        }
+    }
+    
+    private static int getYIncrement(Direction direction) {
+        switch (direction) {
+            case EAST:  return 1;
+            case WEST:  return -1;
+            default:    return 0;
+        }
+    }
+    
+    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/Fire.java b/src/main/java/model/Fire.java
index 8ad742e43ce3525c074b75b49b218e56cdbf49fd..0ff0b1883e56388eb72e8347ec20115990552f7b 100644
--- a/src/main/java/model/Fire.java
+++ b/src/main/java/model/Fire.java
@@ -56,7 +56,7 @@ public class Fire implements Entity {
             }
 
             // Skip if the position contains a Cloud (if clouds prevent fire spread)
-            if (board.doesSquareContainEntity(p, Cloud.class)) {
+            if (board.doesSquareContainEntity(p, Road.class)) {
                 continue;
             }
 
diff --git a/src/main/java/model/FireFighterScenario.java b/src/main/java/model/FireFighterScenario.java
index f48e74465b29f6110b07ab257f54772f1ae299d6..8be76438beec260d42b7ad1a5a59feb74b4d61f6 100644
--- a/src/main/java/model/FireFighterScenario.java
+++ b/src/main/java/model/FireFighterScenario.java
@@ -7,6 +7,7 @@ import java.util.Map;
 import java.util.Random;
 
 import util.Matrix;
+import util.PathGenerator;
 import util.Position;
 import util.PositionUtil;
 
@@ -23,12 +24,12 @@ public class FireFighterScenario extends EntityScenario implements Board<Square>
     this.step = 0;
   }
 
-public void placeInitialEntities(Map<EntityFactory, Integer> entityCounts) {
+  public void placeInitialEntities(Map<EntityFactory, Integer> entityCounts) {
     EntitySpawner spawner = new EntitySpawner(this);
     spawner.spawnEntities(entityCounts);
+    generateRoads();
     this.initialMap = entityCounts;
-}
-
+  }
 
   public Square getStates(Position position) {
     if (position.x() > matrix.size() || position.y() > matrix.size()) {
@@ -62,7 +63,6 @@ public void placeInitialEntities(Map<EntityFactory, Integer> entityCounts) {
     }
   }
 
-
   public int rowCount() {
     return matrix.getRows();
   }
@@ -81,24 +81,24 @@ public void placeInitialEntities(Map<EntityFactory, Integer> entityCounts) {
     Iterator<Square> iterator = matrix.iterator();
 
     while (iterator.hasNext()) {
-        Square s = iterator.next();
-        if (s.isEmpty())
-            continue;
-        if (s.getMaxAge() == 0) {
-            s.incrementAllAges();
-            continue;
-        }
-        if (s.getMaxAge() == step + 1) {
-            continue;
-        }
-        List<Entity> entities = new ArrayList<>(s.getEntities());
-        for (Entity e : entities) {
-            if(e.getAge() >= stepNumber()-1){
-              continue;
-            }
-            e.incrementAge();
-            changedPositions.addAll(e.nextTurn(this));
+      Square s = iterator.next();
+      if (s.isEmpty())
+        continue;
+      if (s.getMaxAge() == 0) {
+        s.incrementAllAges();
+        continue;
+      }
+      if (s.getMaxAge() == step + 1) {
+        continue;
+      }
+      List<Entity> entities = new ArrayList<>(s.getEntities());
+      for (Entity e : entities) {
+        if (e.getAge() >= stepNumber() - 1) {
+          continue;
         }
+        e.incrementAge();
+        changedPositions.addAll(e.nextTurn(this));
+      }
     }
 
     // Increment the step counter
@@ -106,49 +106,45 @@ public void placeInitialEntities(Map<EntityFactory, Integer> entityCounts) {
 
     // Check if it's time to spawn an AirTanker
     if (this.step % 8 == 0) {
-        // Spawn an AirTanker at a random edge position
-        spawnAirTanker(changedPositions);
+      // Spawn an AirTanker at a random edge position
+      spawnAirTanker(changedPositions);
     }
 
     return changedPositions;
-}
+  }
 
-// Helper method to spawn an AirTanker
-private void spawnAirTanker(List<Position> changedPositions) {
-  System.out.println("Spawning AirTanker");
-  Random rand = new Random();
-  int edge = rand.nextInt(4); // 0: top, 1: bottom, 2: left, 3: right
-  Position position = null;
+  // Helper method to spawn an AirTanker
+  private void spawnAirTanker(List<Position> changedPositions) {
+    Random rand = new Random();
+    int edge = rand.nextInt(4); // 0: top, 1: bottom, 2: left, 3: right
+    Position position = null;
 
-  if (edge == 0) { // Top edge (x == 0)
-      int y = rand.nextInt(columnCount()-1);
+    if (edge == 0) { // Top edge (x == 0)
+      int y = rand.nextInt(columnCount() - 1);
       position = new Position(0, y);
-  } else if (edge == 1) { // Bottom edge (x == rowCount() - 1)
+    } else if (edge == 1) { // Bottom edge (x == rowCount() - 1)
       int y = rand.nextInt(columnCount());
       position = new Position(rowCount() - 1, y);
-  } else if (edge == 2) { // Left edge (y == 0)
-      int x = rand.nextInt(rowCount()-1);
+    } else if (edge == 2) { // Left edge (y == 0)
+      int x = rand.nextInt(rowCount() - 1);
       position = new Position(x, 0);
-  } else if (edge == 3) { // Right edge (y == columnCount() - 1)
-      int x = rand.nextInt(rowCount()-1);
-      position = new Position(x, columnCount() -1);
-  } else {
-      // This else block is technically not necessary because edge will always be between 0 and 3
+    } else if (edge == 3) { // Right edge (y == columnCount() - 1)
+      int x = rand.nextInt(rowCount() - 1);
+      position = new Position(x, columnCount() - 1);
+    } else {
+      // This else block is technically not necessary because edge will always be
+      // between 0 and 3
       throw new IllegalStateException("Unexpected edge value: " + edge);
-  }
-
-  System.out.println("Position: " + position.toString());
-  // Create a new AirTanker
-  AirTanker airTanker = new AirTanker(position, this, getStepNumber());
-  System.out.println(" direction : " + airTanker.getDirection());
-  // Add the AirTanker to the board
-  addEntityAtSquare(airTanker, position);
-
-  // Record the changed position
-  changedPositions.add(position);
-}
+    }
 
+    // Create a new AirTanker
+    AirTanker airTanker = new AirTanker(position, this, getStepNumber());
+    // Add the AirTanker to the board
+    addEntityAtSquare(airTanker, position);
 
+    // Record the changed position
+    changedPositions.add(position);
+  }
 
   public Position getNearestEntity(Position fromPos, Class<?> entityType) {
     int rows = matrix.getRows();
@@ -210,11 +206,53 @@ private void spawnAirTanker(List<Position> changedPositions) {
   @Override
   public boolean isPositionFree(Position position, int priority) {
     List<Entity> entities = matrix.get(position.x(), position.y()).getEntities();
-    for(Entity e : entities){
-      if(e.getPriority() == priority){
+    for (Entity e : entities) {
+      if (e.getPriority() == priority) {
         return false;
       }
     }
     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){
+          clearCaseFrom(e, e.getPosition());
+        }
+      }
+      addEntityAtSquare(new Road(p), p);
+    }
+}
+
 }
diff --git a/src/main/java/model/Road.java b/src/main/java/model/Road.java
new file mode 100644
index 0000000000000000000000000000000000000000..aacbd8e7a3d4f9408c550a73e57f25093f3df0dd
--- /dev/null
+++ b/src/main/java/model/Road.java
@@ -0,0 +1,57 @@
+package model;
+
+import java.util.List;
+
+import javafx.scene.paint.Color;
+import util.Position;
+
+public class Road implements Entity{
+    private int age;
+    private final int PRIORITY = 0;
+    private final Color VIEW_COLOR = Color.BLACK;
+    private Position position;
+
+    public Road(Position position){
+        this.position = position;
+    }
+    @Override
+    public List<Position> nextTurn(Board<Square> board) {
+        return List.of();
+    }
+
+    @Override
+    public Position getPosition() {
+        return this.position;
+    }
+
+    @Override
+    public void setPosition(Position p) {
+        this.position = p;
+    }
+
+    @Override
+    public int getAge() {
+        return age;
+    }
+
+    @Override
+    public void setAge(int age) {
+        this.age = age;
+    }
+
+    @Override
+    public void incrementAge() {
+        this.age = age + 1;
+    }
+
+    @Override
+    public Color getViewColor() {
+        return this.VIEW_COLOR;
+    }
+
+    @Override
+    public int getPriority() {
+        return this.PRIORITY;
+    }
+    
+}
diff --git a/src/main/java/util/DirectionUtils.java b/src/main/java/util/DirectionUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1daaeac1941f5fc6437868f42fa709ba2bc2bf0
--- /dev/null
+++ b/src/main/java/util/DirectionUtils.java
@@ -0,0 +1,109 @@
+package util;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import model.Board;
+import model.Square;
+
+public class DirectionUtils {
+    
+    /**
+     * Obtient l'incrément sur l'axe X pour une direction donnée.
+     *
+     * @param direction La direction.
+     * @return L'incrément sur l'axe X.
+     */
+    public static int getXIncrement(Direction direction) {
+        switch (direction) {
+            case NORTH:
+                return -1;
+            case SOUTH:
+                return 1;
+            default:
+                return 0;
+        }
+    }
+
+    /**
+     * Obtient l'incrément sur l'axe Y pour une direction donnée.
+     *
+     * @param direction La direction.
+     * @return L'incrément sur l'axe Y.
+     */
+    public static int getYIncrement(Direction direction) {
+        switch (direction) {
+            case EAST:
+                return 1;
+            case WEST:
+                return -1;
+            default:
+                return 0;
+        }
+    }
+
+    /**
+     * Obtient la direction opposée.
+     *
+     * @param direction La direction actuelle.
+     * @return La direction opposée.
+     */
+    public static Direction getOpposite(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);
+        }
+    }
+
+    /**
+     * Choisit une direction aléatoire parmi toutes les directions disponibles.
+     *
+     * @param random Instance de Random.
+     * @return Une direction aléatoire.
+     */
+    public static Direction getRandomDirection() {
+        Random r = new Random();
+        Direction[] directions = Direction.values();
+        return directions[r.nextInt(directions.length)];
+    }
+
+    /**
+     * Obtient les directions valides en fonction des exclusions et de la position actuelle.
+     *
+     * @param currentDirection              La direction actuelle.
+     * @param permanentlyExcludedDirections Les directions définitivement exclues.
+     * @param temporarilyExcludedDirections Les directions temporairement exclues.
+     * @param board                         Le plateau de jeu.
+     * @param currentPosition               La position actuelle.
+     * @return Une liste de directions valides.
+     */
+    public static List<Direction> getValidDirections(
+            Direction currentDirection,
+            Set<Direction> permanentlyExcludedDirections,
+            Set<Direction> temporarilyExcludedDirections,
+            Board<Square> board,
+            Position currentPosition
+    ) {
+        return Arrays.stream(Direction.values())
+                .filter(dir -> dir != currentDirection)
+                .filter(dir -> dir != getOpposite(currentDirection))
+                .filter(dir -> !permanentlyExcludedDirections.contains(dir))
+                .filter(dir -> !temporarilyExcludedDirections.contains(dir))
+                .filter(dir -> {
+                    Position nextPos = currentPosition.move(dir);
+                    return board.doesPositionExist(nextPos);
+                })
+                .collect(Collectors.toList());
+    }
+}
diff --git a/src/main/java/util/PathGenerator.java b/src/main/java/util/PathGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..149c4ca1633a286e84915cf3c75c7405607470da
--- /dev/null
+++ b/src/main/java/util/PathGenerator.java
@@ -0,0 +1,189 @@
+package util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import model.Board;
+
+public class PathGenerator {
+    private final Board<?> board;
+    private final Random random = new Random();
+    private final int maxStepsInDirection;
+    private final int minimumRoadLength;
+    private final Set<Direction> initialExcludedDirections = new HashSet<>();
+    private final Position anchor;
+
+    private Position currentPosition;
+    private Direction currentDirection;
+    private Direction excludedDirection = null;
+    private Direction lastDirection = null;
+    private int stepsInCurrentDirection = 0;
+    private int roadLength = 1;
+    private final List<Position> path = new ArrayList<>();
+
+    /**
+     * Constructeur de PathGenerator.
+     *
+     * @param board               Le plateau de jeu.
+     * @param anchor              La position de départ.
+     * @param maxStepsInDirection Nombre maximal de pas dans une direction avant de changer.
+     * @param minimumRoadLength   Longueur minimale du chemin.
+     */
+    public PathGenerator(Board<?> board, Position anchor, int maxStepsInDirection, int minimumRoadLength) {
+        this.board = board;
+        this.anchor = anchor;
+        this.maxStepsInDirection = maxStepsInDirection;
+        this.minimumRoadLength = minimumRoadLength;
+        initializePath();
+    }
+
+    /**
+     * Génère le chemin en respectant les contraintes.
+     *
+     * @return Liste des positions formant le chemin.
+     */
+    public List<Position> generate() {
+        while (true) {
+            if (canMoveInCurrentDirection()) {
+                moveInCurrentDirection();
+                if (shouldChangeDirection()) {
+                    if (!changeDirection(false)) break;
+                }
+            } else {
+                if (!handleObstacle()) break;
+            }
+        }
+        return roadLength >= minimumRoadLength ? path : regeneratePath();
+    }
+
+    /** Initialise le chemin avec l'ancre et choisit la première direction. */
+    private void initializePath() {
+        path.clear();
+        roadLength = 1;
+        stepsInCurrentDirection = 0;
+        currentPosition = anchor;
+        path.add(anchor);
+        currentDirection = DirectionUtils.getRandomDirection();
+        initialExcludedDirections.clear();
+        initialExcludedDirections.add(currentDirection);
+        lastDirection = currentDirection;
+        excludedDirection = null;
+    }
+
+    /** Vérifie si le mouvement dans la direction actuelle est possible. */
+    private boolean canMoveInCurrentDirection() {
+        Position nextPosition = currentPosition.move(currentDirection);
+        return board.doesPositionExist(nextPosition);
+    }
+
+    /** Effectue le mouvement dans la direction actuelle. */
+    private void moveInCurrentDirection() {
+        currentPosition = currentPosition.move(currentDirection);
+        path.add(currentPosition);
+        roadLength++;
+        stepsInCurrentDirection++;
+        excludedDirection = DirectionUtils.getOpposite(currentDirection);
+    }
+
+    /** Détermine si un changement de direction est nécessaire. */
+    private boolean shouldChangeDirection() {
+        return stepsInCurrentDirection >= maxStepsInDirection;
+    }
+
+    /**
+     * Change la direction actuelle.
+     *
+     * @param mustContinue Si true, la nouvelle direction doit permettre de continuer le chemin.
+     * @return true si la direction a été changée avec succès, sinon false.
+     */
+    private boolean changeDirection(boolean mustContinue) {
+        Direction newDirection = chooseNewDirection(mustContinue);
+        if (newDirection == null) return false;
+        updateDirection(newDirection);
+        return true;
+    }
+
+    /** Gère le cas où le mouvement n'est pas possible (obstacle ou bord du plateau). */
+    private boolean handleObstacle() {
+        if (roadLength < minimumRoadLength) {
+            return changeDirection(true);
+        }
+        return false;
+    }
+
+    /** Réinitialise et génère à nouveau le chemin. */
+    private List<Position> regeneratePath() {
+        initializePath();
+        return generate();
+    }
+
+    /** Met à jour la direction actuelle et les compteurs associés. */
+    private void updateDirection(Direction newDirection) {
+        currentDirection = newDirection;
+        stepsInCurrentDirection = 0;
+        lastDirection = newDirection;
+        excludedDirection = DirectionUtils.getOpposite(newDirection);
+    }
+
+    /**
+     * Choisit une nouvelle direction valide en tenant compte des exclusions.
+     *
+     * @param mustContinue Si true, la direction doit permettre de continuer le chemin.
+     * @return La nouvelle direction choisie ou null si aucune n'est valide.
+     */
+    private Direction chooseNewDirection(boolean mustContinue) {
+        Set<Direction> exclusions = new HashSet<>(initialExcludedDirections);
+        Collections.addAll(exclusions, excludedDirection, lastDirection);
+        List<Direction> validDirections = getValidDirections(exclusions, currentPosition);
+
+        if (mustContinue) {
+            validDirections = filterDirectionsToContinue(validDirections, currentPosition);
+        }
+
+        return validDirections.isEmpty() ? null : validDirections.get(random.nextInt(validDirections.size()));
+    }
+
+    /**
+     * Obtient les directions valides à partir de la position actuelle.
+     *
+     * @param exclusions       Les directions à exclure.
+     * @param currentPosition  La position actuelle.
+     * @return Liste des directions valides.
+     */
+    private List<Direction> getValidDirections(Set<Direction> exclusions, Position currentPosition) {
+        List<Direction> validDirections = new ArrayList<>();
+        for (Direction dir : Direction.values()) {
+            if (!exclusions.contains(dir)) {
+                Position nextPos = currentPosition.move(dir);
+                if (board.doesPositionExist(nextPos)) {
+                    validDirections.add(dir);
+                }
+            }
+        }
+        return validDirections;
+    }
+
+    /**
+     * Filtre les directions pour s'assurer qu'elles permettent de continuer le chemin.
+     *
+     * @param directions      Liste des directions valides.
+     * @param currentPosition La position actuelle.
+     * @return Liste des directions permettant de continuer.
+     */
+    private List<Direction> filterDirectionsToContinue(List<Direction> directions, Position currentPosition) {
+        List<Direction> filtered = new ArrayList<>();
+        for (Direction dir : directions) {
+            Position nextPos = currentPosition.move(dir);
+            Set<Direction> futureExclusions = new HashSet<>(initialExcludedDirections);
+            futureExclusions.add(DirectionUtils.getOpposite(dir));
+            if (!getValidDirections(futureExclusions, nextPos).isEmpty()) {
+                filtered.add(dir);
+            }
+        }
+        return filtered;
+    }
+}
diff --git a/src/main/java/util/Position.java b/src/main/java/util/Position.java
index 389b8214dbc56af0914084e8fa7e68cd3c1b2e72..d6407fadb846754bdfb63ef8b4a5966dd78f25e1 100644
--- a/src/main/java/util/Position.java
+++ b/src/main/java/util/Position.java
@@ -1,5 +1,10 @@
 package util;
 
 public record Position(int x, int y) {
-
+        // Méthode pour déplacer la position dans une direction donnée
+        public Position move(Direction direction) {
+            int newX = this.x + DirectionUtils.getXIncrement(direction);
+            int newY = this.y + DirectionUtils.getYIncrement(direction);
+            return new Position(newX, newY);
+        }
 }
diff --git a/src/main/java/util/PositionUtil.java b/src/main/java/util/PositionUtil.java
index 278bf9f0aab3b76154f1d442ba7b001e60c60278..0a3f9011468dbeb11e6b8b2f4fb3549f0f083328 100644
--- a/src/main/java/util/PositionUtil.java
+++ b/src/main/java/util/PositionUtil.java
@@ -75,8 +75,6 @@ public class PositionUtil {
     }
 
     public static List<Position> generateAdjacentPositions(Position position, Board<Square> board, int distance) {
-        int x = position.x();
-        int y = position.y();
 
         List<Position> positions = new ArrayList<Position>();
         for(int i = 0; i < 4; i++){