diff --git a/comptes-rendus/journal-de-bord/semaines/semaine2.md b/comptes-rendus/journal-de-bord/semaines/semaine2.md
index 5462c9a787dc05f10bb7ffb5826dd90fe0079fe1..61eb940c24e164e1f8ba4ed9321a2ee6a2eff673 100755
--- a/comptes-rendus/journal-de-bord/semaines/semaine2.md
+++ b/comptes-rendus/journal-de-bord/semaines/semaine2.md
@@ -18,12 +18,22 @@ Voici ici le descriptif du travail effectué lors de la journée du 23/05/2022.
 
 ### De 8h30 à 10h
 
+* Relecture article scientifique
+* Continuation implémentation comportement de l'article
+
 ### de 10h à 12h
 
+* Continuation implémentation comportement de l'article
+
 ### de 14h à 16h
 
+* Continuer lecture article donné par l'encadrant
+* Fin (pour l'instant) implémentation comportement de l'article (voir v3)
+
 ### de 16h à 18h
 
+* fin lecture article donné par l'encadrant
+
 
 <h2 id="mardi"> <strong> ✏️ Journal de Bord - Jour 7</strong> <a href="#menu">↩️</a> </h2>
 
diff --git a/src/Packages/v3.unitypackage b/src/Packages/v3.unitypackage
new file mode 100755
index 0000000000000000000000000000000000000000..db3bbbe6df8afe96a28209958aaa1d61e18fc260
Binary files /dev/null and b/src/Packages/v3.unitypackage differ
diff --git a/src/Scripts/Agent.cs b/src/Scripts/Agent.cs
index c7e8983d845fe04dbb2eff8df3e30e3da3d32ec1..83cc5e2bfb2c6ab4d17ff826ead15bc20719239a 100755
--- a/src/Scripts/Agent.cs
+++ b/src/Scripts/Agent.cs
@@ -11,10 +11,14 @@ public class Agent : MonoBehaviour, Visible
     private Comportement comportement;
     private Perception perception;
     public Vector3 direction;
-    public float speed;
-    public List<Vector3> oldDirections;
+    private float speed;
+    private List<Vector3> oldDirections;
     private int Taille_Memoire = 5;
 
+    private int angle = 180;
+
+    private static int count = 0;
+    public int id;
 
     // Start is called before the first frame update
     void Start()
@@ -23,7 +27,7 @@ public class Agent : MonoBehaviour, Visible
 
         //List<Comportement> comps = new List<Comportement> { new Reynolds(this), new Bord(this), new Aleatoire(this)};
         List<Comportement> comps = new List<Comportement> { new Paper(this), new Bord(this), new Aleatoire(this)};
-        List<int> imps = new List<int> { 5,8,1 };
+        List<int> imps = new List<int> { 5,5,2 };
         Comportement c =  new CompositeSeq(this,comps,imps);
 
         if(system._3D) comportement = c;
@@ -33,11 +37,18 @@ public class Agent : MonoBehaviour, Visible
         direction = Vector3.zero;
         speed = 0.7f;
         oldDirections = new List<Vector3>();
+
+        id = Agent.count;
+        Agent.count++;
     }
 
     // Update is called once per frame
     void Update()
     {   
+        if(angle != system.angle) {
+            angle = system.angle;
+            perception = new Perception(this,20.0f,(float) angle);
+        }
         reagir(voir());
         memoire();
     }
@@ -58,4 +69,33 @@ public class Agent : MonoBehaviour, Visible
 
     public bool isAlive() { return true; }
 
+    void OnTriggerEnter(Collider other) { 
+        direction = Vector3.zero;
+        //Debug.Log("enter trigger");
+    }
+
+    void OnTriggerExit(Collider other) { 
+        direction = Utils.meanVector(oldDirections); 
+        //Debug.Log("exit trigger");    
+    }
+
+    public override bool Equals(object obj)
+        {
+            // If the passed object is null
+            if (obj == null)
+            {
+                return false;
+            }
+            if (!(obj is Agent))
+            {
+                return false;
+            }
+            return (this.id == ((Agent) obj).id);
+        }
+
+    public override int GetHashCode()
+   {
+      return id;
+   }
+
 }
