diff --git a/cmd/simu/main.go b/cmd/simu/main.go
index c8ccb5a2534b19973e7cd4ee5d10e94ff0e700f4..f963e03be40af2a537924923ad7f76bad953b94a 100644
--- a/cmd/simu/main.go
+++ b/cmd/simu/main.go
@@ -6,8 +6,7 @@ import (
 )
 
 func main() {
-	s := simulation.NewSimulation(3, -1, 600*time.Second)
-	//go simulation.StartAPI(s)
+	s := simulation.NewSimulation(10, -1, 600*time.Second)
 	//go simulation.StartAPI(s)
 	s.Run()
 }
diff --git a/go.mod b/go.mod
index e05f097a3e2aa9273f01fe45320f4dd910b237cd..b98b1cd48f76bc17ca17b46f8e4776b9be866d54 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module metrosim
 
-go 1.23
+go 1.21.1
diff --git a/internal/algorithms/astar.go b/internal/algorithms/astar.go
index d1fc5062c3e54db8733201f9de67c1036b26b6e1..1b706ea39da6cbe1e0856ecde45cba215405521a 100644
--- a/internal/algorithms/astar.go
+++ b/internal/algorithms/astar.go
@@ -2,7 +2,9 @@ package algorithms
 
 import (
 	"container/heap"
+	"context"
 	"math/rand"
+	"time"
 )
 
 /*
@@ -62,7 +64,11 @@ 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) []Node {
+func FindPath(matrix [20][20]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()
+
 	pq := make(PriorityQueue, 0)
 	heap.Init(&pq)
 
@@ -76,6 +82,13 @@ func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node, orienta
 	foundPath := false
 
 	for pq.Len() > 0 {
+		select {
+		case <-ctx.Done():
+			// Timeout reached, return an error or handle accordingly
+			return nil
+		default:
+			// Continue with the algorithm
+		}
 		current := heap.Pop(&pq).(*Node)
 
 		// Mise à jour du point le plus proche si le point actuel est plus proche
@@ -120,10 +133,9 @@ func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node, orienta
 }
 
 func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node, orientation bool) []*Node {
-	//fmt.Println("okk")
 	neighbors := make([]*Node, 0)
 
-	// Possible moves: up, down, left, right
+	// Déplacements possibles: up, down, left, right
 	possibleMoves := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
 
 	for _, move := range possibleMoves {
@@ -131,8 +143,7 @@ func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node,
 		if orientation {
 			for or := 0; or < 4; or++ {
 				current.orientation = or
-				//fmt.Println(orientation)
-				//Check if the new position is valid, considering agent dimensions and rotation
+				//Vérifie que le déplacement soit valide
 				if isValidMove(matrix, current, forbiddenCell, newRow, newCol, orientation) {
 					neighbors = append(neighbors, &Node{
 						row:         newRow,
@@ -169,7 +180,8 @@ func Heuristic(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(3)
+	return abs(row-end.row) + abs(col-end.col) + rand.Intn(10)
 }
 
 func abs(x int) int {
diff --git a/internal/simulation/agent.go b/internal/simulation/agent.go
index 53bd71836d92fbfe12821a7f2008d0f8931829e1..f90daf0b5114a74ac4300b5e8adc708b30cfe377 100644
--- a/internal/simulation/agent.go
+++ b/internal/simulation/agent.go
@@ -9,13 +9,9 @@ package simulation
  */
 
 import (
-	//"fmt"
-
-	//"log"
+	"fmt"
+	"log"
 	"math/rand"
-
-	//"math"
-	//"math/rand"
 	alg "metrosim/internal/algorithms"
 	"time"
 )
@@ -27,9 +23,10 @@ const (
 	Mark
 	Wait
 	Move
-	Disapear
+	Disappear
 	Expel // virer l'agent
 	Stop  // arreter l'agent
+	GiveInfos
 )
 
 type Coord [2]int
@@ -76,14 +73,7 @@ func NewRequest(demandeur chan Request, decision int) (req *Request) {
 
 func NewAgent(id string, env *Environment, syncChan chan int, vitesse time.Duration, force int, politesse bool, behavior Behavior, departure, destination Coord, width, height int) *Agent {
 	isOn := make(map[Coord]string)
-	saveCells(&env.station, isOn, departure, width, height, 0)
-	// Enregistrement des panneaux menant à la zone
-	// visitedPanneaux := make(map[alg.Node]bool, len(env.panneaux[env.zones[destination]]))
-	// for _, panneau := range env.panneaux[env.zones[destination]] {
-	// 	visitedPanneaux[panneau] = false
-	// }
-	// visiting := alg.NewNode(destination[0], destination[1], 0, HeuristicWithObstacles(departure, destination, env), 0, 0)
-	return &Agent{AgentID(id), vitesse, force, politesse, departure, departure, destination, behavior, env, syncChan, Noop, isOn, false, width, height, 0, make([]alg.Node, 0), nil, 0}
+	return &Agent{AgentID(id), vitesse, force, politesse, departure, departure, destination, behavior, env, syncChan, Noop, isOn, false, width, height, 3, make([]alg.Node, 0), nil,0}
 }
 
 func (ag *Agent) ID() AgentID {
@@ -91,8 +81,8 @@ func (ag *Agent) ID() AgentID {
 }
 
 func (ag *Agent) Start() {
-	//log.Printf("%s starting...\n", ag.id)
-
+	log.Printf("%s starting...\n", ag.id)
+	go ag.listenForRequests()
 	go func() {
 		var step int
 		for {
@@ -101,7 +91,7 @@ func (ag *Agent) Start() {
 			ag.behavior.Deliberate(ag)
 			ag.behavior.Act(ag)
 			ag.syncChan <- step
-			if ag.decision == Disapear {
+			if ag.decision == Disappear {
 				ag.env.RemoveAgent(*ag)
 				return
 			}
@@ -124,6 +114,10 @@ func IsMovementSafe(path []alg.Node, agt *Agent, env *Environment) (bool, int) {
 	// Calcul des bornes de position de l'agent avant mouvement
 	infRow, supRow, infCol, supCol := calculateBounds(agt.position, agt.width, agt.height, agt.orientation)
 
+	// 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 {
+		return false, agt.orientation
+	}
 	// Simulation du déplacement
 	ag := *agt
 	ag.position = Coord{path[0].Row(), path[0].Col()}
@@ -165,16 +159,13 @@ func IsAgentBlocking(path []alg.Node, agt *Agent, env *Environment) bool {
 	for or := 0; or < 4; or++ {
 		rotateAgent(&ag, or)
 		blocking := false
-		//Test
-
 		// Calcul des bornes de position de l'agent après mouvement
 		borneInfRow, borneSupRow, borneInfCol, borneSupCol := calculateBounds(ag.position, ag.width, ag.height, ag.orientation)
-
+		//fmt.Println(ag.id,borneInfRow,borneInfRow, borneSupRow, borneInfCol, borneSupCol)
 		if !(borneInfCol < 0 || borneInfRow < 0 || borneSupRow > 20 || borneSupCol > 20) {
 			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] == "A" {
-
+					if !(j >= infCol && j < supCol && i >= infRow && i < supRow) && len(env.station[i][j]) > 2 {
 						// Si on n'est pas sur une case atteignable, en dehors de la zone qu'occupe l'agent avant déplacement, on est bloqué
 						blocking = true
 					}
@@ -208,7 +199,7 @@ func (ag *Agent) isStuck() bool {
 				count++
 			}
 			// Case inaccessible
-			if i < 0 || j < 0 || i > 19 || j > 19 || ag.env.station[i][j] == "X" || ag.env.station[i][j] == "Q" || existAgent(ag.env.station[i][j]) {
+			if i < 0 || j < 0 || i > 19 || j > 19 || ag.env.station[i][j] == "X" || ag.env.station[i][j] == "Q" || len(ag.env.station[i][j]) > 2 {
 				not_acc++
 
 			}
@@ -248,26 +239,27 @@ func (ag *Agent) MoveAgent() {
 	if len(ag.path) == 0 {
 		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)
+		path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 0), false, 2*time.Second)
 		ag.path = path
 	}
 
 	// ================== Etude de faisabilité =======================
 	if IsAgentBlocking(ag.path, ag, ag.env) {
+		
 		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)
+			path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 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)
+			//blockingAgent := ag.env.FindAgentByID(blockingAgentID)
 			var reqToBlockingAgent *Request
-			var reqToImpoliteAgent *Request
+			//var reqToImpoliteAgent *Request
 			i := 0
 			accept := false
 			for !accept && i < 3 {
@@ -282,7 +274,7 @@ func (ag *Agent) MoveAgent() {
 
 
 				*/
-
+				/*
 				//BlockingAgent cherche si autour de lui c'est vide
 				possible, or := IsMovementSafe(blockingAgent.path, blockingAgent, blockingAgent.env)
 
@@ -295,6 +287,7 @@ func (ag *Agent) MoveAgent() {
 					coordBlockingAgent := blockingAgent.position
 					//Gérer le déplacement de Ag et de BlockingAgent + déplacement en fonction de la force !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 				}
+				*/
 			}
 		}
 	}
@@ -302,13 +295,11 @@ func (ag *Agent) MoveAgent() {
 	// ================== Déplacement si aucun problème ou si blockingAgent se pousse =======================
 	safe, or := IsMovementSafe(ag.path, ag, ag.env)
 	if safe {
-		RemoveAgent(&ag.env.station, ag)
-		rotateAgent(ag, or) // mise à jour de l'orientation
-		//ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = ag.isOn
-
-		//MODIFICATION DE DIRECTION
+		if len(ag.isOn) > 0 {
+			RemoveAgent(&ag.env.station, ag)
+		}
+		rotateAgent(ag, or)
 		ag.direction = calculDirection(ag.position, Coord{ag.path[0].Row(), ag.path[0].Col()})
-		//fmt.Println("[MoveAgent]Direction : ", ag.direction)
 		ag.position[0] = ag.path[0].Row()
 		ag.position[1] = ag.path[0].Col()
 		if len(ag.path) > 1 {
@@ -317,12 +308,11 @@ func (ag *Agent) MoveAgent() {
 			ag.path = nil
 		}
 		saveCells(&ag.env.station, ag.isOn, ag.position, ag.width, ag.height, ag.orientation)
-		//ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = "A"
 		writeAgent(&ag.env.station, ag)
 		// ============ Prise en compte de la vitesse de déplacement ======================
 		time.Sleep(ag.vitesse * time.Millisecond)
-
 	}
+
 }
 
 func (ag *Agent) generatePathExtremities() (alg.Node, alg.Node) {
@@ -428,3 +418,16 @@ func calculateBounds(position Coord, width, height, orientation int) (infRow, su
 	}
 	return borneInfRow, borneSupRow, borneInfCol, borneSupCol
 }
+
+func (ag *Agent) listenForRequests() {
+	for {
+		if ag.request == nil {
+			req := <-ag.env.agentsChan[ag.id]
+			fmt.Println("Request received by UsagerLambda:", req.decision)
+			ag.request = &req
+			if req.decision == Disappear {
+				return
+			}
+		}
+	}
+}
diff --git a/internal/simulation/controleur.go b/internal/simulation/controleur.go
index bbd400f8c696a11dcb57f6118418874f53893e48..bc17235c7803339b1a604efba5af299421e80fae 100644
--- a/internal/simulation/controleur.go
+++ b/internal/simulation/controleur.go
@@ -3,10 +3,11 @@ package simulation
 //ajouter liste des agents déjà controllés
 
 import (
+	"fmt"
 	"math/rand"
 	"regexp"
 	"time"
-	//"fmt"
+	//"time"
 )
 
 /*
@@ -73,9 +74,9 @@ func (c *Controleur) Act(ag *Agent) {
 	} else if ag.decision == Wait {
 		n := rand.Intn(2) // temps d'attente aléatoire
 		time.Sleep(time.Duration(n) * time.Second)
-	} else { // Expel ou Wait
-		agt_face_id := AgentID(c.faceCase)                                                   //id de l'agent qui se trouve devant le controleur
+	} else {
+		agt_face_id := AgentID(c.faceCase) //id de l'agent qui se trouve devant le controleur
+		fmt.Print("L'agent ", agt_face_id, " a été expulsé\n")
 		ag.env.agentsChan[agt_face_id] <- *NewRequest(ag.env.agentsChan[ag.id], ag.decision) // envoie la decision du controleur à l'agent qui se trouve devant lui
-		//fmt.Print("[Controlleur , Act ]requête envoyée à l'agent ", agt_face_id, "\n")
 	}
 }
diff --git a/internal/simulation/env.go b/internal/simulation/env.go
index 9d7f02e4b1eb43b7626ccd0013189b69c695bb13..9dbca0de1fcb8f16ed328c4a62467aa0e9d743bf 100644
--- a/internal/simulation/env.go
+++ b/internal/simulation/env.go
@@ -16,13 +16,6 @@ type Environment struct {
 	// panneaux   map[ZoneID][]alg.Node // Les panneaux de la station, permettant d'aller vers la zone
 }
 
-type ZoneID int
-
-
-
-
-
-
 func NewEnvironment(ags []Agent, carte [20][20]string, agentsCh map[AgentID]chan Request) (env *Environment) {
 	mapControlle := make(map[AgentID]bool)
 	for _, ag := range ags {
@@ -31,7 +24,6 @@ func NewEnvironment(ags []Agent, carte [20][20]string, agentsCh map[AgentID]chan
 	return &Environment{ags: ags, agentCount: len(ags), station: carte, agentsChan: agentsCh, controlledAgents: mapControlle}
 }
 
-
 func (env *Environment) AddAgent(agt Agent) {
 	env.ags = append(env.ags, agt)
 	env.agentCount++
@@ -39,9 +31,10 @@ func (env *Environment) AddAgent(agt Agent) {
 
 func (env *Environment) RemoveAgent(agt Agent) {
 	for i := 0; i < len(env.station); i++ {
-		if env.ags[i].id == agt.id{
+		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)
 			// Sortir de la boucle après avoir trouvé et supprimé l'élément
 			break
 		}
@@ -79,7 +72,6 @@ func (env *Environment) Rect() Coord {
 	return Coord{0, 0}
 }
 
-
 func (env *Environment) GetAgentChan(agt_id AgentID) chan Request {
 	return env.agentsChan[agt_id]
 }
@@ -102,4 +94,4 @@ func calculDirection(depart Coord, arrive Coord) int {
 			return 2 //bas
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/internal/simulation/metro.go b/internal/simulation/metro.go
new file mode 100644
index 0000000000000000000000000000000000000000..a31708b76854f47807cac797f2f2fbfc72c3365f
--- /dev/null
+++ b/internal/simulation/metro.go
@@ -0,0 +1,82 @@
+package simulation
+
+import (
+	"fmt"
+	"log"
+	"math/rand"
+	"time"
+)
+
+type Metro struct {
+	frequency  time.Duration
+	stopTime   time.Duration
+	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 {
+	return &Metro{
+		frequency:  freq,
+		stopTime:   stopT,
+		freeSpace:  freeS,
+		env:        env,
+		comChannel: make(chan Request),
+		way:        way,
+	}
+}
+
+func (metro *Metro) Start() {
+	log.Printf("Metro starting...\n")
+	refTime := time.Now()
+	go func() {
+		//var step int
+		for {
+			//step = <-metro.syncChan
+			if refTime.Add(metro.frequency).Before(time.Now()) {
+				go metro.pickUpUsers()
+				metro.freeSpace = rand.Intn(10)
+				fmt.Println(metro.way.id, metro.freeSpace)
+				//go metro.dropUsers()
+				refTime = time.Now()
+			}
+			//metro.syncChan <- step
+
+		}
+	}()
+}
+
+func (metro *Metro) pickUpUsers() {
+	// Faire monter les usagers dans le métro
+	t := time.Now()
+	for time.Now().Before(t.Add(metro.stopTime)) {
+		if metro.freeSpace > 0 {
+			for _, gate := range metro.way.gates {
+				go metro.pickUpGate(&gate)
+			}
+		}
+	}
+}
+
+func (metro *Metro) pickUpGate(gate *Coord) {
+	// Récupérer les usagers à une porte spécifique
+	gate_cell := metro.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--
+		}
+	}
+}
+
+func (metro *Metro) findAgent(agent AgentID) *Agent {
+	// Trouver l'adresse de l'agent
+	for _, agt := range metro.env.ags {
+		if agt.id == agent {
+			return &agt
+		}
+	}
+	return nil
+}
diff --git a/internal/simulation/simu.go b/internal/simulation/simu.go
index 1d39fc2b5f6d5bb058e6307fd92254a3f6d78157..4f93e7d8e2a42141e36dec7970b3467ea4c7acb1 100644
--- a/internal/simulation/simu.go
+++ b/internal/simulation/simu.go
@@ -41,7 +41,6 @@ var carte [20][20]string = [20][20]string{
 	{"X", "X", "X", "X", "S", "S", "X", "X", "X", "X", "X", "X", "E", "E", "X", "X", "X", "X", "X", "X"},
 }
 
-
 var playground [20][20]string = [20][20]string{
 	{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
 	{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
@@ -73,6 +72,7 @@ type Simulation struct {
 	step        int // Stats
 	start       time.Time
 	syncChans   sync.Map
+	metros      []Metro
 }
 
 func (sim *Simulation) Env() *Environment {
@@ -87,32 +87,37 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu
 
 	// Communication entre agents
 	mapChan := make(map[AgentID]chan Request)
+
+	// Création de l'environement
 	simu.env = *NewEnvironment([]Agent{}, carte, mapChan)
 	//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}
+
 	// création des agents et des channels
 	for i := 0; i < agentCount; i++ {
 		// création de l'agent
-		
+
 		syncChan := make(chan int)
 		//ag := NewAgent(id, &simu.env, syncChan, time.Duration(time.Second), 0, true, Coord{0, 8 + i%2}, Coord{0, 8 + i%2}, &UsagerLambda{}, Coord{0, 8 + i%2}, Coord{12 - 4*(i%2), 18 - 15*(i%2)})
-
 		//ag := NewAgent(id, &simu.env, syncChan, 1000, 0, true, &UsagerLambda{},  Coord{18, 4}, Coord{0, 8}, 2, 1)
-		
-		
+
 		ag := &Agent{}
-		
-		if i%2==0{ //Type Agent
+
+		if i%2 == 0 { //Type Agent
 			id := fmt.Sprintf("Agent%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, 1000, 0, true, &UsagerLambda{}, Coord{16, 5+i}, Coord{0, 8}, 1, 1)
-		}else{ // Type Controleur
-			id := fmt.Sprintf("Controleur%d", i)
-			//ag = NewAgent(id, &simu.env, syncChan, 1000, 0, true, &UsagerLambda{}, Coord{1, 8}, Coord{8, 5}, 1, 1)
-			ag = NewAgent(id, &simu.env, syncChan, 1000, 0, true, &Controleur{}, Coord{16, 12}, Coord{18, 4}, 1, 1)
+			ag = NewAgent(id, &simu.env, syncChan, 200, 0, true, &UsagerLambda{}, Coord{18, 4}, Coord{13, 4}, 1, 1)
+		} else { // Type Controleur
+			//id := fmt.Sprintf("Controleur%d", i)
+			id := fmt.Sprintf("Agent%d", i)
+			ag = NewAgent(id, &simu.env, syncChan, 200, 0, true, &UsagerLambda{}, 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)
 		}
-		
-		
+
 		//ag := NewAgent(id, &simu.env, syncChan, 1000, 0, true, &UsagerLambda{}, Coord{19, 12}, Coord{0, 8}, 2, 1)
 
 		// ajout de l'agent à la simulation
@@ -129,13 +134,11 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu
 		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() 
+	// 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())
 	// Démarrage du micro-service de Log
 	go simu.Log()
@@ -156,6 +159,15 @@ func (simu *Simulation) Run() {
 	// On sauvegarde la date du début de la simulation
 	simu.start = time.Now()
 
+	// Lancement des métros
+	for _, metro := range simu.metros {
+		wg.Add(1)
+		go func(metro Metro) {
+			defer wg.Done()
+			metro.Start()
+		}(metro)
+	}
+
 	// Lancement de l'orchestration de tous les agents
 	// simu.step += 1 // plus de sens
 	for _, agt := range simu.agents {
@@ -164,8 +176,8 @@ func (simu *Simulation) Run() {
 			for {
 				step++
 				c, _ := simu.syncChans.Load(agt.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) <- step                  // /!\ utilisation d'un "Type Assertion"
+				time.Sleep(1 * time.Millisecond)      // "cool down"
 				<-c.(chan int)
 			}
 		}(agt)
@@ -176,7 +188,6 @@ func (simu *Simulation) Run() {
 	log.Printf("Fin de la simulation [step: %d, in: %d, out: %d, π: %f]", simu.step, simu.env.PI())
 }
 
-
 func (simu *Simulation) Print_v0() {
 	for {
 		for i := 0; i < 20; i++ {
@@ -191,28 +202,26 @@ func (simu *Simulation) Print_v0() {
 	}
 }
 func (simu *Simulation) Print() {
-    for {
-        for i := 0; i < 20; i++ {
-            for j := 0; j < 20; 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()
+	for {
+		for i := 0; i < 20; i++ {
+			for j := 0; j < 20; 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("============================================================")
-        //time.Sleep(time.Second / 4) // 60 fps !
-        time.Sleep(500 * time.Millisecond) // 1 fps !
-        //fmt.Print("\033[H\033[2J") // effacement du terminal
-    }
+		//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 216a45fd9902003a57db5a789403756f3ec63384..476751e00ba6ca85cf96915f9449768c74072a30 100644
--- a/internal/simulation/usagerLambda.go
+++ b/internal/simulation/usagerLambda.go
@@ -2,6 +2,7 @@ package simulation
 
 import (
 	//"fmt"
+	"fmt"
 	"math/rand"
 	alg "metrosim/internal/algorithms"
 	"time"
@@ -15,12 +16,23 @@ func (ul *UsagerLambda) Percept(ag *Agent) {
 	// récupérer le channel de l'agent lambda
 	//fmt.Println("[AgentLambda, Percept] direction ", ag.direction)
 
-	chan_agt := ag.env.GetAgentChan(ag.id)
-	select {
-	case req := <-chan_agt: //verifier si l'agent est communiqué par un autre agent, par exemple un controleur lui a demandé de s'arreter
-		//fmt.Println("[AgentLambda, Percept] Requete recue par l'agent lambda : ", req.decision)
-		ul.req = req
-	case <-time.After(time.Second):
+	// chan_agt := ag.env.GetAgentChan(ag.id)
+	// select {
+	// case req := <-chan_agt: //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 : ", req.decision, "\n")
+	// 	ul.req = req
+	// case <-time.After(100 * time.Millisecond):
+	// 	ag.stuck = ag.isStuck()
+	// 	if ag.stuck {
+	// 		return
+
+	// 	}
+	// }
+	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")
+		ul.req = *ag.request
+	default:
 		ag.stuck = ag.isStuck()
 		if ag.stuck {
 			return
@@ -37,9 +49,11 @@ func (ul *UsagerLambda) Deliberate(ag *Agent) {
 		ag.decision = Wait
 	} 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
 		ag.decision = Expel
-	} else if ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") {
-		//fmt.Println(ag.id, "disapear")
-		ag.decision = Disapear
+	} else if ul.req.decision == Disappear || (ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S")) {
+		fmt.Println(ag.id, "disapear")
+		ag.decision = Disappear
+	} else if ul.req.decision == Wait {
+		ag.decision = Wait
 	} else {
 		ag.decision = Move
 	}
@@ -52,7 +66,7 @@ func (ul *UsagerLambda) Act(ag *Agent) {
 	} else if ag.decision == Wait {
 		n := rand.Intn(2) // temps d'attente aléatoire
 		time.Sleep(time.Duration(n) * time.Second)
-	} else if ag.decision == Disapear {
+	} else if ag.decision == Disappear {
 		RemoveAgent(&ag.env.station, ag)
 	} else { //age.decision == Expel
 		//fmt.Println("[AgentLambda, Act] Expel")
diff --git a/internal/simulation/way.go b/internal/simulation/way.go
new file mode 100644
index 0000000000000000000000000000000000000000..87212b517ae3fa6b73a3df679c04dbc661960854
--- /dev/null
+++ b/internal/simulation/way.go
@@ -0,0 +1,14 @@
+package simulation
+
+type Way struct {
+	id    WayID
+	gates []Coord //listes des portes associée à la voie
+}
+
+type WayID int
+
+func NewWay(wayId WayID, gates []Coord) *Way {
+	return &Way{
+		id:    wayId,
+		gates: gates}
+}