diff --git a/cmd/simu/main.go b/cmd/simu/main.go
index f7d520dfa8148306eaee88f31c1b470d6c80ee3b..c29a1f66f5a6b3a3bf7c3dee0a49389e68be6697 100644
--- a/cmd/simu/main.go
+++ b/cmd/simu/main.go
@@ -6,7 +6,7 @@ import (
 )
 
 func main() {
-	s := simulation.NewSimulation(40, -1, 600*time.Second)
+	s := simulation.NewSimulation(1, -1, 600*time.Second)
 	//go simulation.StartAPI(s)
 	s.Run()
 }
diff --git a/internal/algorithms/astar.go b/internal/algorithms/astar.go
index 41e1f306dfbd9b83241179d0869468cbcbf978e3..f19a1eeda0e0c734f8f49afcfe22e0b6819ba3ce 100644
--- a/internal/algorithms/astar.go
+++ b/internal/algorithms/astar.go
@@ -2,19 +2,21 @@ package algorithms
 
 import (
 	"container/heap"
+	"fmt"
 )
 
 /*
  * Utilisation de l'algorithme A* pour les déplacements
  * //TODO: Peut-être gérer un passage par référence et non par copie
- * //TODO: Prise en compte des dimensions des agents
+ * 
  */
 type Node struct {
-	row, col, cost, heuristic int
+	row, col, cost, heuristic, width, height, orientation int
 }
 
-func NewNode(row, col, cost, heuristic int) *Node {
-	return &Node{row, col, cost, heuristic}
+func NewNode(row, col, cost, heuristic, width, height int) *Node {
+	//fmt.Println()
+	return &Node{row, col, cost, heuristic, width , height, 0}
 }
 
 func (nd *Node) Row() int {
@@ -107,18 +109,27 @@ func FindPath(matrix [20][20]string, start, end Node, forbidenCell Node) []Node
 	return nil // Aucun chemin trouvé
 }
 
-func getNeighbors(matrix [20][20]string, current, end Node, forbidenCell Node) []*Node {
+func getNeighbors(matrix [20][20]string, current, end Node, forbiddenCell Node) []*Node {
+	fmt.Println("okkk")
 	neighbors := make([]*Node, 0)
 
-	// Déplacements possibles : haut, bas, gauche, droite
+	// Possible moves: up, down, left, right, rotate (clockwise)
 	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
-		if (forbidenCell.row != newRow || forbidenCell.col != newCol) && newRow >= 0 && newRow < len(matrix) && newCol >= 0 && newCol < len(matrix[0]) && (matrix[newRow][newCol] != "Q" && matrix[newRow][newCol] != "X") {
-			neighbors = append(neighbors, &Node{newRow, newCol, current.cost + 1, heuristic(newRow, newCol, end)})
+		// Check if the new position is valid, considering agent dimensions and rotation
+		if isValidMove(matrix, current, forbiddenCell, newRow, newCol) {
+			neighbors = append(neighbors, &Node{
+				row:         newRow,
+				col:         newCol,
+				cost:        current.cost + 1,
+				heuristic:   heuristic(newRow, newCol, end),
+				width:       current.width,
+				height:      current.height,
+				orientation: current.orientation,
+			})
 		}
 	}
 
@@ -136,3 +147,61 @@ func abs(x int) int {
 	}
 	return x
 }
+
+func isValidMove(matrix [20][20]string, current Node, forbiddenCell Node, newRow, newCol int) 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
+	}
+
+	// Check if the new position overlaps with forbidden cells or obstacles
+	if forbiddenCell.row == newRow && forbiddenCell.col == newCol {
+		return false
+	}
+
+	// Check if the agent fits in the new position, considering its dimensions and rotation
+	for i := 0; i < current.height; i++ {
+		for j := 0; j < current.width; j++ {
+			// Calculate the rotated coordinates based on the agent's orientation
+			rotatedI, rotatedJ := rotateCoordinates(i, j, current.orientation)
+
+			// Calculate the absolute coordinates in the matrix
+			absRow, absCol := newRow+rotatedI, newCol+rotatedJ
+
+			// Check if the absolute coordinates are within the bounds of the matrix
+			if absRow < 0 || absRow >= len(matrix) || absCol < 0 || absCol >= len(matrix[0]) {
+				return false
+			}
+
+			// Check if the absolute coordinates overlap with forbidden cells or obstacles
+			if forbiddenCell.row == absRow && forbiddenCell.col == absCol {
+				return false
+			}
+
+			// Check if the absolute coordinates overlap with obstacles in the matrix
+			if matrix[absRow][absCol] == "Q" || matrix[absRow][absCol] == "X" {
+				return false
+			}
+		}
+	}
+
+	return true
+}
+
+func rotateCoordinates(i, j, orientation int) (rotatedI, rotatedJ int) {
+	// Rotate the coordinates based on the agent's orientation
+	// You need to implement the logic for rotation based on your specific rules
+	// This is a simple example that assumes the agent can rotate in all directions
+	switch orientation {
+	case 0: // No rotation
+		rotatedI, rotatedJ = i, j
+	case 1: // 90-degree rotation
+		rotatedI, rotatedJ = j, -i
+	case 2: // 180-degree rotation
+		rotatedI, rotatedJ = -i, -j
+	case 3: // 270-degree rotation
+		rotatedI, rotatedJ = -j, i
+	}
+
+	return rotatedI, rotatedJ
+}
diff --git a/internal/simulation/agent.go b/internal/simulation/agent.go
index c0c4040ba10bb3cb073f4b350cb26b48a350ac74..4a08dd08f66998ac2ea367147ea63a5adca312f4 100644
--- a/internal/simulation/agent.go
+++ b/internal/simulation/agent.go
@@ -1,9 +1,19 @@
 package simulation
 
+/*
+ * Classe et méthodes principales de la structure Agent
+ * à faire :
+ *			//TODO: gérer les orientations
+ *			// 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"
+	"fmt"
 	"log"
 	"math/rand"
 	alg "metrosim/internal/algorithms"
@@ -23,20 +33,21 @@ type Coord [2]int
 type AgentID string
 
 type Agent struct {
-	id                  AgentID
-	vitesse             time.Duration
-	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
-	stuck               bool
+	id          AgentID
+	vitesse     time.Duration
+	force       int
+	politesse   bool
+	position    Coord // Coordonnées de référence, width et height on compte width et height à partir de cette position
+	departure   Coord
+	destination Coord
+	behavior    Behavior
+	env         *Environment
+	syncChan    chan int
+	decision    int
+	isOn        map[Coord]string // Contenu de la case sur laquelle il se trouve
+	stuck       bool
+	width       int
+	height      int
 }
 
 type Behavior interface {
@@ -45,9 +56,10 @@ type Behavior interface {
 	Act(*Agent)
 }
 
-
-func NewAgent(id string, env *Environment, syncChan chan int, vitesse time.Duration, 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]], false}
+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)
+	return &Agent{AgentID(id), vitesse, force, politesse, departure, departure, destination, behavior, env, syncChan, Noop, isOn, false, width, height}
 }
 
 func (ag *Agent) ID() AgentID {
@@ -75,66 +87,151 @@ func (ag *Agent) Act(env *Environment) {
 	}
 }
 
-func IsMovementSafe(path []alg.Node, env *Environment) bool {
+func IsMovementSafe(path []alg.Node, ag *Agent, env *Environment) bool {
 	// Détermine si le movement est faisable
-	return len(path) > 0 && (env.station[path[0].Row()][path[0].Col()] == "B" || env.station[path[0].Row()][path[0].Col()] == "_")
+	if len(path) <= 0 {
+		return false
+	}
+	startX, startY := ag.position[1], ag.position[0]
+	width, height := ag.width, ag.height
+
+	// on simule son nouvel emplacement
+	// et regarde s'il chevauche un autre agent
+	for i := path[0].Row(); i < path[0].Row()+ag.height; i++ {
+		for j := path[0].Col(); j < path[0].Col()+ag.width; j++ {
+
+			if !(j >= startX && j < startX+width && i >= startY && i < startY+height) && (env.station[i][j] != "B" && env.station[i][j] != "_") {
+				// Si on est sur une case non atteignable, en dehors de la zone qu'occupe l'agent avant déplacement, on est bloqué
+				return false
+			}
+		}
+	}
+	return true
 }
 
-func IsAgentBlocking(path []alg.Node, env *Environment) bool {
+func IsAgentBlocking(path []alg.Node, ag *Agent, env *Environment) bool {
 	// Détermine si un agent se trouve sur la case à visiter
-	return len(path) > 0 && env.station[path[0].Row()][path[0].Col()] == "A"
+	// Coordonnée de départ et dimensions du rectangle
+	if len(path) <= 0 {
+		return false
+	}
+	startX, startY := ag.position[1], ag.position[0]
+	width, height := ag.width, ag.height
+
+	// on simule son nouvel emplacement
+	// et regarde s'il chevauche un autre agent
+	for i := path[0].Row(); i < path[0].Row()+ag.height; i++ {
+		for j := path[0].Col(); j < path[0].Col()+ag.width; j++ {
+
+			if !(j >= startX && j < startX+width && i >= startY && i < startY+height) && env.station[i][j] == "A" {
+				// Si on est sur un agent, en dehors de la zone qu'occupe l'agent avant déplacement, on est bloqué
+				return true
+			}
+		}
+	}
+
+	return false
 }
 
 func (ag *Agent) isStuck() bool {
 	// Perception des éléments autour de l'agent pour déterminer si bloqué
-	s := 0 // nombre de cases indisponibles autour de l'agent
-	for i := 0; i < 3; i++ {
-		for j := 0; j < 3; j++ {
-			ord := (ag.coordBasOccupation[0] - 1) + i
-			abs := (ag.coordBasOccupation[1] - 1) + j
-
-			if ord != ag.coordBasOccupation[0] && abs != ag.coordBasOccupation[1] {
-				if ord < 0 || abs < 0 || ord > 19 || abs > 19 {
-					s++
-				} else if ag.env.station[ord][abs] == "X" || ag.env.station[ord][abs] == "Q" || ag.env.station[ord][abs] == "A" {
-					s++
-				}
+	not_acc := 0 // nombre de cases indisponibles autour de l'agent
+
+	// Coordonnée de départ et dimensions du rectangle
+	startX, startY := ag.position[1], ag.position[0]
+	width, height := ag.width, ag.height
+
+	// Largeur et hauteur du rectangle étendu
+	extendedWidth := width + 2   // +2 pour les cases à gauche et à droite du rectangle
+	extendedHeight := height + 2 // +2 pour les cases au-dessus et en dessous du rectangle
+
+	count := 0
+	// Parcourir les cases autour du rectangle
+	for i := startX - 1; i < startX+extendedWidth-1; i++ {
+		for j := startY - 1; j < startY+extendedHeight-1; j++ {
+			// Éviter les cases à l'intérieur du rectangle
+			if i >= startX && i < startX+width && j >= startY && j < startY+height {
+
+				continue
+			} else {
+				count++
+			}
+			// Case inaccessible
+			if ag.env.station[j][i] == "X" || ag.env.station[j][i] == "Q" || ag.env.station[j][i] == "A" {
+				not_acc++
+
 			}
+			// fmt.Printf("Border (%d, %d) = %s \n", j, i,ag.env.station[j][i])
 		}
 	}
 	// Si aucune case disponible autour de lui, il est bloqué
-	return s == 8
+	return not_acc == count
 }
 
 func (ag *Agent) MoveAgent() {
-	// TODO: Gérer les moments où les agents font du quasi-sur place car il ne peuvent plus bouger
-	// TODO: Parfois, certains agents ne bougent plus,
-	// 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
 
 	// ============ Initialisation des noeuds de départ ======================
-	start := *alg.NewNode(ag.coordBasOccupation[0], ag.coordBasOccupation[1], 0, 0)
-	end := *alg.NewNode(ag.destination[0], ag.destination[1], 0, 0)
-
+	start := *alg.NewNode(ag.position[0], ag.position[1], 0, 0, ag.width, ag.height)
+	end := *alg.NewNode(ag.destination[0], ag.destination[1], 0, 0, ag.width, ag.height)
 	// ================== Tentative de calcul du chemin =======================
-	path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1,-1,0,0))
-	
+	path := alg.FindPath(ag.env.station, start, end, *alg.NewNode(-1, -1, 0, 0, 0, 0))
 	// ================== Etude de faisabilité =======================
-	if IsAgentBlocking(path, ag.env) {
+	fmt.Println(path)
+	if IsAgentBlocking(path, ag, ag.env) {
 		// Si un agent bloque notre déplacement, on attend un temps aléatoire, et reconstruit un chemin en évitant la position
 		time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
 		path = alg.FindPath(ag.env.station, start, end, path[0])
 		time.Sleep(time.Second)
 	}
-
-	if IsMovementSafe(path, ag.env) {
-		ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = ag.isOn
-		ag.isOn = ag.env.station[path[0].Row()][path[0].Col()]
-		ag.coordBasOccupation[0] = path[0].Row()
-		ag.coordBasOccupation[1] = path[0].Col()
-		ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = "A"
+	if IsMovementSafe(path, ag, ag.env) {
+		removeAgent(&ag.env.station, ag)
+		//ag.env.station[ag.coordBasOccupation[0]][ag.coordBasOccupation[1]] = ag.isOn
+		ag.position[0] = path[0].Row()
+		ag.position[1] = path[0].Col()
+		saveCells(&ag.env.station, ag.isOn, ag.position, ag.width, ag.height)
+		//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.Sleep(ag.vitesse * time.Millisecond)
+		//fmt.Println(path[0])
+		//fmt.Println(ag.position)
+	}
+
+}
+
+func removeAgent(matrix *[20][20]string, agt *Agent) {
+	// Supprime l'agent de la matrice
+	for i := agt.position[0]; i < agt.position[0]+agt.height; i++ {
+		for j := agt.position[1]; j < agt.position[1]+agt.width; j++ {
+			matrix[i][j] = agt.isOn[Coord{i, j}]
+			removeCoord(Coord{i, j}, agt.isOn)
+		}
+	}
+}
+
+func writeAgent(matrix *[20][20]string, agt *Agent) {
+	// Ecris un agent dans la matrice
+	for i := agt.position[0]; i < agt.position[0]+agt.height; i++ {
+		for j := agt.position[1]; j < agt.position[1]+agt.width; j++ {
+			matrix[i][j] = "A"
+		}
 	}
+}
 
+func saveCells(matrix *[20][20]string, savedCells map[Coord]string, ref Coord, width, height int) {
+	// Enregistrement des valeurs des cellules de la matrice
+	for i := ref[0]; i < ref[0]+height; i++ {
+		for j := ref[1]; j < ref[1]+width; j++ {
+			savedCells[Coord{i, j}] = matrix[i][j]
+		}
+	}
+}
+
+func removeCoord(to_remove Coord, mapping map[Coord]string) {
+	// Suppression d'une clé dans une map
+	for coord, _ := range mapping {
+		if coord[0] == to_remove[0] && coord[1] == to_remove[1] {
+			delete(mapping, coord)
+		}
+	}
 }
diff --git a/internal/simulation/simu.go b/internal/simulation/simu.go
index cfd487963669f6501d884d20380cd73b067cb27e..e67858293bb2290a61d5cf04d848f174b233ac42 100644
--- a/internal/simulation/simu.go
+++ b/internal/simulation/simu.go
@@ -97,7 +97,8 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu
 		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, 1, 0, true, Coord{4, 10}, Coord{4, 10}, &UsagerLambda{}, Coord{4, 10}, Coord{0, 0})
+		//ag := NewAgent(id, &simu.env, syncChan, 1000, 0, true, &UsagerLambda{}, Coord{5, 8}, Coord{7, 15}, 2, 1)
+		ag := NewAgent(id, &simu.env, syncChan, 1000, 0, true, &UsagerLambda{}, Coord{5, 8}, Coord{0, 0}, 2, 1)
 
 		// ajout de l'agent à la simulation
 		simu.agents = append(simu.agents, *ag)
diff --git a/internal/simulation/usagerLambda.go b/internal/simulation/usagerLambda.go
index 1f977f18c14bf8f2708fc52e447086145261f472..843be3742b32ab72bbfaef92a5696af2d4cb08ec 100644
--- a/internal/simulation/usagerLambda.go
+++ b/internal/simulation/usagerLambda.go
@@ -1,6 +1,6 @@
 package simulation
 
-import(
+import (
 	"math/rand"
 	"time"
 )
@@ -11,6 +11,7 @@ func (ul *UsagerLambda) Percept(ag *Agent) {
 	ag.stuck = ag.isStuck()
 	if ag.stuck {
 		return
+
 	}
 
 }
@@ -31,4 +32,4 @@ func (ul *UsagerLambda) Act(ag *Agent) {
 		time.Sleep(time.Duration(n) * time.Second)
 	}
 
-}
\ No newline at end of file
+}