diff --git a/cmd/simu/main.go b/cmd/simu/main.go
index f963e03be40af2a537924923ad7f76bad953b94a..c298cf2bfb099acbc2cec11fb165e1ad79a66d61 100644
--- a/cmd/simu/main.go
+++ b/cmd/simu/main.go
@@ -6,7 +6,7 @@ import (
 )
 
 func main() {
-	s := simulation.NewSimulation(10, -1, 600*time.Second)
+	s := simulation.NewSimulation(2, -1, 600*time.Second)
 	//go simulation.StartAPI(s)
 	s.Run()
 }
diff --git a/cmd/test/main.go b/cmd/test/main.go
deleted file mode 100644
index f5e5e2d9ece35c061fc43785bb778f2d36bb978f..0000000000000000000000000000000000000000
--- a/cmd/test/main.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"regexp"
-)
-
-func main() {
-	faceCase := "Agent1000" // Remplacez ceci par votre variable
-
-	// Créer l'expression régulière
-	regexPattern := `^Agent\d+$` // \d+ correspond à un ou plusieurs chiffres
-	matched, err := regexp.MatchString(regexPattern, faceCase)
-
-	if err != nil {
-		fmt.Println("Erreur lors de l'analyse de la regex :", err)
-		return
-	}
-
-	// Vérifiez si la chaîne ne correspond pas au motif
-	if !matched {
-		fmt.Println("La chaîne ne correspond pas au motif 'Agentx'")
-	} else {
-		fmt.Println("La chaîne correspond au motif 'Agentx'")
-	}
-}
diff --git a/internal/algorithms/astar.go b/internal/algorithms/astar.go
index d159d9db222d884b42ada32d48bc8aa92ba299e0..c7f400e4ea9a029e0443849a8ea729757d34c0e3 100644
--- a/internal/algorithms/astar.go
+++ b/internal/algorithms/astar.go
@@ -64,7 +64,7 @@ func (pq *PriorityQueue) Pop() interface{} {
 type ZoneID int
 type Coord [2]int
 
-func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node, orientation bool, timeout time.Duration) []Node {
+func FindPath(matrix [50][50]string, start, end Node, forbidenCell Node, orientation bool, timeout time.Duration) []Node {
 	// Création d'un context avec timeout, pour limiter le calcul
 	ctx, cancel := context.WithTimeout(context.Background(), timeout)
 	defer cancel()
@@ -77,7 +77,7 @@ func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node, orienta
 	parents := make(map[Node]Node)
 
 	closestPoint := start // Initialisation avec le point de départ
-	closestDistance := Heuristic(start.row, start.col, end)
+	closestDistance := Heuristic(matrix, start.row, start.col, end)
 
 	foundPath := false
 
@@ -92,7 +92,7 @@ func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node, orienta
 		current := heap.Pop(&pq).(*Node)
 
 		// Mise à jour du point le plus proche si le point actuel est plus proche
-		currentDistance := Heuristic(current.row, current.col, end)
+		currentDistance := Heuristic(matrix, current.row, current.col, end)
 		if currentDistance < closestDistance {
 			closestPoint = *current
 			closestDistance = currentDistance
@@ -132,7 +132,7 @@ func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node, orienta
 	return nil // Aucun chemin trouvé
 }
 
-func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node, orientation bool) []*Node {
+func getNeighbors(matrix [50][50]string, current, end Node, forbiddenCell Node, orientation bool) []*Node {
 	neighbors := make([]*Node, 0)
 
 	// Déplacements possibles: up, down, left, right
@@ -149,7 +149,7 @@ func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node,
 						row:         newRow,
 						col:         newCol,
 						cost:        current.cost + 1,
-						heuristic:   Heuristic(newRow, newCol, end),
+						heuristic:   Heuristic(matrix, newRow, newCol, end),
 						width:       current.width,
 						height:      current.height,
 						orientation: current.orientation,
@@ -163,7 +163,7 @@ func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node,
 					row:         newRow,
 					col:         newCol,
 					cost:        current.cost + 1,
-					heuristic:   Heuristic(newRow, newCol, end),
+					heuristic:   Heuristic(matrix, newRow, newCol, end),
 					width:       current.width,
 					height:      current.height,
 					orientation: current.orientation,
@@ -176,12 +176,16 @@ func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node,
 	return neighbors
 }
 
-func Heuristic(row, col int, end Node) int {
+func Heuristic(matrix [50][50]string, row, col int, end Node) int {
 	// Heuristique simple : distance de Manhattan
 	// On introduit de l'aléatoire pour ajouter de la diversité dans la construction des chemins
 	// On évite d'avoir tout le temps le même chemin pour un même point de départ et d'arrivé
 	//return abs(row-end.row) + abs(col-end.col) + rand.Intn(3)
-	return Abs(row-end.row) + Abs(col-end.col) + rand.Intn(10)
+	malus := 0
+	if len(matrix[row][col]) > 1 {
+		malus += 10
+	}
+	return Abs(row-end.row) + Abs(col-end.col) + rand.Intn(10) + malus
 }
 
 func Abs(x int) int {
@@ -191,7 +195,7 @@ func Abs(x int) int {
 	return x
 }
 
-func isValidMove(matrix [20][20]string, current Node, forbiddenCell Node, newRow, newCol int, orientation bool) bool {
+func isValidMove(matrix [50][50]string, current Node, forbiddenCell Node, newRow, newCol int, orientation bool) bool {
 	// Check if the new position is within the bounds of the matrix
 	if newRow < 0 || newRow >= len(matrix) || newCol < 0 || newCol >= len(matrix[0]) {
 		return false
@@ -199,10 +203,11 @@ func isValidMove(matrix [20][20]string, current Node, forbiddenCell Node, newRow
 
 	// Check if the new position overlaps with forbidden cells or obstacles
 	if forbiddenCell.row == newRow && forbiddenCell.col == newCol {
-		return false
+		//return false
+		current.heuristic = current.heuristic + 100
 	}
 	// Check if the absolute coordinates overlap with obstacles in the matrix
-	if matrix[newRow][newCol] == "Q" || matrix[newRow][newCol] == "X" {
+	if matrix[newRow][newCol] == "Q" || matrix[newRow][newCol] == "X" || matrix[newRow][newCol] == "M" {
 		return false
 	}
 
@@ -223,11 +228,12 @@ func isValidMove(matrix [20][20]string, current Node, forbiddenCell Node, newRow
 
 				// Check if the absolute coordinates overlap with forbidden cells or obstacles
 				if forbiddenCell.row == absRow && forbiddenCell.col == absCol {
-					return false
+					//return false
+					current.heuristic = current.heuristic + 100
 				}
 
 				// Check if the absolute coordinates overlap with obstacles in the matrix
-				if matrix[absRow][absCol] == "Q" || matrix[absRow][absCol] == "X" {
+				if matrix[absRow][absCol] == "Q" || matrix[absRow][absCol] == "X" || matrix[absRow][absCol] == "M" {
 					return false
 				}
 			}
@@ -286,3 +292,22 @@ func calculateBounds(row, col, width, height, orientation int) (infRow, supRow,
 	}
 	return borneInfRow, borneSupRow, borneInfCol, borneSupCol
 }
+
+func FindNearestExit(matrix [50][50]string, row, col int) (dest_row, dest_col int) {
+	// Recherche de la sortie la plus proche
+	min := 1000000
+	n := len(matrix[0])
+	for i := 0; i < n; i++ {
+		for j := 0; j < n; j++ {
+			if matrix[i][j] == "S" || matrix[i][j] == "W" {
+				dist := Abs(row-i) + Abs(col-j)
+				if dist < min {
+					min = dist
+					dest_row = i
+					dest_col = j
+				}
+			}
+		}
+	}
+	return dest_row, dest_col
+}
diff --git a/internal/simulation/agent.go b/internal/simulation/agent.go
index 09a45169216bc3ef3a216a4d1b8dc217f0d22f63..a72707b8b66816e3f4e49df351082e8571d85e97 100644
--- a/internal/simulation/agent.go
+++ b/internal/simulation/agent.go
@@ -2,14 +2,10 @@ package simulation
 
 /*
  * Classe et méthodes principales de la structure Agent
- * à faire :
- *			// TODO: Gérer les moments où les agents font du quasi-sur place car ils ne peuvent plus bouger
- *			// TODO: Il arrive encore que certains agents soient bloqués, mais c'est quand il n'y a aucun mouvement possible.
- *			// Il faudrait faire en sorte que les agents bougent et laisse passer les autres
  */
 
 import (
-	//"fmt"
+	"fmt"
 	"log"
 	//"fmt"
 
@@ -17,19 +13,18 @@ import (
 	"math/rand"
 	alg "metrosim/internal/algorithms"
 	"time"
+	"sort"
 )
 
 type Action int64
 
 const (
-	Noop = iota
-	Mark
-	Wait
-	Move
-	Disappear
-	Expel // virer l'agent
-	Stop  // arreter l'agent
-	GiveInfos
+	Noop      = iota
+	Wait      // Attente
+	Move      // Déplacement de l'agent
+	Disappear // Disparition  de l'agent dans la simulatiin
+	Expel     // virer l'agent
+	Stop      // arreter l'agent
 )
 
 type Coord [2]int
@@ -51,14 +46,15 @@ type Agent struct {
 	stuck       bool
 	width       int
 	height      int
-	orientation int //0 : vers le haut, 1 : vers la droite, 2 : vers le bas, 3 : vers la gauche (sens de deuxieme case occupé par l'agent)
+	orientation int //0 : vers le haut, 1 : vers la droite, 2 : vers le bas, 3 : vers la gauche (sens de construction de l'agent)
 	path        []alg.Node
 	request     *Request
 	direction   int //0 : vers le haut, 1 : vers la droite, 2 : vers le bas, 3 : vers la gauche (sens de son deplacement)
+
 }
 
 type Request struct {
-	demandeur chan Request
+	demandeur chan Request //channel de l'émetteur de la demande
 	decision  int
 }
 
@@ -90,6 +86,9 @@ func (ag *Agent) Start() {
 	if (ag.id[0] == 'C') {
 		ag.behavior.(*Controleur).startTimer()
 	}
+	if (ag.id[0] == 'M') {
+		ag.behavior.(*MobiliteReduite).setUpPath(ag)
+	}
 
 	go func() {
 		var step int
@@ -99,6 +98,7 @@ func (ag *Agent) Start() {
 			ag.behavior.Deliberate(ag)
 			ag.behavior.Act(ag)
 			ag.syncChan <- step
+			//fmt.Println(ag.id, ag.path)
 			if ag.decision == Disappear {
 				ag.env.RemoveAgent(*ag)
 				return
@@ -117,6 +117,7 @@ func IsMovementSafe(path []alg.Node, agt *Agent, env *Environment) (bool, int) {
 	// Détermine si le movement est faisable
 
 	if len(path) <= 0 {
+		fmt.Println("[isMovementSafe] path vide : ", agt.id)
 		return false, agt.orientation
 	}
 	// Calcul des bornes de position de l'agent avant mouvement
@@ -124,6 +125,7 @@ func IsMovementSafe(path []alg.Node, agt *Agent, env *Environment) (bool, int) {
 
 	// Si pas encore sur la map, mais agent déja sur la position, on ne peut pas encore apparaître
 	if len(agt.isOn) == 0 && len(env.station[agt.path[0].Row()][agt.path[0].Col()]) > 1 {
+		//fmt.Println("[isMovementSafe] case occupée : ",agt.id)
 		return false, agt.orientation
 	}
 	// Simulation du déplacement
@@ -139,8 +141,9 @@ func IsMovementSafe(path []alg.Node, agt *Agent, env *Environment) (bool, int) {
 		if !(borneInfCol < 0 || borneInfRow < 0 || borneSupRow > len(env.station[0]) || borneSupCol > len(env.station[1])) {
 			for i := borneInfRow; i < borneSupRow; i++ {
 				for j := borneInfCol; j < borneSupCol; j++ {
-					if !(j >= infCol && j < supCol && i >= infRow && i < supRow) && (env.station[i][j] != "B" && env.station[i][j] != "_" && env.station[i][j] != "W" && env.station[i][j] != "S") {
+					if !(j >= infCol && j < supCol && i >= infRow && i < supRow) && (env.station[i][j] != "B" && env.station[i][j] != "_" && env.station[i][j] != "W" && env.station[i][j] != "S" && env.station[i][j] != "O") {
 						// Si on n'est pas sur une case atteignable, en dehors de la zone qu'occupe l'agent avant déplacement, on est bloqué
+						//fmt.Println("[IsMovementSafe]case inaccessible :",agt.id)
 						safe = false
 					}
 				}
@@ -152,7 +155,6 @@ func IsMovementSafe(path []alg.Node, agt *Agent, env *Environment) (bool, int) {
 
 	}
 	return false, agt.orientation
-
 }
 
 func IsAgentBlocking(path []alg.Node, agt *Agent, env *Environment) bool {
@@ -220,27 +222,88 @@ func (ag *Agent) isStuck() bool {
 	return not_acc == count
 }
 
+func (ag *Agent) WhichAgent() string {
+	if ag.direction == 0 { // vers le haut
+		return ag.env.station[ag.position[0]-1][ag.position[1]]
+	} else if ag.direction == 1 { // vers la droite
+		return ag.env.station[ag.position[0]][ag.position[1]+1]
+	} else if ag.direction == 2 { // vers le bas
+		return ag.env.station[ag.position[0]+1][ag.position[1]]
+	} else { // vers la gauche
+		return ag.env.station[ag.position[0]][ag.position[1]-1]
+	}
+}
+
+func (env *Environment) FindAgentByID(agtId AgentID) *Agent {
+	for i := range env.ags {
+		if env.ags[i].id == agtId {
+			return &env.ags[i]
+		}
+	}
+	return nil
+}
+
 func (ag *Agent) MoveAgent() {
 	//fmt.Println("[Agent, MoveAgent] destination ", ag.destination)
 	// ================== Tentative de calcul du chemin =======================
-	if len(ag.path) == 0 {
+	if len(ag.path) == 0 || ag.isGoingToExitPath() {
 		start, end := ag.generatePathExtremities()
 		// Recherche d'un chemin si inexistant
-		path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 0), false, 2*time.Second)
-		ag.path = path
+		ag.path = alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 0), false, 2*time.Second)
+		
 	}
 
 	// ================== Etude de faisabilité =======================
 	if IsAgentBlocking(ag.path, ag, ag.env) {
-		// TODO:voir comment gérer les situations de blocage
-		start, end := ag.generatePathExtremities()
-		// Si un agent bloque notre déplacement, on attend un temps aléatoire, et reconstruit
-		time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
-		path := alg.FindPath(ag.env.station, start, end, ag.path[0], true, 2*time.Second)
-		ag.path = path
 
+		if ag.politesse {
+			start, end := ag.generatePathExtremities()
+			// Si un agent bloque notre déplacement, on attend un temps aléatoire, et reconstruit
+			time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
+			//path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 0), false, 2*time.Second)
+			path := alg.FindPath(ag.env.station, start, end, ag.path[0], false, 2*time.Second)
+			ag.path = path
+			return
+		} else {
+			//Si individu impoli, demande à l'agent devant de bouger
+			//On récupère le id de la personne devant
+			blockingAgentID := AgentID(ag.WhichAgent())
+			//blockingAgent := ag.env.FindAgentByID(blockingAgentID)
+			var reqToBlockingAgent *Request
+			//var reqToImpoliteAgent *Request
+			i := 0
+			accept := false
+			for !accept && i < 3 {
+				//Demande à l'agent qui bloque de se pousser (réitère trois fois s'il lui dit pas possible)
+				i += 1
+				reqToBlockingAgent = NewRequest(ag.env.agentsChan[ag.id], 3) //Création "Hello, je suis ag.id, move."
+				ag.env.agentsChan[blockingAgentID] <- *reqToBlockingAgent    //Envoi requête
+
+				/*
+					1. Faire le moment ou blocking agent recoit qqchose sur son canal
+					2.
+
+
+				*/
+				/*
+					//BlockingAgent cherche si autour de lui c'est vide
+					possible, or := IsMovementSafe(blockingAgent.path, blockingAgent, blockingAgent.env)
+
+					if !possible {
+						reqToImpoliteAgent = NewRequest(ag.id, 0)
+						ag.env.agentsChan[ag.id] <- *reqToImpoliteAgent
+					} else {
+						//Bouge sur la case possible
+						accept = true
+						coordBlockingAgent := blockingAgent.position
+						//Gérer le déplacement de Ag et de BlockingAgent + déplacement en fonction de la force !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+					}
+				*/
+			}
+		}
 	}
-	// ================== Déplacement si aucun problème =======================
+
+	// ================== Déplacement si aucun problème ou si blockingAgent se pousse =======================
 	safe, or := IsMovementSafe(ag.path, ag, ag.env)
 	if safe {
 		if len(ag.isOn) > 0 {
@@ -275,7 +338,7 @@ func (ag *Agent) generatePathExtremities() (alg.Node, alg.Node) {
 	return start, end
 }
 
-func RemoveAgent(matrix *[20][20]string, agt *Agent) {
+func RemoveAgent(matrix *[50][50]string, agt *Agent) {
 	// Supprime l'agent de la matrice
 
 	// Calcul des bornes de position de l'agent
@@ -289,7 +352,7 @@ func RemoveAgent(matrix *[20][20]string, agt *Agent) {
 	}
 }
 
-func writeAgent(matrix *[20][20]string, agt *Agent) {
+func writeAgent(matrix *[50][50]string, agt *Agent) {
 	// Ecris l'agent dans la matrice
 
 	// Calcul des bornes de position de l'agent
@@ -303,7 +366,7 @@ func writeAgent(matrix *[20][20]string, agt *Agent) {
 
 }
 
-func saveCells(matrix *[20][20]string, savedCells map[Coord]string, position Coord, width, height, orientation int) {
+func saveCells(matrix *[50][50]string, savedCells map[Coord]string, position Coord, width, height, orientation int) {
 	// Enregistrement des valeurs des cellules de la matrice
 	borneInfRow, borneSupRow, borneInfCol, borneSupCol := calculateBounds(position, width, height, orientation)
 
@@ -384,20 +447,51 @@ func (ag *Agent) listenForRequests() {
 	}
 }
 
-func (ag *Agent) findNearestGate(gates [] Coord) (Coord) {
-	// Recherche de la porte la plus proche
-	nearest := Coord{0, 0}
-	min := 1000000
+func (ag *Agent) isGoingToExitPath() bool {
+	if len(ag.path) > 0 {
+		for _, metro := range ag.env.metros {
+			for gate_index, gate := range metro.way.gates {
+				if equalCoord(&ag.destination, &gate) {
+					// Si la destination est une porte de métro, on va essayer de libérer le chemin des agents sortants
+					exit_path := metro.way.pathsToExit[gate_index]
+					for _, cell := range exit_path {
+						if equalCoord(&Coord{cell.Row(), cell.Col()}, &ag.position) {
+							return true
+						}
+					}
+				}
+			}
+		}
+	}
+	return false
+
+}
+
+// Structure pour associer une Coord et sa distance par rapport au position d'un agent
+type GateDistance struct {
+	Gate   Coord
+	Distance int
+}
+
+func (ag *Agent) findNearestGates(gates []Coord) []GateDistance {
+	var gateDistances []GateDistance
+
+	// Calcul de la distance pour chaque porte
 	for _, gate := range gates {
 		dist := alg.Abs(ag.position[0]-gate[0]) + alg.Abs(ag.position[1]-gate[1])
-		if dist < min {
-			min = dist
-			nearest = gate
-		}
+		gateDistances = append(gateDistances, GateDistance{Gate: gate, Distance: dist})
 	}
-	return nearest
+
+	// Tri des Coords par distance
+	sort.Slice(gateDistances, func(i, j int) bool {
+		return gateDistances[i].Distance < gateDistances[j].Distance
+	})
+
+	return gateDistances
 }
 
+
+
 func (ag *Agent) findNearestExit() (Coord){
 	// Recherche de la sortie la plus proche
 	nearest := Coord{0, 0}
@@ -488,4 +582,20 @@ func verifyDirection( n int ,depart Coord, dimensionCarte int) bool{
 			}
 	}
 	return false
-}
\ No newline at end of file
+}
+
+
+func (ag *Agent) bestGate(gates[] Coord) (Coord) {
+	mapNb := make(map[Coord]int)
+	for _, gate := range gates {
+		nb :=ag.env.getNbAgentsAround(gate)
+		mapNb[gate] = nb
+	}
+
+	listDist := ag.findNearestGates(gates) //Type []GateDistance
+
+	for _, couple := range listDist {
+		mapNb[couple.Gate] = mapNb[couple.Gate] / couple.Distance // il faut trouver le gate ayant une valeur le plus proche à 1
+	}
+	return mapNb
+}
diff --git a/internal/simulation/controleur.go b/internal/simulation/controleur.go
index 49143c9f40c890d3b6a30e32ce17769f420365aa..4935d023dcacbb4bb6f45d7e10a8615d08896096 100644
--- a/internal/simulation/controleur.go
+++ b/internal/simulation/controleur.go
@@ -53,15 +53,15 @@ func (c *Controleur) Deliberate(ag *Agent) {
 	matchedFraud, err2 := regexp.MatchString(regexFraudeur, c.faceCase)
 	//fmt.Println("faceCase : ", c.faceCase)
 	//fmt.Println("matchedAgt : ", matchedAgt)
-	
+
 	if err1 != nil || err2 != nil {
 		fmt.Println("Erreur lors de l'analyse de la regex :", err1, err2)
 		return
 	} else {
-		if matchedAgt  && ag.env.controlledAgents[AgentID(c.faceCase)] == false { // si l'agent devant le controleur est un agent et qu'il n'a pas encore été controlé
+		if matchedAgt && ag.env.controlledAgents[AgentID(c.faceCase)] == false { // si l'agent devant le controleur est un agent et qu'il n'a pas encore été controlé
 			//fmt.Println("L'agent ", c.face, " a été détecté par le controleur")
 			ag.decision = Stop // arreter l'agent devant lui
-		} else if matchedFraud && !ag.env.controlledAgents[AgentID(c.faceCase)]{
+		} else if matchedFraud && !ag.env.controlledAgents[AgentID(c.faceCase)] {
 			ag.decision = Expel // virer l'agent devant lui
 			//sinon comportement par défaut (comportement de l'usager lambda)
 			}else if ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") { // si l'agent est arrivé à sa destination et qu'il est sur une sortie
diff --git a/internal/simulation/env.go b/internal/simulation/env.go
index cf3aaf76417a44cb9ccc1a7a8b1b5927f5b394b0..ab0e46f9fec5f684af1d7ebb08fb4f05efba52a6 100644
--- a/internal/simulation/env.go
+++ b/internal/simulation/env.go
@@ -7,43 +7,52 @@ import (
 
 type Environment struct {
 	sync.RWMutex
-	ags        []Agent
-	agentCount int
-	station    [20][20]string
-	agentsChan map[AgentID]chan Request
+	ags              []Agent
+	agentCount       int
+	station          [50][50]string
+	agentsChan       map[AgentID]chan Request
 	controlledAgents map[AgentID]bool
-	metros	 []Metro // Liste des métros de la station , utilisé pour le choix du métro par l'agent à mobilité réduite (A voir si on peut trouver une autre manière de faire)
-	// zones      map[Coord]ZoneID      // Zones de la station
-	// panneaux   map[ZoneID][]alg.Node // Les panneaux de la station, permettant d'aller vers la zone
+	newAgentChan     chan Agent
+	metros           []Metro
 }
 
 type ZoneID int
 
 
-func NewEnvironment(ags []Agent, carte [20][20]string, agentsCh map[AgentID]chan Request) (env *Environment) {
-	mapControlle := make(map[AgentID]bool)
+
+func NewEnvironment(ags []Agent, carte [50][50]string, newAgtCh chan Agent, agtCount int) (env *Environment) {
+	agentsCh := make(map[AgentID]chan Request)
+	mapControlled := make(map[AgentID]bool)
 	for _, ag := range ags {
-		mapControlle[ag.id] = false
+		mapControlled[ag.id] = false
+
 	}
-	return &Environment{ags: ags, agentCount: len(ags), station: carte, agentsChan: agentsCh, controlledAgents: mapControlle}
+	return &Environment{ags: ags, agentCount: agtCount, station: carte, agentsChan: agentsCh, controlledAgents: mapControlled, newAgentChan: newAgtCh}
 }
 
 func (env *Environment) AddAgent(agt Agent) {
+	env.Lock()
+	defer env.Unlock()
 	env.ags = append(env.ags, agt)
+	env.controlledAgents[agt.id] = false
+	// ajout du channel de l'agent à l'environnement
+	env.agentsChan[agt.id] = make(chan Request, 5)
 	env.agentCount++
+	env.newAgentChan <- agt
 }
 
 func (env *Environment) RemoveAgent(agt Agent) {
+	// TODO:gérer la suppression dans simu
 	for i := 0; i < len(env.station); i++ {
 		if env.ags[i].id == agt.id {
 			// Utiliser la syntaxe de découpage pour supprimer l'élément
 			env.ags = append(env.ags[:i], env.ags[i+1:]...)
-			delete(env.agentsChan,agt.id)
+			delete(env.agentsChan, agt.id)
 			// Sortir de la boucle après avoir trouvé et supprimé l'élément
 			break
 		}
 	}
-	env.agentCount--
+	//env.agentCount--
 }
 
 func (env *Environment) Do(a Action, c Coord) (err error) {
@@ -51,12 +60,12 @@ func (env *Environment) Do(a Action, c Coord) (err error) {
 	defer env.Unlock()
 
 	switch a {
-	case Mark:
-		if c[0] < 0 || c[0] > 1 || c[1] < 0 || c[1] > 1 {
-			return fmt.Errorf("bad coordinates (%f,%f)", c[0], c[1])
-		}
+	// case Mark:
+	// 	if c[0] < 0 || c[0] > 1 || c[1] < 0 || c[1] > 1 {
+	// 		return fmt.Errorf("bad coordinates (%f,%f)", c[0], c[1])
+	// 	}
 
-		return nil
+	// 	return nil
 
 	case Noop:
 		return nil
@@ -85,15 +94,15 @@ func (env *Environment) verifyEmptyCase(c Coord) bool {
 }
 
 func existAgent(c string) bool {
-	return c != "X" && c != "E"  &&  c != "S" &&  c != "W" &&  c!= "Q" && c!= "_" &&  c!= "B"
+	return c != "X" && c != "E" && c != "S" && c != "W" && c != "Q" && c != "_" && c != "B"
 }
 
 func calculDirection(depart Coord, arrive Coord) int {
 	if depart[0] == arrive[0] {
 		if depart[1] > arrive[1] {
-			return  3 //Gauche
+			return 3 //Gauche
 		} else {
-			return  1 //droite
+			return 1 //droite
 		}
 	} else {
 		if depart[0] > arrive[0] {
@@ -102,4 +111,18 @@ func calculDirection(depart Coord, arrive Coord) int {
 			return 2 //bas
 		}
 	}
-}
\ No newline at end of file
+}
+
+func (env *Environment) getNbAgentsAround(pos Coord) int {
+	nb := 0
+	for i := 0; i < 4; i++ {
+		for j := 0; j < 4; j++ {
+			c := env.station[pos[0]+i][pos[1]+j]
+			if existAgent(c) {
+				nb++
+			}
+		}
+	}
+	return nb
+}
+
diff --git a/internal/simulation/metro.go b/internal/simulation/metro.go
index a31708b76854f47807cac797f2f2fbfc72c3365f..dbd6b8793110c895e9b5ccf8b1d746ca3cce4c89 100644
--- a/internal/simulation/metro.go
+++ b/internal/simulation/metro.go
@@ -7,21 +7,28 @@ import (
 	"time"
 )
 
+/*
+ * //TODO:Ajouter la capacité max
+ * // Apparition des agents sortant
+ */
+
+var metro_speed int = 5 // Nombre de seconde de l'entrée en gare
+
 type Metro struct {
-	frequency  time.Duration
-	stopTime   time.Duration
+	frequency  time.Duration // fréquence d'arrivée du métro
+	stopTime   time.Duration // temps d'arrêt du métro en gare
+	capacity   int
 	freeSpace  int // nombre de cases disponibles dans le métro
-	env        *Environment
 	comChannel chan Request
 	way        *Way
 }
 
-func NewMetro(freq time.Duration, stopT time.Duration, freeS int, env *Environment, way *Way) *Metro {
+func NewMetro(freq time.Duration, stopT time.Duration, capacity, freeS int, way *Way) *Metro {
 	return &Metro{
 		frequency:  freq,
 		stopTime:   stopT,
+		capacity:   capacity,
 		freeSpace:  freeS,
-		env:        env,
 		comChannel: make(chan Request),
 		way:        way,
 	}
@@ -34,11 +41,16 @@ func (metro *Metro) Start() {
 		//var step int
 		for {
 			//step = <-metro.syncChan
+			if refTime.Add(metro.frequency).Sub(time.Now()) <= time.Duration(metro_speed)*time.Second {
+				metro.printMetro()
+			}
 			if refTime.Add(metro.frequency).Before(time.Now()) {
-				go metro.pickUpUsers()
+				//metro.dropUsers()
+				metro.way.openGates()
+				metro.pickUpUsers()
+				metro.way.closeGates()
+				metro.removeMetro()
 				metro.freeSpace = rand.Intn(10)
-				fmt.Println(metro.way.id, metro.freeSpace)
-				//go metro.dropUsers()
 				refTime = time.Now()
 			}
 			//metro.syncChan <- step
@@ -61,22 +73,146 @@ func (metro *Metro) pickUpUsers() {
 
 func (metro *Metro) pickUpGate(gate *Coord) {
 	// Récupérer les usagers à une porte spécifique
-	gate_cell := metro.env.station[gate[0]][gate[1]]
+	gate_cell := metro.way.env.station[gate[0]][gate[1]]
 	if len(gate_cell) > 1 {
 		agent := metro.findAgent(AgentID(gate_cell))
 		if agent != nil && agent.width*agent.height <= metro.freeSpace && agent.destination == *gate {
-			metro.env.agentsChan[agent.id] <- *NewRequest(metro.comChannel, Disappear)
-			metro.freeSpace--
+			metro.way.env.agentsChan[agent.id] <- *NewRequest(metro.comChannel, Disappear)
+			fmt.Println("[pickUpGate] requete envoyée à l'agent ", agent.id)
+			metro.freeSpace = metro.freeSpace - agent.width*agent.height
 		}
 	}
 }
 
 func (metro *Metro) findAgent(agent AgentID) *Agent {
 	// Trouver l'adresse de l'agent
-	for _, agt := range metro.env.ags {
+	for _, agt := range metro.way.env.ags {
 		if agt.id == agent {
 			return &agt
 		}
 	}
 	return nil
 }
+
+func (metro *Metro) dropUsers() {
+	nb := rand.Intn(metro.capacity - metro.freeSpace) // Nombre de cases à vider du métro
+	for nb > 0 {
+		gate_nb := rand.Intn(len(metro.way.gates)) // Sélection d'une porte aléatoirement
+		width := 1                                 //+ rand.Intn(2)
+		height := 1                                //+ rand.Intn(2)
+		metro.freeSpace = metro.freeSpace + width*height
+		nb = nb - width*height
+		id := fmt.Sprintf("Agent%d", metro.way.env.agentCount)
+		path := metro.way.pathsToExit[gate_nb]
+		ag := NewAgent(id, metro.way.env, make(chan int), 200, 0, true, &UsagerLambda{}, metro.way.gates[gate_nb], metro.way.nearestExit[gate_nb], width, height)
+		ag.path = path
+		writeAgent(&ag.env.station,ag)
+		metro.way.env.AddAgent(*ag)
+		//log.Println(metro.way.id, nb, metro.way.env.agentCount)
+		//fmt.Println("agent leaving metro", ag.id, ag.departure, ag.destination, width, height)
+		//time.Sleep(500 * time.Millisecond)
+	}
+
+}
+
+func (metro *Metro) printMetro() {
+
+	if metro.way.horizontal {
+		waiting_time := time.Duration((metro_speed * 1000) / (metro.way.downRightCoord[1] - metro.way.upLeftCoord[1]))
+		if metro.way.goToLeft {
+			for y := metro.way.downRightCoord[1]; y >= metro.way.upLeftCoord[1]; y-- {
+				for x := metro.way.upLeftCoord[0]; x <= metro.way.downRightCoord[0]; x++ {
+					if metro.way.env.station[x][y] == "Q" {
+						metro.way.env.station[x][y] = "M"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		} else {
+			for y := metro.way.upLeftCoord[1]; y <= metro.way.downRightCoord[1]; y++ {
+				for x := metro.way.upLeftCoord[0]; x <= metro.way.downRightCoord[0]; x++ {
+					if metro.way.env.station[x][y] == "Q" {
+						metro.way.env.station[x][y] = "M"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		}
+
+	} else {
+		waiting_time := time.Duration((metro_speed * 1000) / (metro.way.downRightCoord[0] - metro.way.upLeftCoord[0]))
+		if metro.way.goToLeft {
+			// de bas en haut
+			for x := metro.way.downRightCoord[0]; x >= metro.way.upLeftCoord[0]; x-- {
+				for y := metro.way.upLeftCoord[1]; y <= metro.way.downRightCoord[1]; y++ {
+					if metro.way.env.station[x][y] == "Q" {
+						metro.way.env.station[x][y] = "M"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		} else {
+			for x := metro.way.upLeftCoord[0]; x <= metro.way.downRightCoord[0]; x++ {
+				for y := metro.way.upLeftCoord[1]; y <= metro.way.downRightCoord[1]; y++ {
+					if metro.way.env.station[x][y] == "Q" {
+						metro.way.env.station[x][y] = "M"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		}
+
+	}
+
+}
+
+func (metro *Metro) removeMetro() {
+
+	if metro.way.horizontal {
+		waiting_time := time.Duration((metro_speed * 1000) / (metro.way.downRightCoord[1] - metro.way.upLeftCoord[1]))
+
+		if metro.way.goToLeft {
+			for y := metro.way.downRightCoord[1]; y >= metro.way.upLeftCoord[1]; y-- {
+				for x := metro.way.upLeftCoord[0]; x <= metro.way.downRightCoord[0]; x++ {
+					if metro.way.env.station[x][y] == "M" {
+						metro.way.env.station[x][y] = "Q"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		} else {
+			for y := metro.way.upLeftCoord[1]; y <= metro.way.downRightCoord[1]; y++ {
+				for x := metro.way.upLeftCoord[0]; x <= metro.way.downRightCoord[0]; x++ {
+					if metro.way.env.station[x][y] == "M" {
+						metro.way.env.station[x][y] = "Q"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		}
+
+	} else {
+		waiting_time := time.Duration((metro_speed * 1000) / (metro.way.downRightCoord[0] - metro.way.upLeftCoord[0]))
+		if metro.way.goToLeft {
+			// de bas en haut
+			for x := metro.way.downRightCoord[0]; x >= metro.way.upLeftCoord[0]; x-- {
+				for y := metro.way.upLeftCoord[1]; y <= metro.way.downRightCoord[1]; y++ {
+					if metro.way.env.station[x][y] == "M" {
+						metro.way.env.station[x][y] = "Q"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		} else {
+			for x := metro.way.upLeftCoord[0]; x <= metro.way.downRightCoord[0]; x++ {
+				for y := metro.way.upLeftCoord[1]; y <= metro.way.downRightCoord[1]; y++ {
+					if metro.way.env.station[x][y] == "M" {
+						metro.way.env.station[x][y] = "Q"
+					}
+				}
+				time.Sleep(waiting_time * time.Millisecond)
+			}
+		}
+
+	}
+}
diff --git a/internal/simulation/mobiliteReduite.go b/internal/simulation/mobiliteReduite.go
index d0a9753038ddb1981b33e375f720551118b39653..1a3b43473ba8c8bc596032fdd0bf3628c878b183 100644
--- a/internal/simulation/mobiliteReduite.go
+++ b/internal/simulation/mobiliteReduite.go
@@ -8,33 +8,38 @@ import (
 	alg "metrosim/internal/algorithms"
 )
 
-var once sync.Once
+
 type MobiliteReduite struct {
-	faceCase string 
 	req *Request
+	once sync.Once
 }
 
+
 /*
-	Calcule le chemin de l'agent à mobilité réduite vers la porte la plus proche
+* Fonction qui permet de définir la destination d'un agent à mobilité réduite
 */
-func (mr * MobiliteReduite) setUpPath(ag *Agent) {
+func (mr *MobiliteReduite)setUpDestination(ag *Agent){
 	choix_voie := rand.Intn(2) // choix de la voie de départ aléatoire
-	fmt.Println("[MobiliteReduite, setUpPath] choix_voie = ",choix_voie)
-	dest_porte := ag.findNearestGate(ag.env.metros[choix_voie].way.gates)
+	//fmt.Println("[MobiliteReduite, setUpPath] choix_voie = ",choix_voie)
+	dest_porte := (ag.findNearestGates(ag.env.metros[choix_voie].way.gates))[0].Gate
 	fmt.Println("[MobiliteReduite, setUpPath] dest_porte = ",dest_porte)
 	ag.destination = dest_porte
+	mr.setUpPath(ag)
+}
+/*
+	Calcule le chemin de l'agent à mobilité réduite vers la porte la plus proche
+*/
+func (mr * MobiliteReduite) setUpPath(ag *Agent) {
 	start, end := ag.generatePathExtremities()
 	// Recherche d'un chemin si inexistant
 	path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 0), false, 2*time.Second)
 	ag.path = path
+	fmt.Println("[MobiliteReduite, setUpPath] path = ",ag.path)
 	ag.direction = calculDirection(ag.position, Coord{ag.path[0].Row(), ag.path[0].Col()})
 }
 
 func (mr *MobiliteReduite) Percept(ag *Agent) {
-	once.Do(func(){mr.setUpPath(ag)}) // la fonction setUp est executé à la premiere appel de la fonction Percept()
-	
-	mr.faceCase = ag.getFaceCase() // mettre à jour la case en face de l'agent en fonction de son attribut direction de deplacement
-	
+	mr.once.Do(func(){mr.setUpDestination(ag)}) // la fonction setUp est executé à la premiere appel de la fonction Percept()
 	switch {
 	case ag.request != nil: //verifier si l'agent est communiqué par un autre agent, par exemple un controleur lui a demandé de s'arreter
 		//print("Requete recue par l'agent lambda : ", ag.request.decision, "\n")
@@ -53,11 +58,13 @@ func (mr *MobiliteReduite) Deliberate(ag *Agent) {
 		if mr.req.decision == Stop{
 			ag.decision = Wait
 			mr.req = nil //demande traitée
-		} else { // sinon alors la requete est de type "Viré" cette condition est inutile car l'usager lambda ne peut pas etre expulsé , elle est nécessaire pour les agents fraudeurs
+		} else if mr.req.decision == Expel { // sinon alors la requete est de type "Viré" cette condition est inutile car l'usager lambda ne peut pas etre expulsé , elle est nécessaire pour les agents fraudeurs
 				//fmt.Println("[AgentLambda, Deliberate] Expel")
 				ag.decision = Expel
 				mr.req = nil //demande traitée
-		}
+			}else if mr.req.decision == Disappear {
+				ag.decision = Disappear
+			}
 	}else if ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") { // si l'agent est arrivé à sa destination et qu'il est sur une sortie
 			//fmt.Println(ag.id, "disappear")
 			ag.decision = Disappear
@@ -93,6 +100,9 @@ func (mr *MobiliteReduite) Act(ag *Agent) {
 */
 func (mr *MobiliteReduite) MoveMR(ag *Agent) {
 	// ================== Déplacement si aucun problème =======================
+	if(len(ag.path) <= 0){
+		mr.setUpPath(ag)
+	}
 	safe, or := IsMovementSafe(ag.path, ag, ag.env)
 	if safe {
 		if len(ag.isOn) > 0 {
diff --git a/internal/simulation/simu.go b/internal/simulation/simu.go
index 4d0041bc9287d0560de6b1c7e99df1560f51c925..aba913e5ca18b41d4c39a6dcb9e51acf5d389e3b 100644
--- a/internal/simulation/simu.go
+++ b/internal/simulation/simu.go
@@ -7,41 +7,78 @@ import (
 	"time"
 )
 
-// Déclaration de la matrice
 /*
- * X : Mur, zone inatteignable
- * E : Entrée
- * S : Sortie
- * W : Entrée et Sortie
- * Q : Voie
- * _ : Couloir, case libre
- * B: Bridge/Pont, zone accessible
- * valeur de AgentID : Agent
+ * //TODO: Mettre en place un débit d'apparition des agents
  */
-var carte [20][20]string = [20][20]string{
-	{"X", "X", "X", "X", "X", "X", "X", "X", "W", "W", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X"},
-	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X"},
-	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X"},
-	{"X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X"},
-	{"X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "_", "X", "X"},
-	{"X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "_", "X", "X"},
-	{"X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "_", "X"},
-	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
-	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "_"},
-	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B"},
-	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B"},
-	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B"},
-	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B"},
-	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
-	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
-	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X"},
-	{"X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X"},
-	{"X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X"},
-	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X"},
-	{"X", "X", "X", "X", "S", "S", "X", "X", "X", "X", "X", "X", "E", "E", "X", "X", "X", "X", "X", "X"},
+
+// Déclaration de la matrice
+/*
+  - X : Mur, zone inatteignable
+  - E : Entrée
+  - S : Sortie
+  - W : Entrée et Sortie
+  - Q : Voie
+  - _ : Couloir, case libre
+  - B: Bridge/Pont, zone accessible
+  - G: gate/porte de métro
+  - O : Porte ouverte
+  - M : rame de métro
+  - valeur de AgentID : Agent
+*/
+var carte [50][50]string = [50][50]string{
+	{"X", "X", "X", "X", "X", "X", "X", "X", "W", "W", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "_", "X", "X", "X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "_", "X", "X", "X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "_", "_", "X", "X", "_", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "Q", "B", "B", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
+	{"X", "X", "X", "X", "S", "S", "X", "X", "X", "X", "X", "X", "E", "E", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "E", "E", "X", "X", "X", "X", "X", "X", "S", "S", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "W", "W"},
 }
 
-var playground [20][20]string = [20][20]string{
+var playground [50][50]string = [50][50]string{
 	{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
 	{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
 	{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
@@ -65,37 +102,36 @@ var playground [20][20]string = [20][20]string{
 }
 
 type Simulation struct {
-	env         Environment
-	agents      []Agent
-	maxStep     int
-	maxDuration time.Duration
-	step        int // Stats
-	start       time.Time
-	syncChans   sync.Map
-	metros      []Metro
+	env          Environment
+	maxStep      int
+	maxDuration  time.Duration
+	step         int // Stats
+	start        time.Time
+	syncChans    sync.Map
+	newAgentChan chan Agent // permet la création d'agent en cours de simulation (canal de com avec env)
 }
 
+// TODO:voir si agents est mis à jour lors de suppression d'agent
+
 func (sim *Simulation) Env() *Environment {
 	return &sim.env
 }
 
 func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu *Simulation) {
 	simu = &Simulation{}
-	simu.agents = make([]Agent, 0, agentCount)
 	simu.maxStep = maxStep
 	simu.maxDuration = maxDuration
 
-	// Communication entre agents
-	mapChan := make(map[AgentID]chan Request)
+	simu.newAgentChan = make(chan Agent, 200) // channel avec buffer pour gérer les sorties simultanées
 
 	// Création de l'environement
-	simu.env = *NewEnvironment([]Agent{}, carte, mapChan)
+	simu.env = *NewEnvironment([]Agent{}, carte, simu.newAgentChan, agentCount)
 	//simu.env = *NewEnvironment([]Agent{}, playground, mapChan)
 
 	// Création du métro
-	metro1 := *NewMetro(10*time.Second, 5*time.Second, 2, &simu.env, NewWay(1, []Coord{{8, 5}}))
-	metro2 := *NewMetro(10*time.Second, 5*time.Second, 2, &simu.env, NewWay(2, []Coord{{13, 4}}))
-	simu.metros = []Metro{metro1, metro2}
+	//NewWay(wayId WayID, upLeftCoord, downRightCoord Coord, goToLeft bool, gates []Coord, env *Environment)
+	metro1 := *NewMetro(10*time.Second, 5*time.Second, 20, 2, NewWay(1, Coord{9, 0}, Coord{10, 39}, true, []Coord{{8, 5}, {8, 34}}, &simu.env))
+	metro2 := *NewMetro(10*time.Second, 5*time.Second, 20, 2, NewWay(2, Coord{11, 0}, Coord{12, 39}, false, []Coord{{13, 5}, {13, 34}}, &simu.env))
 	simu.env.metros = []Metro{metro1, metro2}
 
 	// création des agents et des channels
@@ -108,39 +144,40 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu
 
 		ag := &Agent{}
 
+
+
+		id := fmt.Sprintf("MR%d", i)
+		ag = NewAgent(id, &simu.env, syncChan, 400, 0, true, &MobiliteReduite{}, Coord{0, 28}, Coord{8, 5}, 1, 1)
+		/*
 		if i%2 == 0 { //Type Agent
 			id := fmt.Sprintf("MR%d", i)
 			//NewAgent(id string, env *Environment, syncChan chan int, vitesse time.Duration, force int, politesse bool, behavior Behavior, departure, destination Coord, width, height int)
-			ag = NewAgent(id, &simu.env, syncChan, 200, 0, true, &MobiliteReduite{}, Coord{18, 4}, Coord{13, 4}, 1, 1)
+			ag = NewAgent(id, &simu.env, syncChan, 200, 0, true, &UsagerLambda{}, Coord{49, 32}, Coord{0, 9}, 2, 1)
 		} else { // Type Controleur
 			//id := fmt.Sprintf("Controleur%d", i)
-			id := fmt.Sprintf("Controleur%d", i)
-			//ag = NewAgent(id, &simu.env, syncChan, 500, 0, true, &Controleur{}, Coord{1, 8}, Coord{8, 5}, 1, 1)
-			ag = NewAgent(id, &simu.env, syncChan, 1000, 0, true, &Controleur{}, Coord{18, 12}, Coord{18, 4}, 1, 1)
+			id := fmt.Sprintf("Agent%d", i)
+			ag = NewAgent(id, &simu.env, syncChan, 200, 0, true, &UsagerLambda{}, Coord{0, 8}, Coord{8, 5}, 1, 1)
+			//ag = NewAgent(id, &simu.env, syncChan, 1000, 0, true, &Controleur{}, Coord{18, 12}, Coord{18, 4}, 1, 1)
 		}
+		*/
 
 		//ag := NewAgent(id, &simu.env, syncChan, 1000, 0, true, &UsagerLambda{}, Coord{19, 12}, Coord{0, 8}, 2, 1)
 
 		// ajout de l'agent à la simulation
-		simu.agents = append(simu.agents, *ag)
+		simu.env.ags = append(simu.env.ags, *ag)
+
+		simu.env.agentsChan[ag.id] = make(chan Request, 5)
 
 		// ajout du channel de synchro
 		simu.syncChans.Store(ag.ID(), syncChan)
 
-		// ajout de l'agent à l'environnement
-		ag.env.AddAgent(*ag)
-		ag.env.controlledAgents[ag.id] = false
-
-		// ajout du channel de l'agent à l'environnement
-		simu.env.agentsChan[ag.id] = make(chan Request)
 	}
 
 	return simu
 }
 
 func (simu *Simulation) Run() {
-	// A REVOIR si nécessaire de faire appeler simu.env.pi()
-	log.Printf("Démarrage de la simulation [step: %d, π: %f]", simu.step, simu.env.PI())
+	log.Printf("Démarrage de la simulation ")
 	// Démarrage du micro-service de Log
 	go simu.Log()
 	// Démarrage du micro-service d'affichage
@@ -149,7 +186,7 @@ func (simu *Simulation) Run() {
 	// Démarrage des agents
 
 	var wg sync.WaitGroup
-	for _, agt := range simu.agents {
+	for _, agt := range simu.env.ags {
 		wg.Add(1)
 		go func(agent Agent) {
 			defer wg.Done()
@@ -161,7 +198,7 @@ func (simu *Simulation) Run() {
 	simu.start = time.Now()
 
 	// Lancement des métros
-	for _, metro := range simu.metros {
+	for _, metro := range simu.env.metros {
 		wg.Add(1)
 		go func(metro Metro) {
 			defer wg.Done()
@@ -170,8 +207,8 @@ func (simu *Simulation) Run() {
 	}
 
 	// Lancement de l'orchestration de tous les agents
-	// simu.step += 1 // plus de sens
-	for _, agt := range simu.agents {
+
+	for _, agt := range simu.env.ags {
 		go func(agt Agent) {
 			step := 0
 			for {
@@ -184,45 +221,59 @@ func (simu *Simulation) Run() {
 		}(agt)
 	}
 
+	go simu.listenNewAgentChan()
+
 	time.Sleep(simu.maxDuration)
 
-	log.Printf("Fin de la simulation [step: %d, in: %d, out: %d, π: %f]", simu.step, simu.env.PI())
 }
+func (simu *Simulation) listenNewAgentChan() {
+	for {
+		select {
+		case newAgent := <-simu.newAgentChan:
+			//simu.env.ags = append(simu.env.ags, newAgent)
+			simu.syncChans.Store(newAgent.ID(), newAgent.syncChan)
+			go func(agent Agent) {
+				agent.Start()
+			}(newAgent)
+			go func(agent Agent) {
+				step := 0
+				for {
+					step++
+					c, _ := simu.syncChans.Load(agent.ID()) // communiquer les steps aux agents
+					c.(chan int) <- step                    // /!\ utilisation d'un "Type Assertion"
+					time.Sleep(1 * time.Millisecond)        // "cool down"
+					<-c.(chan int)
+				}
+			}(newAgent)
+
+			// Add the new agent to simu.agents
+
+		}
+	}
+}
+
 
-func (simu *Simulation) Print_v0() {
+func (simu *Simulation) Print() {
 	for {
 		for i := 0; i < 20; i++ {
-			fmt.Println(simu.env.station[i])
+			for j := 0; j < 50; j++ {
+				element := simu.env.station[i][j]
+				if len(element) > 1 {
+					fmt.Print(element[len(element)-1:] + " ") // Afficher le premier caractère si la longueur est supérieure à 1
+				} else {
+					fmt.Print(element + " ")
+				}
+			}
+			fmt.Println()
 		}
-		//fmt.Println("=================================================================================")
 		fmt.Println()
 		fmt.Println()
+		//fmt.Println("============================================================")
 		//time.Sleep(time.Second / 4) // 60 fps !
-		time.Sleep(500 * time.Millisecond) // 1 fps !
-		//fmt.Print("\033[H\033[2J") // effacement du terminal
+		time.Sleep(200 * time.Millisecond) // 1 fps !
 	}
 }
-func (simu *Simulation) Print() {
-    for {
-        for i := 0; i < len(simu.env.station[0]); i++ {
-            for j := 0; j < len(simu.env.station[0]); j++ {
-                element := simu.env.station[i][j]
-                if len(element) > 1 {
-                    fmt.Print(string(element[0]) + " ") // Afficher le premier caractère si la longueur est supérieure à 1
-                } else {
-                    fmt.Print(element+" ")
-                }
-            }
-            fmt.Println()
-        }
-        fmt.Println()
-		fmt.Println()
-        //fmt.Println("============================================================")
-        //time.Sleep(time.Second / 4) // 60 fps !
-        time.Sleep(500 * time.Millisecond) // 1 fps !
-        //fmt.Print("\033[H\033[2J") // effacement du terminal
-    }
-}
+
 
 func (simu *Simulation) Log() {
 	// Not implemented
diff --git a/internal/simulation/usagerLambda.go b/internal/simulation/usagerLambda.go
index b50fdef505118330d8833d0f5f47db0b17b17e47..7ec0bd21d7075f0cfbcb8d3122a5a3cab8a60e56 100644
--- a/internal/simulation/usagerLambda.go
+++ b/internal/simulation/usagerLambda.go
@@ -2,9 +2,10 @@ package simulation
 
 import (
 	//"fmt"
+
 	"math/rand"
-	"time"
 	alg "metrosim/internal/algorithms"
+	"time"
 )
 
 type UsagerLambda struct {
@@ -23,7 +24,6 @@ func (ul *UsagerLambda) Percept(ag *Agent) {
 
 		}
 	}
-
 }
 
 func (ul *UsagerLambda) Deliberate(ag *Agent) {
@@ -32,12 +32,19 @@ func (ul *UsagerLambda) Deliberate(ag *Agent) {
 		if ul.req.decision == Stop{
 			ag.decision = Wait
 			ul.req = nil //demande traitée
-		} else { // sinon alors la requete est de type "Viré" cette condition est inutile car l'usager lambda ne peut pas etre expulsé , elle est nécessaire pour les agents fraudeurs
+			return
+		} else if ul.req.decision == Expel { // cette condition est inutile car l'usager lambda ne peut pas etre expulsé , elle est nécessaire pour les agents fraudeurs
 				//fmt.Println("[AgentLambda, Deliberate] Expel")
 				ag.decision = Expel
 				ul.req = nil //demande traitée
+				return
+		}else if ul.req.decision == Disappear {
+			ag.decision = Disappear
+			return
+		}else if ul.req.decision == Wait {
+			ag.decision = Wait
 		}
-	}else if ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") { // si l'agent est arrivé à sa destination et qu'il est sur une sortie
+	}else if (ag.position != ag.departure && ag.position == ag.destination) && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") { // si l'agent est arrivé à sa destination et qu'il est sur une sortie
 			//fmt.Println(ag.id, "disappear")
 			ag.decision = Disappear
 		} else if ag.stuck{ // si l'agent est bloqué
@@ -56,12 +63,14 @@ func (ul *UsagerLambda) Act(ag *Agent) {
 		time.Sleep(time.Duration(n) * time.Second)
 	} else if ag.decision == Disappear {
 		RemoveAgent(&ag.env.station, ag)
-	} else { //age.decision == Expel
+	} else if ag.decision == Expel {
 		//fmt.Println("[AgentLambda, Act] Expel")
 		ag.destination = ag.findNearestExit()
 		//fmt.Println("[AgentLambda, Act] destination = ",ag.destination)
 		ag.env.controlledAgents[ag.id] = true
-		ag.path = make([]alg.Node,0)
+		ag.path = make([]alg.Node, 0)
 		ag.MoveAgent()
+	} else {
+		// nothing to wait
 	}
 }
diff --git a/internal/simulation/way.go b/internal/simulation/way.go
index 87212b517ae3fa6b73a3df679c04dbc661960854..141e50d1d17da44c1d996379108c7192e8f12498 100644
--- a/internal/simulation/way.go
+++ b/internal/simulation/way.go
@@ -1,14 +1,72 @@
 package simulation
 
+/*
+ * Classe et méthodes principales de la structure Way (porte de métro)
+ */
+
+import (
+	alg "metrosim/internal/algorithms"
+	"time"
+)
+
 type Way struct {
-	id    WayID
-	gates []Coord //listes des portes associée à la voie
+	id             WayID
+	upLeftCoord    Coord // inclus
+	downRightCoord Coord // inclus
+	goToLeft       bool  // si vrai, le métro se déplace de droite à gauche, si faux de gauche à droite
+	horizontal     bool
+	gates          []Coord //listes des portes associée à la voie
+	nearestExit    []Coord // Chemin vers la sortie la plus proche pour chaque porte (index vers pathsToExit)
+	pathsToExit    [][]alg.Node
+	env            *Environment
 }
 
 type WayID int
 
-func NewWay(wayId WayID, gates []Coord) *Way {
+func NewWay(wayId WayID, upLeftCoord, downRightCoord Coord, goToLeft bool, gates []Coord, env *Environment) *Way {
+	/* Affichage des portes */
+	for _, gate := range gates {
+		if !(gate[0] < 0 || gate[1] > 49) && env.station[gate[0]][gate[1]] != "X" && env.station[gate[0]][gate[1]] != "Q" {
+			env.station[gate[0]][gate[1]] = "G"
+		}
+
+	}
+	/* Sens de la voie */
+	horizontal := true
+	if alg.Abs(upLeftCoord[0]-downRightCoord[0]) > alg.Abs(upLeftCoord[1]-downRightCoord[1]) {
+		horizontal = false
+	}
+	nearestExit := make([]Coord, len(gates))
+	pathsToExit := make([][]alg.Node, len(gates))
+	for index, gate := range gates {
+		row, col := alg.FindNearestExit(env.station, gate[0], gate[1])
+		nearestExit[index] = Coord{row, col}
+		pathsToExit[index] = alg.FindPath(env.station, *alg.NewNode(gate[0], gate[1], 0, 0, 1, 1), *alg.NewNode(row, col, 0, 0, 0, 0), *alg.NewNode(-1, -1, 0, 0, 0, 0), false, 5*time.Second)
+		index++
+	}
+
 	return &Way{
-		id:    wayId,
-		gates: gates}
+		id:             wayId,
+		upLeftCoord:    upLeftCoord,
+		downRightCoord: downRightCoord,
+		goToLeft:       goToLeft,
+		horizontal:     horizontal,
+		gates:          gates,
+		nearestExit:    nearestExit,
+		pathsToExit:    pathsToExit,
+		env:            env}
+}
+
+func (way *Way) openGates() {
+	// Début d'autorisation d'entrer dans le métro
+	for _, gate := range way.gates {
+		way.env.station[gate[0]][gate[1]] = "O"
+	}
+}
+
+func (way *Way) closeGates() {
+	// Fin d'autorisation d'entrer dans le métro
+	for _, gate := range way.gates {
+		way.env.station[gate[0]][gate[1]] = "G"
+	}
 }