122 lines
2.7 KiB
Go
122 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
//Definition CardinalDirection als enum
|
|
type CardinalDirection int
|
|
|
|
const (
|
|
north = iota
|
|
east
|
|
south
|
|
west
|
|
)
|
|
|
|
func (direction CardinalDirection) String() string {
|
|
return [...]string{"North", "East", "South", "West"}[direction]
|
|
}
|
|
|
|
//Definition Colour als enum
|
|
type Colour int
|
|
|
|
const (
|
|
red Colour = iota
|
|
green
|
|
yellow
|
|
)
|
|
|
|
//definiert nächste Farbe in der Reihenfolge red -> green -> yellow -> red ...
|
|
func nextColour(colour Colour) Colour {
|
|
return (colour + 1) % (yellow + 1)
|
|
}
|
|
|
|
func (colour Colour) String() string {
|
|
return [...]string{"Red", "Green", "Yellow"}[colour]
|
|
}
|
|
|
|
//Erstellung der Channel
|
|
var northSouthChannel = make(chan string)
|
|
var eastWestChannel = make(chan string)
|
|
|
|
var northEastChannel = make(chan string)
|
|
var southWestChannel = make(chan string)
|
|
|
|
//Channel für die Achse erhalten, zu der direction gehört
|
|
func getAxisChannel(direction CardinalDirection) chan string {
|
|
if direction == north || direction == south {
|
|
return northSouthChannel
|
|
}
|
|
return eastWestChannel
|
|
}
|
|
|
|
//Channel für Kommunikation zur rechts folgendem TrafficLight erhalten.
|
|
func getNextChannel(direction CardinalDirection) chan string {
|
|
if direction == north || direction == east {
|
|
return northEastChannel
|
|
}
|
|
return southWestChannel
|
|
}
|
|
|
|
func main() {
|
|
var quitChannel = make(chan string)
|
|
|
|
//starten der Routinen
|
|
go TrafficLight(north)
|
|
go TrafficLight(south)
|
|
go TrafficLight(east)
|
|
go TrafficLight(west)
|
|
|
|
<-quitChannel
|
|
}
|
|
|
|
func TrafficLight(direction CardinalDirection) {
|
|
var colour = red
|
|
|
|
//warten bis handover ausgelöst wurde wenn Osten/Westen
|
|
if direction == east || direction == west {
|
|
select {
|
|
case <-getNextChannel(direction):
|
|
}
|
|
}
|
|
|
|
//Dauerschleife
|
|
for {
|
|
show(direction, colour) //Zustand zeigen
|
|
|
|
if colour == red { //wenn zu rot gewechselt wurde
|
|
sync("wait", direction) //synchronisieren
|
|
handover("changeDirection", direction) //Nächstfolgende Ampel auslösen, warten bis diese fertig durchgelaufen ist.
|
|
}
|
|
sync("changeLight", direction) //synchronisieren
|
|
colour = nextColour(colour) //Ampel umschalten
|
|
}
|
|
}
|
|
|
|
//der Routine für die rechts folgende Richtung eine Nachricht senden.
|
|
//erst wenn eine Nachricht der linken Routine empfangen wird, wird fortgefahren.
|
|
func handover(message string, direction CardinalDirection) {
|
|
getNextChannel(direction) <- message
|
|
|
|
select {
|
|
case <-getNextChannel(direction):
|
|
}
|
|
|
|
}
|
|
|
|
//mit der Routine für die gegenüberliegende Ampel synchronisieren.
|
|
func sync(message string, direction CardinalDirection) {
|
|
|
|
select {
|
|
case getAxisChannel(direction) <- message:
|
|
case <-getAxisChannel(direction):
|
|
}
|
|
|
|
}
|
|
|
|
//zeigen des aktuellen Zustands.
|
|
func show(direction CardinalDirection, colour Colour) {
|
|
fmt.Println(direction.String(), " : ", colour.String())
|
|
}
|