diff --git a/internal/simulation/agent.go b/internal/simulation/agent.go index 1e65e1a53a7d6f5823a690e1c2e7b9b586f69a07..a5818ba7f080ea9c0326bf252bb6fc13ad090dec 100644 --- a/internal/simulation/agent.go +++ b/internal/simulation/agent.go @@ -7,6 +7,7 @@ package simulation import ( "fmt" "log" + //"fmt" //"log" @@ -20,16 +21,16 @@ type Action int64 const ( Noop = iota //No opération, utiliser pour refuser un mouvement - Wait // Attente - Move // Déplacement de l'agent - EnterMetro //Entrer dans le métro + Wait // Attente + Move // Déplacement de l'agent + EnterMetro //Entrer dans le métro TryToMove YouHaveToMove //Utiliser par un usager impoli pour forcer un déplacement Done - Disappear // Disparition de l'agent dans la simulation - Expel // virer l'agent - Stop // arreter l'agent - ACK // acquittement + Disappear // Disparition de l'agent dans la simulation + Expel // virer l'agent + Stop // arreter l'agent + ACK // acquittement ) type AgentID string @@ -61,9 +62,9 @@ type Behavior interface { Percept(*Agent) Deliberate(*Agent) Act(*Agent) + SetUpAleaDestination(ag *Agent) } - func NewAgent(id string, env *Environment, syncChan chan int, vitesse time.Duration, force int, politesse bool, behavior Behavior, departure, destination alg.Coord, width, height int) *Agent { isOn := make(map[alg.Coord]string) direct := initDirection(departure, len(env.station[0])) @@ -75,16 +76,16 @@ func (ag *Agent) ID() AgentID { } func (ag *Agent) Start() { - + log.Printf("%s starting...\n", ag.id) go ag.listenForRequests() - + // si c'est un controlleur on lance le timer de durée de vie - if (ag.id[0] == 'C') { + if ag.id[0] == 'C' { fmt.Println("[Start()] C'est un controleur") ag.behavior.(*Controleur).startTimer() } - + go func() { var step int for { @@ -102,8 +103,6 @@ func (ag *Agent) Start() { }() } - - func (agt *Agent) IsMovementSafe() (bool, int) { // Détermine si le movement est faisable @@ -140,7 +139,7 @@ func (agt *Agent) IsMovementSafe() (bool, int) { safe = false } } - if !(j >= infCol && j < supCol && i >= infRow && i < supRow) && (agt.env.station[i][j] != "B" && agt.env.station[i][j] != "_" && agt.env.station[i][j] != "W" && agt.env.station[i][j] != "S" ) { + if !(j >= infCol && j < supCol && i >= infRow && i < supRow) && (agt.env.station[i][j] != "B" && agt.env.station[i][j] != "_" && agt.env.station[i][j] != "W" && agt.env.station[i][j] != "S") { // 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 @@ -234,10 +233,10 @@ func (ag *Agent) NextCell() string { } case 2: // vers le bas if ag.position[0]+1 >= 0 && ag.position[0]+1 < len(ag.env.station[0]) { - return ag.env.station[ag.position[0]+1][ag.position[1]] + return ag.env.station[ag.position[0]+1][ag.position[1]] } default: //vers la gauche - if ag.position[1]-1 >= 0 && ag.position[1]-1 < len(ag.env.station[1]){ + if ag.position[1]-1 >= 0 && ag.position[1]-1 < len(ag.env.station[1]) { return ag.env.station[ag.position[0]][ag.position[1]-1] } } @@ -247,9 +246,9 @@ func (ag *Agent) NextCell() string { func (ag *Agent) MoveAgent() bool { //fmt.Printf("[MoveAgent, %s ] direction = %d \n",ag.id, ag.direction) // ================== Tentative de calcul du chemin ======================= - if len(ag.path) == 0 || - ag.isGoingToExitPath() || - (ag.env.station[ag.path[0].Row()][ag.path[0].Col()]=="O" && !alg.EqualCoord(&ag.destination,&alg.Coord{ag.path[0].Row(),ag.path[0].Col()})) { + if len(ag.path) == 0 || + ag.isGoingToExitPath() || + (ag.env.station[ag.path[0].Row()][ag.path[0].Col()] == "O" && !alg.EqualCoord(&ag.destination, &alg.Coord{ag.path[0].Row(), ag.path[0].Col()})) { start, end := ag.generatePathExtremities() // Recherche d'un chemin si inexistant if len(ag.path) > 0 { @@ -273,7 +272,7 @@ func (ag *Agent) MoveAgent() bool { } else { //Si individu impoli, demande à l'agent devant de bouger //On récupère le id de la personne devant - if (existAgent(ag.NextCell())) { + if existAgent(ag.NextCell()) { blockingAgentID := AgentID(ag.NextCell()) //blockingAgent := ag.env.FindAgentByID(blockingAgentID) var reqToBlockingAgent *req.Request @@ -283,10 +282,10 @@ func (ag *Agent) MoveAgent() bool { 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 - fmt.Printf("[MoveAgent, %s] You have to move %s for the %d time \n",ag.id, blockingAgentID, i) + fmt.Printf("[MoveAgent, %s] You have to move %s for the %d time \n", ag.id, blockingAgentID, i) reqToBlockingAgent = req.NewRequest(ag.env.agentsChan[ag.id], YouHaveToMove) //Création "Hello, je suis ag.id, move." - ag.env.agentsChan[blockingAgentID] <- *reqToBlockingAgent //Envoi requête - repFromBlockingAgent := <-ag.env.agentsChan[ag.id] //Attend la réponse + ag.env.agentsChan[blockingAgentID] <- *reqToBlockingAgent //Envoi requête + repFromBlockingAgent := <-ag.env.agentsChan[ag.id] //Attend la réponse if repFromBlockingAgent.Decision() == Done { //BlockingAgent lui a répondu Done, il s'est donc poussé fmt.Printf("okay i will move agent %s \n", ag.id) @@ -298,7 +297,7 @@ func (ag *Agent) MoveAgent() bool { return false //il ne peut pas bouger, il s'arrête } } - + } } @@ -353,16 +352,13 @@ func (ag *Agent) listenForRequests() { fmt.Println("[listenForRequests] Request received by :", ag.id, req.Decision) ag.request = &req } - + if ag.request.Decision() == Disappear || ag.request.Decision() == EnterMetro { return } } } - - - func (ag *Agent) isGoingToExitPath() bool { if len(ag.path) > 0 { for _, metro := range ag.env.metros { @@ -382,76 +378,74 @@ func (ag *Agent) isGoingToExitPath() bool { return false } - /* - * Méthode qui envoie la valeur de case en face de l'agent -*/ -func (ag * Agent) getFaceCase() string{ + * Méthode qui envoie la valeur de case en face de l'agent + */ +func (ag *Agent) getFaceCase() string { switch { - case ag.direction == 0: // vers le haut - if (ag.position[0] - 1) < 0 { + case ag.direction == 0: // vers le haut + if (ag.position[0] - 1) < 0 { return "X" // si le controleur est au bord de la station, alors il fait face à un mur - } else { + } else { return ag.env.station[ag.position[0]-1][ag.position[1]] - } - case ag.direction == 1: // vers la droite - if (ag.position[1] + 1) > 50 { - return "X" // si le controleur est au bord de la station, alors il fait face à un mur - } else { - return ag.env.station[ag.position[0]][ag.position[1]+1] - } - case ag.direction == 2: // vers le bas - if (ag.position[0] + 1) > 50 { - return "X" // si le controleur est au bord de la station, alors il fait face à un mur - } else { - return ag.env.station[ag.position[0]+1][ag.position[1]] - } - - case ag.direction == 3: // vers la gauche - if (ag.position[1] - 1) < 0 { - return "X" // si le controleur est au bord de la station, alors il fait face à un mur - } else { - return ag.env.station[ag.position[0]][ag.position[1]-1] - } + } + case ag.direction == 1: // vers la droite + if (ag.position[1] + 1) > 50 { + return "X" // si le controleur est au bord de la station, alors il fait face à un mur + } else { + return ag.env.station[ag.position[0]][ag.position[1]+1] + } + case ag.direction == 2: // vers le bas + if (ag.position[0] + 1) > 50 { + return "X" // si le controleur est au bord de la station, alors il fait face à un mur + } else { + return ag.env.station[ag.position[0]+1][ag.position[1]] + } + + case ag.direction == 3: // vers la gauche + if (ag.position[1] - 1) < 0 { + return "X" // si le controleur est au bord de la station, alors il fait face à un mur + } else { + return ag.env.station[ag.position[0]][ag.position[1]-1] + } } return "X" } - func initDirection(depart alg.Coord, dimensionCarte int) int { n := rand.Intn(4) // direction aléatoire - for !verifyDirection(n,depart, dimensionCarte){ + for !verifyDirection(n, depart, dimensionCarte) { n = rand.Intn(4) // direction aléatoire } return n } -func verifyDirection( n int ,depart alg.Coord, dimensionCarte int) bool{ +func verifyDirection(n int, depart alg.Coord, dimensionCarte int) bool { switch n { - case 0: // vers le haut - if (depart[0] - 1) < 0 { - return false - }else { - return true - } - case 1: // vers la droite - if (depart[1] + 1) > dimensionCarte { - return false - }else { - return true - } - case 2: // vers le bas - if (depart[0] + 1) > dimensionCarte{ - return false - }else { - return true - } - case 3: // vers la gauche - if (depart[1] - 1) < 0 { - return false - }else { - return true - } + case 0: // vers le haut + if (depart[0] - 1) < 0 { + return false + } else { + return true + } + case 1: // vers la droite + if (depart[1] + 1) > dimensionCarte { + return false + } else { + return true + } + case 2: // vers le bas + if (depart[0] + 1) > dimensionCarte { + return false + } else { + return true + } + case 3: // vers la gauche + if (depart[1] - 1) < 0 { + return false + } else { + return true + } } return false } @@ -460,20 +454,18 @@ func verifyDirection( n int ,depart alg.Coord, dimensionCarte int) bool{ // Structure pour associer une Coord et sa distance par rapport au position d'un agent type Gate struct { - Position alg.Coord // Coordonnées de la porte + Position alg.Coord // Coordonnées de la porte Distance float64 NbAgents float64 } - - -func (ag *Agent) findNearestExit() (alg.Coord){ +func (ag *Agent) findNearestExit() alg.Coord { // Recherche de la sortie la plus proche nearest := alg.Coord{0, 0} min := 1000000 n := len(ag.env.station[0]) - for i := 0; i < n ; i++ { - for j := 0; j < n ; j++ { + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { if ag.env.station[i][j] == "S" || ag.env.station[i][j] == "W" { dist := alg.Abs(ag.position[0]-i) + alg.Abs(ag.position[1]-j) if dist < min { @@ -486,9 +478,6 @@ func (ag *Agent) findNearestExit() (alg.Coord){ return nearest } - - - func findMetro(env *Environment, gateToFind *alg.Coord) *Metro { for _, metro := range env.metros { for _, gate := range metro.way.gates { @@ -530,4 +519,4 @@ func (env *Environment) GetAgentByChannel(channel chan req.Request) *Agent { } // Aucune direction n'est sûre, il ne bouge pas return false -} */ \ No newline at end of file +} */ diff --git a/internal/simulation/controleur.go b/internal/simulation/controleur.go index 06c5ce5dec003e93f6ef585d314d6d9dd7681b32..376dbfd6536e781347296183378c3f3e30cae44a 100644 --- a/internal/simulation/controleur.go +++ b/internal/simulation/controleur.go @@ -9,33 +9,33 @@ package simulation import ( "fmt" "math/rand" + alg "metrosim/internal/algorithms" req "metrosim/internal/request" "regexp" "time" - alg "metrosim/internal/algorithms" ) type Controleur struct { - req *req.Request // requete reçue par le controleur - faceCase string // chaine de caractère qui contient l'id de l'agent qui se trouve devant le controleur, exemple : "Agent1", "Fraudeur1", "X" ,etc. - timer *time.Timer // timer qui permet de définir la durée de vie du controleur - isExpired bool // true si le controleur est expiré, false sinon + req *req.Request // requete reçue par le controleur + faceCase string // chaine de caractère qui contient l'id de l'agent qui se trouve devant le controleur, exemple : "Agent1", "Fraudeur1", "X" ,etc. + timer *time.Timer // timer qui permet de définir la durée de vie du controleur + isExpired bool // true si le controleur est expiré, false sinon } func (c *Controleur) Percept(ag *Agent) { //initialiser le faceCase en fonction de la direction de l'agent c.faceCase = ag.getFaceCase() switch { - // comportement par défaut (comportement agent Lambda) - case ag.request != nil: //verifier si l'agent est communiqué par un autre agent - //print("Requete recue par l'agent lambda : ", ag.request.decision, "\n") - c.req = ag.request - default: - ag.stuck = ag.isStuck() - if ag.stuck { - return - - } + // comportement par défaut (comportement agent Lambda) + case ag.request != nil: //verifier si l'agent est communiqué par un autre agent + //print("Requete recue par l'agent lambda : ", ag.request.decision, "\n") + c.req = ag.request + default: + ag.stuck = ag.isStuck() + if ag.stuck { + return + + } } } @@ -45,39 +45,39 @@ func (c *Controleur) Deliberate(ag *Agent) { regexCont := `^Cont\d+$` // \d+ correspond à un ou plusieurs chiffres regexFraudeur := `^Fraudeur\d+$` - existAgt := existAgent(c.faceCase) // true si l'agent existe dans la case en face , false sinon + existAgt := existAgent(c.faceCase) // true si l'agent existe dans la case en face , false sinon // Vérifier si la valeur de faceCase ne correspond pas au motif matchedCont, err1 := regexp.MatchString(regexCont, c.faceCase) matchedFraud, err := regexp.MatchString(regexFraudeur, c.faceCase) //fmt.Println("faceCase : ", c.faceCase) //fmt.Println("matchedAgt : ", matchedAgt) - if err!= nil { - fmt.Println("Erreur lors de l'analyse de la regex :",err) + if err != nil { + fmt.Println("Erreur lors de l'analyse de la regex :", err) return - } - if err1!= nil { - fmt.Println("Erreur lors de l'analyse de la regex :",err1) + } + if err1 != nil { + fmt.Println("Erreur lors de l'analyse de la regex :", err1) return - }else { - if matchedCont{ + } else { + if matchedCont { // si l'agent devant le controleur est un autre controleur alors il faut attendre qu'il se déplace - ag.decision = Move + ag.decision = Move return } if matchedFraud && !ag.env.controlledAgents[AgentID(c.faceCase)] { ag.decision = Expel // virer l'agent devant lui - }else if existAgt && !ag.env.controlledAgents[AgentID(c.faceCase)] { // si l'agent devant le controleur est un agent et qu'il n'a pas encore été controlé + } else if existAgt && !ag.env.controlledAgents[AgentID(c.faceCase)] { // 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 - }else if ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") { // si le controleur est arrivé à sa destination et qu'il est sur une sortie - //fmt.Println(ag.id, "disappear") - ag.decision = Disappear - } else if ag.stuck{ // si le controleur est bloqué - ag.decision = Wait - }else { - ag.decision = Move - } + ag.decision = Stop // arreter l'agent + } else if ag.position == ag.destination && (ag.isOn[ag.position] == "W" || ag.isOn[ag.position] == "S") { // si le controleur est arrivé à sa destination et qu'il est sur une sortie + //fmt.Println(ag.id, "disappear") + ag.decision = Disappear + } else if ag.stuck { // si le controleur est bloqué + ag.decision = Wait + } else { + ag.decision = Move + } } } @@ -86,9 +86,9 @@ func (c *Controleur) Act(ag *Agent) { case Move: if !c.isExpired { //fmt.Printf("[Controleur, Act, non expiré] Le controleur %s est en mouvement \n", ag.id) - ag.destination = c.randomDestination(ag) + c.SetUpAleaDestination(ag) //fmt.Printf("[Controleur, Act] destination s = %s : %d \n",ag.id,ag.destination) - }else { + } else { //fmt.Printf("[Controleur, Act] Le controleur %s est expiré \n",ag.id) ag.destination = ag.findNearestExit() //fmt.Printf("[Controleur, Act, Expire] destination de %s = %d \n",ag.id,ag.destination) @@ -102,24 +102,24 @@ func (c *Controleur) Act(ag *Agent) { case Disappear: ag.env.RemoveAgent(ag) - case Expel, Stop : //Expel ou Stop + case Expel, Stop: //Expel ou Stop 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é ou arrete\n") - ag.env.controlledAgents[agt_face_id] = true // l'agent qui se trouve devant le controleur est controlé + ag.env.controlledAgents[agt_face_id] = true // l'agent qui se trouve devant le controleur est controlé ag.env.agentsChan[agt_face_id] <- *req.NewRequest(ag.env.agentsChan[ag.id], ag.decision) // envoie la decision du controleur à l'agent qui se trouve devant lui time.Sleep(500 * time.Millisecond) } } -func (c *Controleur) randomDestination(ag *Agent) alg.Coord { - rand.Seed(time.Now().UnixNano()) // le générateur de nombres aléatoires +func (c *Controleur) SetUpAleaDestination(ag *Agent) { + rand.Seed(time.Now().UnixNano()) // le générateur de nombres aléatoires randomRow := rand.Intn(len(ag.env.station[0])) // Génère un entier aléatoire entre 0 et 19 randomCol := rand.Intn(len(ag.env.station[1])) // Génère un entier aléatoire entre 0 et 19 for ag.env.station[randomRow][randomCol] != "_" { randomRow = rand.Intn(len(ag.env.station[0])) // Génère un entier aléatoire entre 0 et 19 randomCol = rand.Intn(len(ag.env.station[1])) // Génère un entier aléatoire entre 0 et 19 } - return alg.Coord{randomRow, randomCol} + ag.destination = alg.Coord{randomRow, randomCol} } func (c *Controleur) startTimer() { @@ -127,11 +127,10 @@ func (c *Controleur) startTimer() { //randomSeconds := rand.Intn(9) + 2 // Génère un entier aléatoire entre 2 et 10 randomSeconds := 500 lifetime := time.Duration(randomSeconds) * time.Second - c.timer = time.NewTimer(lifetime) + c.timer = time.NewTimer(lifetime) //fmt.Println("[Controleur , startTimer] Le controleur est créé avec une durée de vie de ", lifetime) - go func() { - <-c.timer.C // attend que le timer expire - c.isExpired = true - }() + go func() { + <-c.timer.C // attend que le timer expire + c.isExpired = true + }() } - diff --git a/internal/simulation/simu.go b/internal/simulation/simu.go index 2eb61e22ddd6b3ac15b96d651c8193d994f37c14..44b6be13031ae19d02d773cfc43bf0f8a9b53490 100644 --- a/internal/simulation/simu.go +++ b/internal/simulation/simu.go @@ -243,7 +243,9 @@ func (simu *Simulation) Log() { func (simu *Simulation) ActivateFlow() { // Activation du flux d'agents for { - simu.env.AddAgent(*NewAgent("Agent"+fmt.Sprint(simu.env.agentCount), &simu.env, make(chan int), 200, 0, true, &UsagerLambda{}, simu.env.entries[rand.Intn(len(simu.env.entries))], simu.env.gates[rand.Intn(len(simu.env.gates))], 1, 1)) + ag := *NewAgent("Agent"+fmt.Sprint(simu.env.agentCount), &simu.env, make(chan int), 200, 0, true, &UsagerLambda{}, simu.env.entries[rand.Intn(len(simu.env.entries))], simu.env.gates[rand.Intn(len(simu.env.gates))], 1, 1) + ag.behavior.SetUpAleaDestination(&ag) + simu.env.AddAgent(ag) time.Sleep(time.Duration(simu.flow) * time.Millisecond) log.Println(simu.env.ags[len(simu.env.ags)-1].path) } diff --git a/internal/simulation/usagerLambda.go b/internal/simulation/usagerLambda.go index e92642172c8c78e3f28df66b296f7228ec16c84b..a9b9c8406c77de47796a4deff4e019bfbacf7363 100644 --- a/internal/simulation/usagerLambda.go +++ b/internal/simulation/usagerLambda.go @@ -5,17 +5,16 @@ import ( "math/rand" alg "metrosim/internal/algorithms" req "metrosim/internal/request" - "sync" "time" ) type UsagerLambda struct { requete *req.Request - once sync.Once + // once sync.Once } func (ul *UsagerLambda) Percept(ag *Agent) { - ul.once.Do(func() { ul.setUpAleaDestination(ag) }) // la fonction setUp est executé à la premiere appel de la fonction Percept() + //ul.once.Do(func() { ul.setUpAleaDestination(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 //fmt.Printf("Requete recue par l'agent lambda %s : %d \n ",ag.id, ag.request.Decision(), "\n") @@ -135,9 +134,9 @@ func (ul *UsagerLambda) Act(ag *Agent) { ag.request = nil // la requete est traitée } -func (ul *UsagerLambda) setUpAleaDestination(ag *Agent) { +func (ul *UsagerLambda) SetUpAleaDestination(ag *Agent) { //fmt.Println("[UsagerLambda, setUpAleaDestination] setUpAleaDestination") - choix_voie := rand.Intn(len(ag.env.metros)) // choix de la voie de métro aléatoire + choix_voie := rand.Intn(len(ag.env.metros)) // choix de la voie de métro aléatoire dest_porte := rand.Intn(len(ag.env.metros[choix_voie].way.gates)) // choix de la porte de métro aléatoire ag.destination = ag.env.metros[choix_voie].way.gates[dest_porte] } diff --git a/internal/simulation/usagerNormal.go b/internal/simulation/usagerNormal.go index 905babcbf774ad199426784c6421dd0e5b53c428..e3c989f49dbaadebf246f98c53cb6b977cc79824 100644 --- a/internal/simulation/usagerNormal.go +++ b/internal/simulation/usagerNormal.go @@ -1,4 +1,3 @@ - package simulation /* @@ -9,22 +8,22 @@ package simulation import ( "fmt" + "math" "math/rand" alg "metrosim/internal/algorithms" req "metrosim/internal/request" - "time" - "sync" - "math" "sort" + "sync" + "time" ) type UsagerNormal struct { - req *req.Request // req recue par l'agent lambda + req *req.Request // req recue par l'agent lambda once sync.Once } func (un *UsagerNormal) Percept(ag *Agent) { - un.once.Do(func(){un.setUpDestination(ag)}) // la fonction setUp est executé à la premiere appel de la fonction Percept() + un.once.Do(func() { un.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("req recue par l'agent lambda : ", ag.request.decision, "\n") @@ -40,56 +39,55 @@ func (un *UsagerNormal) Percept(ag *Agent) { func (un *UsagerNormal) Deliberate(ag *Agent) { //fmt.Println("[AgentLambda Deliberate] decision :", un.req.decision) - if (un.req != nil ) { + if un.req != nil { switch un.req.Decision() { - case Stop : - ag.decision = Stop - return - case Expel : // cette condition est inutile car l'usager lambda ne peut pas etre expunsé , elle est nécessaire pour les agents fraudeurs - //fmt.Println("[AgentLambda, Deliberate] Expel") - ag.decision = Expel - return - case Disappear : - ag.decision = Disappear - return - case EnterMetro : - ag.decision = EnterMetro - return - case Wait : - ag.decision = Wait - return - case Move : - ag.decision = Move - return - case YouHaveToMove : - fmt.Println("[AgentNormal, Deliberate] J'essaye de bouger ", ag.id) - movement := ag.MoveAgent() - //fmt.Printf("Je suis agent %s Resultat du mouvement de la personne %t \n", ag.id, movement) - if movement { - fmt.Println("[AgentNormal, Deliberate] J'ai bougé ", ag.id) - ag.decision = Done - } else { - ag.decision = Noop - } - return - } - }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") + case Stop: + ag.decision = Stop + return + case Expel: // cette condition est inutile car l'usager lambda ne peut pas etre expunsé , elle est nécessaire pour les agents fraudeurs + //fmt.Println("[AgentLambda, Deliberate] Expel") + ag.decision = Expel + return + case Disappear: ag.decision = Disappear - } else if ag.stuck{ // si l'agent est bloqué + return + case EnterMetro: + ag.decision = EnterMetro + return + case Wait: ag.decision = Wait - }else { - ag.decision = Move - //un.setUpDestination(ag) - } + return + case Move: + ag.decision = Move + return + case YouHaveToMove: + fmt.Println("[AgentNormal, Deliberate] J'essaye de bouger ", ag.id) + movement := ag.MoveAgent() + //fmt.Printf("Je suis agent %s Resultat du mouvement de la personne %t \n", ag.id, movement) + if movement { + fmt.Println("[AgentNormal, Deliberate] J'ai bougé ", ag.id) + ag.decision = Done + } else { + ag.decision = Noop + } + return + } + } 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é + ag.decision = Wait + } else { + ag.decision = Move + //un.setUpDestination(ag) + } } - func (un *UsagerNormal) Act(ag *Agent) { //fmt.Println("[AgentLambda Act] decision :",ag.decision) switch ag.decision { - case Stop : - time.Sleep(time.Duration(5) * time.Second) + case Stop: + time.Sleep(time.Duration(5) * time.Second) case Move: ag.MoveAgent() case Wait: // temps d'attente aléatoire @@ -98,31 +96,31 @@ func (un *UsagerNormal) Act(ag *Agent) { case Disappear: //fmt.Printf("[UsagerLambda, Act] agent %s est disparu \n",ag.id) ag.env.RemoveAgent(ag) - case EnterMetro : - fmt.Printf("[UsagerNormal, Act] agent %s entre dans le Metro \n",ag.id) + case EnterMetro: + fmt.Printf("[UsagerNormal, Act] agent %s entre dans le Metro \n", ag.id) ag.env.RemoveAgent(ag) //fmt.Printf("Demandeur d'entrer le metro : %s \n",un.req.Demandeur()) un.req.Demandeur() <- *req.NewRequest(ag.env.agentsChan[ag.id], ACK) - case Expel : + case Expel: //fmt.Println("[AgentLambda, Act] Expel") ag.destination = ag.findNearestExit() - fmt.Printf("[UsagerNormal, Act] destination de l'agent %s = %s \n",ag.id,ag.destination) + fmt.Printf("[UsagerNormal, Act] destination de l'agent %s = %s \n", ag.id, ag.destination) ag.env.controlledAgents[ag.id] = true ag.path = make([]alg.Node, 0) ag.MoveAgent() - case Noop : + case Noop: //Cas ou un usager impoli demande a un usager de bouger et il refuse un.req.Demandeur() <- *req.NewRequest(ag.env.agentsChan[ag.id], Noop) // nothing to do - case Done : + case Done: //Cas ou un usager impoli demande a un usager de bouger et il le fait un.req.Demandeur() <- *req.NewRequest(ag.env.agentsChan[ag.id], Done) - case TryToMove : + case TryToMove: movement := ag.MoveAgent() fmt.Printf("Je suis %s est-ce que j'ai bougé? %t \n", ag.id, movement) if movement { - un.req.Demandeur()<- *req.NewRequest(ag.env.agentsChan[ag.id], Done) + un.req.Demandeur() <- *req.NewRequest(ag.env.agentsChan[ag.id], Done) } else { un.req.Demandeur() <- *req.NewRequest(ag.env.agentsChan[ag.id], Noop) } @@ -130,8 +128,8 @@ func (un *UsagerNormal) Act(ag *Agent) { //un.req = nil //demande traitée } -func (un *UsagerNormal)setUpDestination(ag *Agent){ - //t := rand.Intn(10) +1 +func (un *UsagerNormal) SetUpDestination(ag *Agent) { + //t := rand.Intn(10) +1 //time.Sleep(time.Duration(t) * time.Second) // "cool down" //fmt.Println("[UsagerNormal, setUpDestination] setUpDestination") choix_voie := rand.Intn(2) // choix de la voie de métro aléatoire @@ -139,13 +137,11 @@ func (un *UsagerNormal)setUpDestination(ag *Agent){ ag.destination = dest_porte } - - func (un *UsagerNormal) findBestGate(ag *Agent, gates []alg.Coord) alg.Coord { - + uniquegates := make([]alg.Coord, 0) for i, gate := range gates { - if i+1 < len(gates) && twocloseGate(gate,gates[i+1]) { + if i+1 < len(gates) && twocloseGate(gate, gates[i+1]) { // Si la porte est trop proche d'une autre, on l'ignore, on considère que c'est la même continue } @@ -165,8 +161,7 @@ func (un *UsagerNormal) findBestGate(ag *Agent, gates []alg.Coord) alg.Coord { //fmt.Println("[findBestGate] gates non normalisé : ",gatesDistances) normalizedGates, _, _ := normalizeGates(gatesDistances) //fmt.Println("[findBestGate] gates normalisé : ",normalizedGates) - - + bestGates := gates_with_lowest_score(normalizedGates) bestGate := bestGates[0] if len(bestGates) > 1 { @@ -184,17 +179,17 @@ func (un *UsagerNormal) findBestGate(ag *Agent, gates []alg.Coord) alg.Coord { var bestGatePos alg.Coord if len(nearGates) > 1 { bestGatePos = nearGates[rand.Intn(len(nearGates))] - }else { + } else { bestGatePos = nearGates[0] } return bestGatePos } -func twocloseGate(gate1 alg.Coord ,gate2 alg.Coord) bool{ - if (gate1[0] == gate2[0]) && (gate1[1] == gate2[1] + 1 || gate1[1] == gate2[1] - 1) { +func twocloseGate(gate1 alg.Coord, gate2 alg.Coord) bool { + if (gate1[0] == gate2[0]) && (gate1[1] == gate2[1]+1 || gate1[1] == gate2[1]-1) { return true } - if (gate1[1] == gate2[1]) && (gate1[0] == gate2[0] + 1 || gate1[0] == gate2[0] - 1) { + if (gate1[1] == gate2[1]) && (gate1[0] == gate2[0]+1 || gate1[0] == gate2[0]-1) { return true } return false @@ -202,28 +197,28 @@ func twocloseGate(gate1 alg.Coord ,gate2 alg.Coord) bool{ // Normalise les valeurs d'un ensemble de portes func normalizeGates(gates []Gate) ([]Gate, float64, float64) { - var minAgents, maxAgents float64 = math.MaxFloat64, 0 - var minDistance, maxDistance float64 = math.MaxFloat64, 0 + var minAgents, maxAgents float64 = math.MaxFloat64, 0 + var minDistance, maxDistance float64 = math.MaxFloat64, 0 - // Trouver les valeurs max et min pour la normalisation - for _, gate := range gates { - if gate.NbAgents > maxAgents { - maxAgents = gate.NbAgents - } - if gate.NbAgents < minAgents { - minAgents = gate.NbAgents - } - if gate.Distance > maxDistance { - maxDistance = gate.Distance - } - if gate.Distance < minDistance { - minDistance = gate.Distance - } - } + // Trouver les valeurs max et min pour la normalisation + for _, gate := range gates { + if gate.NbAgents > maxAgents { + maxAgents = gate.NbAgents + } + if gate.NbAgents < minAgents { + minAgents = gate.NbAgents + } + if gate.Distance > maxDistance { + maxDistance = gate.Distance + } + if gate.Distance < minDistance { + minDistance = gate.Distance + } + } - // Normaliser les valeurs - d_agt := (maxAgents - minAgents) - if d_agt == 0 { + // Normaliser les valeurs + d_agt := (maxAgents - minAgents) + if d_agt == 0 { d_agt = 1.0 } d_dist := (maxDistance - minDistance) @@ -231,17 +226,16 @@ func normalizeGates(gates []Gate) ([]Gate, float64, float64) { d_dist = 1.0 } //fmt.Println("[normalizeGates] d_dist : ",d_dist) - for i := range gates { - gates[i].NbAgents = (gates[i].NbAgents - minAgents) / d_agt + for i := range gates { + gates[i].NbAgents = (gates[i].NbAgents - minAgents) / d_agt //fmt.Println("[normalizeGates] gates[i].Distance : ",gates[i].Distance) //fmt.Println("[normalizeGates] minDistance : ",minDistance) //fmt.Println("[normalizeGates] d_dist : ",d_dist) - gates[i].Distance = (gates[i].Distance - minDistance) / d_dist + gates[i].Distance = (gates[i].Distance - minDistance) / d_dist } - return gates, float64(maxAgents - minAgents), maxDistance - minDistance + return gates, float64(maxAgents - minAgents), maxDistance - minDistance } - // Calcul du score d'un Gate func (g Gate) Score() float64 { return g.Distance + g.NbAgents @@ -274,4 +268,4 @@ func gates_with_lowest_score(gates []Gate) []Gate { } return lowestScoreGates -} \ No newline at end of file +}