-
Jana Eltayeb El Rafei authoredJana Eltayeb El Rafei authored
simu.go 7.46 KiB
package simulation
import (
"fmt"
"log"
//"math/rand"
"sync"
"time"
)
// Déclaration de la matrice
/*
* X : Mur, zone inatteignable
* E : Entrée
* S : Sortie
* W : Entrée et Sortie
* Q : Voie
* _ : Couloir, case libre
* B: Bridge/Pont, zone accessible
* valeur de AgentID : Agent
*/
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", "_"},
{"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"},
{"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"},
}
var playground [20][20]string = [20][20]string{
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "X", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
{"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_"},
}
type Simulation struct {
env Environment
agents []Agent
maxStep int
maxDuration time.Duration
step int // Stats
start time.Time
syncChans sync.Map
}
func (sim *Simulation) Env() *Environment {
return &sim.env
}
func NewSimulation(agentCount int, maxStep int, maxDuration time.Duration) (simu *Simulation) {
simu = &Simulation{}
simu.agents = make([]Agent, 0, agentCount)
simu.maxStep = maxStep
simu.maxDuration = maxDuration
// Communication entre agents
mapChan := make(map[AgentID]chan Request)
simu.env = *NewEnvironment([]Agent{}, carte, mapChan)
//simu.env = *NewEnvironment([]Agent{}, playground, mapChan)
// 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 := 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, 1000, 0, true, &UsagerLambda{}, Coord{2, 8}, Coord{13, 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)
// ajout du channel de synchro
simu.syncChans.Store(ag.ID(), syncChan)
// ajout de l'agent à l'environnement
ag.env.AddAgent(*ag)
// ajout du channel de l'agent à l'environnement
simu.env.agentsChan[ag.id] = make(chan Request)
}
return simu
}
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())
// Démarrage du micro-service de Log
go simu.Log()
// Démarrage du micro-service d'affichage
go simu.Print()
// Démarrage des agents
var wg sync.WaitGroup
for _, agt := range simu.agents {
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 {
go func(agt Agent) {
step := 0
for {
step++
c, _ := simu.syncChans.Load(agt.ID()) // communiquer les steps aux agents
c.(chan int) <- step // /!\ utilisation d'un "Type Assertion"
time.Sleep(1 * time.Millisecond) // "cool down"
<-c.(chan int)
}
}(agt)
}
time.Sleep(simu.maxDuration)
log.Printf("Fin de la simulation [step: %d, in: %d, out: %d, π: %f]", simu.step, simu.env.PI())
}
func (simu *Simulation) Print() {
for {
for i := 0; i < 20; i++ {
fmt.Println(simu.env.station[i])
}
fmt.Println()
fmt.Println()
fmt.Println("============================================================")
//time.Sleep(time.Second / 4) // 60 fps !
time.Sleep(5000 * time.Millisecond) // 1 fps !
//fmt.Print("\033[H\033[2J") // effacement du terminal
}
}
func (simu *Simulation) Log() {
// Not implemented
}