diff --git a/agent.go b/agent.go
index 5a7d3269d8c03848cf17e690f24fa50ec5720d99..1222a62af26fcf5ef9d5c48693ee013dd7d53e8d 100644
--- a/agent.go
+++ b/agent.go
@@ -1,8 +1,11 @@
 package simulation
 
 import (
+	//"container/heap"
+	"fmt"
 	"log"
 	"math/rand"
+	"time"
 )
 
 type Action int64
@@ -10,39 +13,81 @@ type Action int64
 const (
 	Noop = iota
 	Mark
+	Wait
+	Move
 )
 
-type Coord [2]float64
+type Coord [2]int
+type AgentID string
 
-type Rect [2]Coord
+type Agent struct {
+	id                  AgentID
+	vitesse             int
+	force               int
+	politesse           bool
+	coordHautOccupation Coord
+	coordBasOccupation  Coord
+	departure           Coord
+	destination         Coord
+	behavior            Behavior
+	env                 *Environment
+	syncChan            chan int
+	decision            int
+	isOn                string // Contenu de la case sur laquelle il se trouve
+}
 
-type Agent interface {
-	Start()
-	Percept(*Environment)
-	Deliberate()
-	Act(*Environment)
-	ID() AgentID
+type Behavior interface {
+	// TODO: Comment faire pour ne pas passer l'agent en param ? C'est possible ?
+	Percept(*Agent, *Environment)
+	Deliberate(*Agent)
+	Act(*Agent, *Environment)
 }
 
-type AgentID string
+type UsagerLambda struct{}
+
+func (ul *UsagerLambda) Percept(ag *Agent, env *Environment) {
+}
+
+func (ul *UsagerLambda) Deliberate(ag *Agent) {
+	if ag.env.station[ag.departure[0]][ag.departure[1]] == "A" {
+		ag.decision = Wait
+	} else {
+		ag.decision = Move
+	}
+}
+
+func (ul *UsagerLambda) Act(ag *Agent, env *Environment) {
+	// TODO: Je crois que la construction d'un chemin s'arrête s'il y a déjà un agent sur destination. Il faudrait donc faire en sorte de s'approcher le plus possible
+	if ag.decision == Move {
+		start := ag.coordBasOccupation
+		end := ag.destination
+
+		path := findPathBFS(ag.env.station, start, end)
+		if len(path) > 0 && env.station[path[0][0]][path[0][1]] != "A" {
+			fmt.Println(ag.id, path)
+			ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = ag.isOn
+			ag.isOn = ag.env.station[path[0][0]][path[0][1]]
+			ag.coordBasOccupation[0] = path[0][0]
+			ag.coordBasOccupation[1] = path[0][1]
+			ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = "A"
+		}
+		vitesseInSeconds := int(ag.vitesse)
+		// Multiply the vitesse by time.Second
+		sleepDuration := time.Duration(vitesseInSeconds) * time.Second
+		time.Sleep(sleepDuration)
+	}
 
-type AgentPI struct {
-	id       AgentID
-	rect     Rect
-	decision Action
-	env      *Environment
-	syncChan chan int
 }
 
-func NewAgentPI(id string, env *Environment, syncChan chan int) *AgentPI {
-	return &AgentPI{AgentID(id), Rect{Coord{0, 0}, Coord{1, 1}}, Noop, env, syncChan}
+func NewAgent(id string, env *Environment, syncChan chan int, vitesse int, force int, politesse bool, UpCoord Coord, DownCoord Coord, behavior Behavior, departure, destination Coord) *Agent {
+	return &Agent{AgentID(id), vitesse, force, politesse, UpCoord, DownCoord, departure, destination, behavior, env, syncChan, Noop, env.station[UpCoord[0]][UpCoord[1]]}
 }
 
-func (ag *AgentPI) ID() AgentID {
+func (ag *Agent) ID() AgentID {
 	return ag.id
 }
 
-func (ag *AgentPI) Start() {
+func (ag *Agent) Start() {
 	log.Printf("%s starting...\n", ag.id)
 
 	go func() {
@@ -50,21 +95,19 @@ func (ag *AgentPI) Start() {
 		var step int
 		for {
 			step = <-ag.syncChan
-
-			ag.Percept(env)
-			ag.Deliberate()
-			ag.Act(env)
-
+			ag.behavior.Percept(ag, env)
+			ag.behavior.Deliberate(ag)
+			ag.behavior.Act(ag, env)
 			ag.syncChan <- step
 		}
 	}()
 }
 
-func (ag *AgentPI) Percept(env *Environment) {
-	ag.rect = env.Rect()
+func (ag *Agent) Percept(env *Environment) {
+	//ag.rect = env.Rect()
 }
 
-func (ag *AgentPI) Deliberate() {
+func (ag *Agent) Deliberate() {
 	if rand.Float64() < 0.1 {
 		ag.decision = Noop
 	} else {
@@ -72,12 +115,161 @@ func (ag *AgentPI) Deliberate() {
 	}
 }
 
-func (ag *AgentPI) Act(env *Environment) {
+func (ag *Agent) Act(env *Environment) {
 	if ag.decision == Noop {
 		env.Do(Noop, Coord{})
-	} else {
-		x := rand.Float64()*(ag.rect[1][0]-ag.rect[0][0]) + ag.rect[0][0]
-		y := rand.Float64()*(ag.rect[1][1]-ag.rect[0][1]) + ag.rect[0][1]
-		env.Do(Mark, Coord{x, y})
 	}
 }
+
+// ================================================================================
+
+/*
+ * Utilisation de l'algorithme BFS pour les déplacements. Beaucoup plus rapide que A*
+ *
+ *
+ */
+func findPathBFS(matrix [20][20]string, start, end Coord) []Coord {
+	queue := []Coord{start}
+	visited := make(map[Coord]bool)
+	parents := make(map[Coord]Coord)
+
+	for len(queue) > 0 {
+		current := queue[0]
+		queue = queue[1:]
+
+		if current == end {
+			// Construire le chemin à partir des parents
+			path := []Coord{current}
+			for parent, ok := parents[current]; ok; parent, ok = parents[parent] {
+				path = append([]Coord{parent}, path...)
+			}
+			return path[1:]
+		}
+
+		visited[current] = true
+
+		neighbors := getNeighborsBFS(matrix, current)
+		for _, neighbor := range neighbors {
+			if !visited[neighbor] {
+				parents[neighbor] = current
+				queue = append(queue, neighbor)
+			}
+		}
+	}
+
+	return nil // Aucun chemin trouvé
+}
+
+func getNeighborsBFS(matrix [20][20]string, current Coord) []Coord {
+	neighbors := make([]Coord, 0)
+
+	// Déplacements possibles : haut, bas, gauche, droite
+	possibleMoves := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
+
+	for _, move := range possibleMoves {
+		newRow, newCol := current[0]+move[0], current[1]+move[1]
+
+		// Vérifier si la nouvelle position est valide et non visitée
+		if newRow >= 0 && newRow < len(matrix) && newCol >= 0 && newCol < len(matrix[0]) && (matrix[newRow][newCol] == "_" || matrix[newRow][newCol] == "B") {
+			neighbors = append(neighbors, Coord{newRow, newCol})
+		}
+	}
+
+	return neighbors
+}
+
+/*
+type Node struct {
+	row, col, cost, heuristic int
+}
+
+type PriorityQueue []*Node
+
+func (pq PriorityQueue) Len() int { return len(pq) }
+
+func (pq PriorityQueue) Less(i, j int) bool {
+	return (pq[i].cost + pq[i].heuristic) < (pq[j].cost + pq[j].heuristic)
+}
+
+func (pq PriorityQueue) Swap(i, j int) {
+	pq[i], pq[j] = pq[j], pq[i]
+}
+
+func (pq *PriorityQueue) Push(x interface{}) {
+	item := x.(*Node)
+	*pq = append(*pq, item)
+}
+
+func (pq *PriorityQueue) Pop() interface{} {
+	old := *pq
+	n := len(old)
+	item := old[n-1]
+	*pq = old[0 : n-1]
+	return item
+}
+
+func findPath(matrix [20][20]string, start, end Node) []Node {
+	pq := make(PriorityQueue, 0)
+	heap.Init(&pq)
+
+	heap.Push(&pq, &start)
+	visited := make(map[Node]bool)
+	parents := make(map[Node]Node)
+
+	for pq.Len() > 0 {
+		current := heap.Pop(&pq).(*Node)
+
+		if current.row == end.row && current.col == end.col {
+			// Construire le chemin à partir des parents
+			path := []Node{*current}
+			for parent, ok := parents[*current]; ok; parent, ok = parents[parent] {
+				path = append([]Node{parent}, path...)
+			}
+
+			return path[1:]
+		}
+
+		visited[*current] = true
+
+		neighbors := getNeighbors(matrix, *current)
+		for _, neighbor := range neighbors {
+			if !visited[*neighbor] {
+				parents[*neighbor] = *current
+				heap.Push(&pq, neighbor)
+			}
+		}
+	}
+
+	return nil // Aucun chemin trouvé
+}
+
+func getNeighbors(matrix [20][20]string, current Node) []*Node {
+	neighbors := make([]*Node, 0)
+
+	// Déplacements possibles : haut, bas, gauche, droite
+	possibleMoves := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
+
+	for _, move := range possibleMoves {
+		newRow, newCol := current.row+move[0], current.col+move[1]
+
+		// Vérifier si la nouvelle position est valide et non visitée
+		if newRow >= 0 && newRow < len(matrix) && newCol >= 0 && newCol < len(matrix[0]) && (matrix[newRow][newCol] == "_" || matrix[newRow][newCol] == "B") {
+			neighbors = append(neighbors, &Node{newRow, newCol, current.cost + 1, heuristic(newRow, newCol, current, current)})
+		}
+	}
+
+	return neighbors
+}
+
+func heuristic(row, col int, current, end Node) int {
+	// Heuristique simple : distance de Manhattan
+	return abs(row-end.row) + abs(col-end.col)
+}
+
+func abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+*/
diff --git a/cmd/simu/main.go b/cmd/simu/main.go
index 1fd983b2d04a4f1c253b2b63b22f67602fbb597a..bac00185ea04403b2c5d9c54aaab9934eb55e5da 100644
--- a/cmd/simu/main.go
+++ b/cmd/simu/main.go
@@ -6,7 +6,7 @@ import (
 )
 
 func main() {
-	s := simulation.NewSimulation(100, -1, 600*time.Second)
+	s := simulation.NewSimulation(3, -1, 600*time.Second)
 	go simulation.StartAPI(s)
 	s.Run()
 }
diff --git a/env.go b/env.go
index 55950a82a2745b095a874336a5a4319d7b2bfad2..05fe4b1a5565ed980838b285385a1891b0cbdbba 100644
--- a/env.go
+++ b/env.go
@@ -5,17 +5,16 @@ import (
 	"sync"
 )
 
+
 type Environment struct {
 	sync.RWMutex
 	ags        []Agent
 	agentCount int
-	in         uint64
-	out        uint64
-	noopCount  uint64
+	station [20][20]string
 }
 
-func NewEnvironment(ags []Agent) (env *Environment) {
-	return &Environment{ags: ags, agentCount: len(ags)}
+func NewEnvironment(ags []Agent, carte [20][20]string) (env *Environment) {
+	return &Environment{ags: ags, agentCount: len(ags),station : carte}
 }
 
 func (env *Environment) AddAgent(agt Agent) {
@@ -33,15 +32,9 @@ func (env *Environment) Do(a Action, c Coord) (err error) {
 			return fmt.Errorf("bad coordinates (%f,%f)", c[0], c[1])
 		}
 
-		if c[0]*c[0]+c[1]*c[1] <= 1 {
-			env.in++
-		} else {
-			env.out++
-		}
 		return nil
 
 	case Noop:
-		env.noopCount++
 		return nil
 	}
 
@@ -52,9 +45,9 @@ func (env *Environment) PI() float64 {
 	env.RLock()
 	defer env.RUnlock()
 
-	return 4 * float64(env.in) / (float64(env.out) + float64(env.in))
+	return 4 
 }
 
-func (env *Environment) Rect() Rect {
-	return Rect{Coord{0, 0}, Coord{1, 1}}
+func (env *Environment) Rect() Coord {
+	return Coord{0, 0}
 }
diff --git a/simu.go b/simu.go
index d197e93e8c52163e38c24f5a8814a4979aefb839..6a4597576c15217fb1ff5f6962f41df8eba3249b 100644
--- a/simu.go
+++ b/simu.go
@@ -7,8 +7,40 @@ import (
 	"time"
 )
 
+// Déclaration de la matrice
+/*
+ * X : Mur, zone inatteignable
+ * E : Entrée
+ * S : Sortie
+ * W : Entrée et Sortie
+ * Q : Voie
+ * _ : Couloir, zon
+ * B: Bridge/Pont, zone accessible
+ */
+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", "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"},
+	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
+	{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
+	{"X", "X", "X", "X", "X", "X", "X", "X", "_", "_", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X"},
+	{"X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "X", "X", "X", "X"},
+	{"X", "X", "X", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "X", "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"},
+}
+
 type Simulation struct {
-	env         Environment // pb de copie avec les locks...
+	env         Environment
 	agents      []Agent
 	maxStep     int
 	maxDuration time.Duration
@@ -23,23 +55,23 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu
 	simu.maxStep = maxStep
 	simu.maxDuration = maxDuration
 
-	simu.env = *NewEnvironment([]Agent{})
+	simu.env = *NewEnvironment([]Agent{}, carte)
 
 	// création des agents et des channels
 	for i := 0; i < agentCount; i++ {
 		// création de l'agent
 		id := fmt.Sprintf("Agent #%d", i)
 		syncChan := make(chan int)
-		ag := NewAgentPI(id, &simu.env, syncChan)
-
+		ag := NewAgent(id, &simu.env, syncChan, 1, 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)})
+		fmt.Println(ag.id,ag.departure,ag.destination)
 		// ajout de l'agent à la simulation
-		simu.agents = append(simu.agents, ag)
+		simu.agents = append(simu.agents, *ag)
 
 		// ajout du channel de synchro
 		simu.syncChans.Store(ag.ID(), syncChan)
 
 		// ajout de l'agent à l'environnement
-		ag.env.AddAgent(ag)
+		ag.env.AddAgent(*ag)
 	}
 
 	return simu
@@ -54,13 +86,19 @@ func (simu *Simulation) Run() {
 	go simu.Print()
 
 	// Démarrage des agents
+	// Démarrage des agents
+	var wg sync.WaitGroup
 	for _, agt := range simu.agents {
-		agt.Start()
-	}
+		wg.Add(1)
+		go func(agent Agent) {
+			defer wg.Done()
+			agent.Start()
+		}(agt)
+}
 
 	// On sauvegarde la date du début de la simulation
 	simu.start = time.Now()
-
+	
 	// Lancement de l'orchestration de tous les agents
 	// simu.step += 1 // plus de sens
 	for _, agt := range simu.agents {
@@ -78,13 +116,17 @@ func (simu *Simulation) Run() {
 
 	time.Sleep(simu.maxDuration)
 
-	log.Printf("Fin de la simulation [step: %d, in: %d, out: %d, π: %f]", simu.step, simu.env.in, simu.env.out, simu.env.PI())
+	log.Printf("Fin de la simulation [step: %d, in: %d, out: %d, π: %f]", simu.step, simu.env.PI())
 }
 
 func (simu *Simulation) Print() {
 	for {
-		fmt.Printf("\rπ = %.30f", simu.env.PI())
-		time.Sleep(time.Second / 60) // 60 fps !
+		for i := 0; i < 20; i++ {
+			fmt.Println(simu.env.station[i])
+		}
+		//time.Sleep(time.Second / 60) // 60 fps !
+		time.Sleep(time.Second)    // 1 fps !
+		//fmt.Print("\033[H\033[2J") // effacement du terminal
 	}
 }