diff --git a/src/Scripts/Comportement/Bord.cs b/src/Scripts/Comportement/Bord.cs
index 98a3a6a1eadc01dab6d98ab18c6f35bd3729d73f..1a68f62112d0297246c6556e484608225e222297 100755
--- a/src/Scripts/Comportement/Bord.cs
+++ b/src/Scripts/Comportement/Bord.cs
@@ -7,8 +7,9 @@ public class Bord : Comportement
     static public float Urgent = 5.0f;
     static public float Preoccuppant  = 8.0f;
     static public float Intrigant = 10.0f;
+    private Vector3 currentGoal;
 
-    public Bord(Agent proprietaire) : base(proprietaire) {}
+    public Bord(Agent proprietaire) : base(proprietaire) { currentGoal = proprietaire.direction;}
 
     public override Vector3 reagir(List<Observation> observation) {
         List<Vector3> vectors = new List<Vector3>();
@@ -30,7 +31,9 @@ public class Bord : Comportement
             }
         }
         Vector3 res = Utils.meanVector(vectors);
-        return res;
+        //currentGoal = res;
+        return Utils.meanVector(new List<Vector3> {res,proprietaire.direction});
+        //return res;
         //return Utils.noiseVector(res,nbBruit,bruit);
     }
     
diff --git a/src/Scripts/Comportement/Paper.cs b/src/Scripts/Comportement/Paper.cs
index da1078f750714eac2fd8c6c55c7af8671665c306..2c76e86aaa8ad964db8d2a1330646285f76a710c 100755
--- a/src/Scripts/Comportement/Paper.cs
+++ b/src/Scripts/Comportement/Paper.cs
@@ -1,48 +1,188 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+using System;
 
 public class Paper : Comportement
 {
 
+    [Serializable]
+    public class Memory
+    {
+        public Agent agent;
+        public float idealDistance;
+        public float predictDistance;
+        public float predictAttempt;
+        public float stagnation;
+        public float exilation;
+
+        public Memory(Agent a, float ideal, float predict, float attempt) {
+            agent = a; idealDistance = ideal; predictDistance = predict; predictAttempt = attempt;
+            stagnation = stagnationTolerance; exilation = exileTolerance;
+        }
+    };
+
     private static List<Vector3> moves = new List<Vector3> 
     {
         (new Vector3(-1.0f,1.0f,0.0f)).normalized, (new Vector3(0.0f,1.0f,0.0f)).normalized, (new Vector3(1.0f,1.0f,0.0f)).normalized,
         (new Vector3(-1.0f,0.0f,0.0f)).normalized, (new Vector3(0.0f,0.0f,0.0f)).normalized, (new Vector3(1.0f,0.0f,0.0f)).normalized,
-        (new Vector3(-1.0f,-1.0f,0.0f)).normalized, (new Vector3(0.0f,-1.0f,0.0f)).normalized, (new Vector3(1.0f,-1.0f,0.0f)).normalized
+        (new Vector3(-1.0f,-1.0f,0.0f)).normalized, (new Vector3(0.0f,-1.0f,0.0f)).normalized, (new Vector3(1.0f,-1.0f,0.0f)).normalized,
+        (new Vector3(-1.0f,1.0f,-1.0f)).normalized, (new Vector3(0.0f,1.0f,-1.0f)).normalized, (new Vector3(1.0f,1.0f,-1.0f)).normalized,
+        (new Vector3(-1.0f,0.0f,-1.0f)).normalized, (new Vector3(0.0f,0.0f,-1.0f)).normalized, (new Vector3(1.0f,0.0f,-1.0f)).normalized,
+        (new Vector3(-1.0f,-1.0f,-1.0f)).normalized, (new Vector3(0.0f,-1.0f,-1.0f)).normalized, (new Vector3(1.0f,-1.0f,-1.0f)).normalized,
+        (new Vector3(-1.0f,1.0f,1.0f)).normalized, (new Vector3(0.0f,1.0f,1.0f)).normalized, (new Vector3(1.0f,1.0f,1.0f)).normalized,
+        (new Vector3(-1.0f,0.0f,1.0f)).normalized, (new Vector3(0.0f,0.0f,1.0f)).normalized, (new Vector3(1.0f,0.0f,1.0f)).normalized,
+        (new Vector3(-1.0f,-1.0f,1.0f)).normalized, (new Vector3(0.0f,-1.0f,1.0f)).normalized, (new Vector3(1.0f,-1.0f,1.0f)).normalized
     };
 
+    // Critical real distance at which the FSRs are activated
+    private static float activeSeuil = 8.0f;
+    // Change rate (0 < P_C < 1) for increasing and decreasing ideal distances, and stagnation and exile tolerance times
+    private static float changeRate = 0.2f;
+    // Initial value of the stagnation tolerance time
+    private static float stagnationTolerance = 15.0f;
+    // Initial value of the exile tolerance time
+    private static float exileTolerance = 30.0f;
+
+    private List<Memory> memories = new List<Memory>();
+
+
     public Paper(Agent proprietaire) : base(proprietaire) {
         
     }
 
     public override Vector3 reagir(List<Observation> observation) {
         
-        float disatifaction = 1.0f; Vector3 themove = Vector3.zero; float d;
+        List<Vector3> candidatesVectors = getTheMoves(observation);
+        Vector3 themove = getTheMove(candidatesVectors);
+        assumeTheMove(themove,observation);
+        return themove;
+    }
+
+    private List<Vector3> getTheMoves(List<Observation> observation) {
+        List<Vector3> candidatesVectors = new List<Vector3>();
+        float disatifaction = 1000.0f; float d;
         for(int i=0;i<moves.Count;i++) {
             d = computeDisatisfaction(moves[i],observation);
             if (d < disatifaction) {
-                themove = moves[i]; disatifaction = d;
+                candidatesVectors.Clear(); 
+                candidatesVectors.Add(moves[i]);
+                disatifaction = d;
+            }
+            else if (d == disatifaction) candidatesVectors.Add(moves[i]);
+        }
+        return candidatesVectors;
+    }
+    private Vector3 getTheMove(List<Vector3> candidatesVectors) {
+        Vector3 themove = proprietaire.direction;
+        float d = 1000.0f; float sum;
+        for(int i=0;i<candidatesVectors.Count;i++) {
+            sum = Utils.abs(proprietaire.direction.x - candidatesVectors[i].x);
+            sum += Utils.abs(proprietaire.direction.y - candidatesVectors[i].y);
+            sum += Utils.abs(proprietaire.direction.z - candidatesVectors[i].z);
+            if (sum < d) {
+                d = sum;
+                themove = candidatesVectors[i];
             }
         }
         return themove;
     }
 
+    private void assumeTheMove(Vector3 themove,List<Observation> observation) {
+        Vector3 futurPos = proprietaire.transform.position + themove;
+        List<Observation> agentObservations = observation.FindAll(isAgent);
+        Agent concerned; Vector3 reachPoint; float reachDist;
+        for(int i=0;i<agentObservations.Count;i++) {
+            concerned = (Agent) agentObservations[i].objet;
+            reachPoint = proprietaire.transform.position + agentObservations[i].distance;
+            reachDist = Utils.normVector( reachPoint - futurPos );
+            for(int j=0;j<memories.Count;j++) {
+                if(memories[j].agent == concerned) {
+                    memories[j].predictDistance = reachDist;
+                    memories[j].predictAttempt = reachDist - Utils.normVector(agentObservations[i].distance);
+                }
+            }
+        }
+    }
+
+    private bool isAgent(Observation o) {return o.objet.isAlive();}
+
     private float computeDisatisfaction(Vector3 move, List<Observation> observation) {
         float d = 0.0f; int nb = 0;
         float m = proprietaire.system.environnement.getMaxDistance();
         Vector3 possiblePos = proprietaire.transform.position + move;
+        Vector3 reachPoint;
+        float reachDist; Agent concerned; float dist;
         for(int i=0;i<observation.Count;i++) {
             if (observation[i].objet.isAlive()) {
-                d += Utils.abs(Utils.normVector(observation[i].distance) - idealDistance((Agent) observation[i].objet));
-                nb += 1;
+                dist = Utils.normVector(observation[i].distance);
+                if(dist <= activeSeuil) {
+                    concerned = (Agent) observation[i].objet;
+                    reachPoint = proprietaire.transform.position + observation[i].distance;
+                    reachDist = Utils.normVector( reachPoint - possiblePos );
+                    addAgentInMemory(concerned,dist,m,reachDist);
+                    d += Utils.abs( reachDist - idealDistance((Agent) observation[i].objet));
+                    nb += 1;
+                }
             }
         }
-        return d/(nb*m);
+        if (nb==0) return 1000.0f;
+        else return d/(nb*m);
+    }
+
+    private void addAgentInMemory(Agent concerned,float dist,float max, float reachDist) {
+        bool hasToBeAdd = true;
+        int i = 0;
+        while (i < memories.Count && hasToBeAdd) {
+            if(memories[i].agent == concerned) hasToBeAdd = false;
+            i++;
+        }
+        if(hasToBeAdd) {
+            Memory mem = new Memory(concerned,Utils.random(dist,max),reachDist,0.0f);
+            memories.Add(mem);
+        }
     }
 
     private float idealDistance(Agent other) {
-        return 50.0f;
+        int i = 0;
+        while(memories[i].agent != other) i++;
+        float dist = Utils.normVector(other.transform.position - proprietaire.transform.position);
+        float c = memories[i].predictAttempt;
+        float u = Utils.abs(dist - memories[i].idealDistance) - Utils.abs(memories[i].predictDistance - memories[i].idealDistance);
+        int k = 0;
+        if (u > 0) {
+            if (c < 0) k = 1;
+            else if (c > 0) k = -1;
+            else k = Utils.randomPosOrNeg(1);
+        }
+        else if(u < 0) {
+            if (c < 0) k = -1;
+            else if (c > 0) k = 1;
+            else k = Utils.randomPosOrNeg(1);
+        }
+        float ideal = (1 + k*changeRate) * memories[i].idealDistance;
+        memories[i].idealDistance = ideal;
+        return 5.0f;
+        //return ideal;
+        /*
+        if(Utils.abs(ideal - memories[i].idealDistance) < changeRate && memories[i].stagnation > 1) {
+            memories[i].stagnation -= 1;
+            if(memories[i].stagnation <= 1) {
+                ideal = memories[i].idealDistance + changeRate * stagnationTolerance;
+            }
+        }
+        else if(memories[i].exilation > 1 && memories[i].stagnation <= 1) {
+            memories[i].exilation -= 1;
+            //memories[i].stagnation *= 1 + changeRate;
+            if(memories[i].exilation == 1) {
+                ideal = memories[i].idealDistance - (changeRate * stagnationTolerance + activeSeuil);
+                memories[i].stagnation = stagnationTolerance * (1 + changeRate);
+                memories[i].exilation = exileTolerance * (1 - changeRate);
+            }
+        }
+        memories[i].idealDistance = ideal;
+        return ideal;
+        */
     }
     
 }
diff --git a/src/Scripts/SMA.cs b/src/Scripts/SMA.cs
index eb8ab6a42ecd33b7b63128a6815d53ca428a64c3..43679786129334e7c979b5796baa7513aa809acc 100755
--- a/src/Scripts/SMA.cs
+++ b/src/Scripts/SMA.cs
@@ -10,6 +10,7 @@ public class SMA : MonoBehaviour
     public GameObject boid;
     public bool _3D = true;
     private bool _old3D = true;
+    public int angle = 180;
 
 
     // Start is called before the first frame update
@@ -24,7 +25,6 @@ public class SMA : MonoBehaviour
     {
         if (_3D != _old3D) {
             _old3D = _3D;
-            agents.Clear();
             environnement.changeTo3D(_3D);
             createAgents();
         }
@@ -37,7 +37,7 @@ public class SMA : MonoBehaviour
     }
 
     void createAgents() {
-        GameObject a;
+        GameObject a;agents.Clear();
         for(int i=0; i<population; i++) {
             a = Instantiate(boid, environnement.validPosition(), Quaternion.identity,environnement.transform) as GameObject;
             agents.Add(a.GetComponent<Agent>());
diff --git a/src/Scripts/Utils.cs b/src/Scripts/Utils.cs
index 77195859b362b6c219dab8f8206f6b3d29db0d1a..30282261223519054f0b35e321ac16dec7bf0130 100755
--- a/src/Scripts/Utils.cs
+++ b/src/Scripts/Utils.cs
@@ -24,14 +24,14 @@ public class Utils
         float z = 0.0f;
         int r;
         for(int i = 0; i<10; i++) {
-            r = UnityEngine.Random.Range(0,3);
+            r = random(0,3);
             if (r == 0) x += 1.0f;
             else if (r == 1) y += 1.0f;
             else z += 1.0f;
         }
-        if(UnityEngine.Random.Range(1,3) > 1) x = -x;
-        if(UnityEngine.Random.Range(1,3) > 1) y = -y;
-        if(UnityEngine.Random.Range(1,3) > 1) z = -z;
+        if(random(1,3) > 1) x = -x;
+        if(random(1,3) > 1) y = -y;
+        if(random(1,3) > 1) z = -z;
 
         return normalizedVector(x,y,z);
     }
@@ -50,9 +50,9 @@ public class Utils
     }
 
     public static Vector3 randomVector(float minX, float maxX, float minY, float maxY, float minZ, float maxZ) {
-        return new Vector3(UnityEngine.Random.Range(minX,maxX),
-                            UnityEngine.Random.Range(minY,maxY),
-                            UnityEngine.Random.Range(minZ,maxZ));
+        return new Vector3(random(minX,maxX),
+                            random(minY,maxY),
+                            random(minZ,maxZ));
     }
 
     public static float normVector(Vector3 v) {
@@ -66,8 +66,8 @@ public class Utils
     public static Vector3 noiseVector(Vector3 v, int nbBruit, float bruit ) {
         int coin1; int coin2; float x = v.x; float y = v.y; float z = v.z;
         for(int i=0;i<nbBruit;i++) {
-            coin1 = UnityEngine.Random.Range(1,3);
-            coin2 = UnityEngine.Random.Range(1,4);
+            coin1 = random(1,3);
+            coin2 = random(1,4);
             if(coin2 == 1) {
                 if(coin1 == 1) x+=bruit;
                 else x-= bruit;
@@ -86,4 +86,10 @@ public class Utils
 
     public static float abs(float n) {return (float) Math.Sqrt(Math.Pow(n,2));}
 
+    public static float random(float min, float max) {return UnityEngine.Random.Range(min,max);} 
+    public static int random(int min, int max) {return UnityEngine.Random.Range(min,max);}
+
+    public static float randomPosOrNeg(float n) { return n * ((float) Math.Pow(-1,random(0,2)));  }
+    public static int randomPosOrNeg(int n) { return n * ((int) Math.Pow(-1,random(0,2)));  }
+
 }