Skip to content
Snippets Groups Projects
Commit 7cfe3f6d authored by Jana Eltayeb El Rafei's avatar Jana Eltayeb El Rafei
Browse files

first_modifs

parent 47975acd
No related branches found
No related tags found
1 merge request!8Controleur
package main
import (
"fmt"
"regexp"
)
func main() {
faceCase := "Agent1000" // Remplacez ceci par votre variable
// Créer l'expression régulière
regexPattern := `^Agent\d+$` // \d+ correspond à un ou plusieurs chiffres
matched, err := regexp.MatchString(regexPattern, faceCase)
if err != nil {
fmt.Println("Erreur lors de l'analyse de la regex :", err)
return
}
// Vérifiez si la chaîne ne correspond pas au motif
if !matched {
fmt.Println("La chaîne ne correspond pas au motif 'Agentx'")
} else {
fmt.Println("La chaîne correspond au motif 'Agentx'")
}
}
...@@ -24,6 +24,7 @@ const ( ...@@ -24,6 +24,7 @@ const (
Mark Mark
Wait Wait
Move Move
Expel // decision du Controleur
) )
type Coord [2]int type Coord [2]int
...@@ -45,19 +46,30 @@ type Agent struct { ...@@ -45,19 +46,30 @@ type Agent struct {
stuck bool stuck bool
width int width int
height int height int
orientation int orientation int //0 : vers le haut, 1 : vers la droite, 2 : vers le bas, 3 : vers la gauche
request *Request
} }
type Request struct {
demandeur AgentID
decision int
}
type Behavior interface { type Behavior interface {
Percept(*Agent) Percept(*Agent)
Deliberate(*Agent) Deliberate(*Agent)
Act(*Agent) Act(*Agent)
} }
func NewRequest(demandeur AgentID, decision int) (req *Request) {
return &Request{demandeur, decision}
}
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 { 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) isOn := make(map[Coord]string)
saveCells(&env.station, isOn, departure, width, height, 0) saveCells(&env.station, isOn, departure, width, height, 0)
return &Agent{AgentID(id), vitesse, force, politesse, departure, departure, destination, behavior, env, syncChan, Noop, isOn, false, width, height, 0} return &Agent{AgentID(id), vitesse, force, politesse, departure, departure, destination, behavior, env, syncChan, Noop, isOn, false, width, height, 0, nil}
} }
func (ag *Agent) ID() AgentID { func (ag *Agent) ID() AgentID {
...@@ -229,7 +241,7 @@ func writeAgent(matrix *[20][20]string, agt *Agent) { ...@@ -229,7 +241,7 @@ func writeAgent(matrix *[20][20]string, agt *Agent) {
for i := borneInfRow; i < borneSupRow; i++ { for i := borneInfRow; i < borneSupRow; i++ {
for j := borneInfCol; j < borneSupCol; j++ { for j := borneInfCol; j < borneSupCol; j++ {
matrix[i][j] = "A" matrix[i][j] = string(agt.id)
} }
} }
......
package simulation
import (
"math/rand"
"time"
"regexp"
"fmt"
)
/*
Je suppose que l'id du controleur est de format "Cont + un chiffre"
Exemple : "Cont1"
et l'id du l'agent est de format "Agent + un chiffre"
Exemple : "Agent1"
*/
type Controleur struct{
faceCase string // chaine de caractère qui contient l'id de l'agent qui se trouve devant le controleur, exemple : "Agent1", "Fraudeur1", "X" ,etc.
}
func (c *Controleur) Percept(ag *Agent) {
env := ag.env
if ag.orientation == 0 { // vers le haut
c.faceCase = env.station[ag.position[0]-1][ag.position[1]]
} else if ag.orientation == 1 { // vers la droite
c.faceCase = env.station[ag.position[0]][ag.position[1]+1]
} else if ag.orientation == 2 { // vers le bas
c.faceCase = env.station[ag.position[0]+1][ag.position[1]]
} else { // vers la gauche
c.faceCase = env.station[ag.position[0]][ag.position[1]-1]
}
}
func (c *Controleur) Deliberate(ag *Agent) {
// Verifier si la case devant lui contient un agent ou un fraudeur
// Créer l'expression régulière
regexAgent:= `^Agent\d+$` // \d+ correspond à un ou plusieurs chiffres
regexFraudeur := `^Fraudeur\d+$`
// Vérifier si la valeur de faceCase ne correspond pas au motif
matchedAgt, err1 := regexp.MatchString(regexAgent, c.faceCase)
matchedFraud, err2 := regexp.MatchString(regexFraudeur, c.faceCase)
if err1 != nil || err2 != nil {
fmt.Println("Erreur lors de l'analyse de la regex :", err1, err2)
return
} else {
if matchedAgt {
ag.decision = Wait // arreter l'agent devant lui
} else if matchedFraud {
ag.decision = Expel // virer l'agent devant lui
} else{
// Comportement de l'usager lambda (par defaut)
if ag.stuck {
ag.decision = Wait
} else {
ag.decision = Move
}
}
}
}
func (c *Controleur) Act(ag *Agent) {
if ag.decision == Move {
ag.MoveAgent()
} else if ag.decision == Wait {
n := rand.Intn(2) // temps d'attente aléatoire
time.Sleep(time.Duration(n) * time.Second)
} else {
agt_face_id := AgentID(c.faceCase)
ag.env.agentsChan[agt_face_id] <- *NewRequest(ag.id, ag.decision) // envoie la decision du controleur à l'agent qui se trouve devant lui
}
}
...@@ -10,13 +10,17 @@ type Environment struct { ...@@ -10,13 +10,17 @@ type Environment struct {
ags []Agent ags []Agent
agentCount int agentCount int
station [20][20]string station [20][20]string
agentsChan map[AgentID]chan AgentID agentsChan map[AgentID]chan Request
} }
func NewEnvironment(ags []Agent, carte [20][20]string, agentsCh map[AgentID]chan AgentID) (env *Environment) {
func NewEnvironment(ags []Agent, carte [20][20]string, agentsCh map[AgentID]chan Request) (env *Environment) {
return &Environment{ags: ags, agentCount: len(ags), station: carte, agentsChan: agentsCh} return &Environment{ags: ags, agentCount: len(ags), station: carte, agentsChan: agentsCh}
} }
func (env *Environment) AddAgent(agt Agent) { func (env *Environment) AddAgent(agt Agent) {
env.ags = append(env.ags, agt) env.ags = append(env.ags, agt)
env.agentCount++ env.agentCount++
...@@ -51,3 +55,8 @@ func (env *Environment) PI() float64 { ...@@ -51,3 +55,8 @@ func (env *Environment) PI() float64 {
func (env *Environment) Rect() Coord { func (env *Environment) Rect() Coord {
return Coord{0, 0} return Coord{0, 0}
} }
func (env *Environment) GetAgentChan(agt_id AgentID) chan Request {
return env.agentsChan[agt_id]
}
\ No newline at end of file
...@@ -18,6 +18,7 @@ import ( ...@@ -18,6 +18,7 @@ import (
* Q : Voie * Q : Voie
* _ : Couloir, case libre * _ : Couloir, case libre
* B: Bridge/Pont, zone accessible * B: Bridge/Pont, zone accessible
* valeur de AgentID : Agent
*/ */
var carte [20][20]string = [20][20]string{ 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", "W", "W", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X"},
...@@ -110,13 +111,14 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu ...@@ -110,13 +111,14 @@ func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu
ag.env.AddAgent(*ag) ag.env.AddAgent(*ag)
// ajout // ajout
simu.env.agentsChan[ag.id] = make(chan AgentID) simu.env.agentsChan[ag.id] = make(chan Requete)
} }
return simu return simu
} }
func (simu *Simulation) Run() { func (simu *Simulation) Run() {
// 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()) log.Printf("Démarrage de la simulation [step: %d, π: %f]", simu.step, simu.env.PI())
// Démarrage du micro-service de Log // Démarrage du micro-service de Log
...@@ -145,7 +147,7 @@ func (simu *Simulation) Run() { ...@@ -145,7 +147,7 @@ func (simu *Simulation) Run() {
step := 0 step := 0
for { for {
step++ step++
c, _ := simu.syncChans.Load(agt.ID()) c, _ := simu.syncChans.Load(agt.ID()) // communiquer les steps aux agents
c.(chan int) <- step // /!\ utilisation d'un "Type Assertion" c.(chan int) <- step // /!\ utilisation d'un "Type Assertion"
time.Sleep(1 * time.Millisecond) // "cool down" time.Sleep(1 * time.Millisecond) // "cool down"
<-c.(chan int) <-c.(chan int)
...@@ -163,6 +165,8 @@ func (simu *Simulation) Print() { ...@@ -163,6 +165,8 @@ func (simu *Simulation) Print() {
for i := 0; i < 20; i++ { for i := 0; i < 20; i++ {
fmt.Println(simu.env.station[i]) fmt.Println(simu.env.station[i])
} }
fmt.Println()
fmt.Println()
//time.Sleep(time.Second / 4) // 60 fps ! //time.Sleep(time.Second / 4) // 60 fps !
time.Sleep(500 * time.Millisecond) // 1 fps ! time.Sleep(500 * time.Millisecond) // 1 fps !
//fmt.Print("\033[H\033[2J") // effacement du terminal //fmt.Print("\033[H\033[2J") // effacement du terminal
......
...@@ -5,19 +5,27 @@ import ( ...@@ -5,19 +5,27 @@ import (
"time" "time"
) )
type UsagerLambda struct{} type UsagerLambda struct{
req Request
}
func (ul *UsagerLambda) Percept(ag *Agent) { func (ul *UsagerLambda) Percept(ag *Agent) {
ag.stuck = ag.isStuck() // récupérer le channel de l'agent lambda
if ag.stuck { chan_agt := ag.env.GetAgentChan(ag.id)
return 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
ul.req = req
case <- time.After(time.Second):
ag.stuck = ag.isStuck()
} }
} }
func (ul *UsagerLambda) Deliberate(ag *Agent) { func (ul *UsagerLambda) Deliberate(ag *Agent) {
if ag.stuck { if ul.req.decision == Wait{
ag.decision = Wait
} else if ul.req.decision == Expel{
ag.decision = Expel
} else if ag.stuck {
ag.decision = Wait ag.decision = Wait
} else { } else {
ag.decision = Move ag.decision = Move
...@@ -30,6 +38,24 @@ func (ul *UsagerLambda) Act(ag *Agent) { ...@@ -30,6 +38,24 @@ func (ul *UsagerLambda) Act(ag *Agent) {
} else if ag.decision == Wait { } else if ag.decision == Wait {
n := rand.Intn(2) // temps d'attente aléatoire n := rand.Intn(2) // temps d'attente aléatoire
time.Sleep(time.Duration(n) * time.Second) time.Sleep(time.Duration(n) * time.Second)
} else {
ag.destination = ul.findNearestExit(ag.env)
ag.MoveAgent()
} }
}
/*
* Fonction qui permet de trouver la sortie la plus proche
*/
func (ul *UsagerLambda) findNearestExit(env *Environment) Coord{
station := env.station
for i := 0; i < len(station); i++ {
for j := 0; j < len(station[i]); j++ {
if station[i][j] == "X" {
return Coord{i,j}
}
}
}
return Coord{0,0}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment