152 lines
2.6 KiB
Go
152 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
var printDebugMessages = false
|
|
|
|
type CardinalDirection string
|
|
|
|
const (
|
|
north = CardinalDirection("North")
|
|
south = CardinalDirection("South")
|
|
east = CardinalDirection("East")
|
|
west = CardinalDirection("West")
|
|
)
|
|
|
|
func nextDirection(currentDirection CardinalDirection) CardinalDirection {
|
|
switch currentDirection {
|
|
case north:
|
|
return east
|
|
case east:
|
|
return south
|
|
case south:
|
|
return west
|
|
case west:
|
|
return north
|
|
}
|
|
return north
|
|
}
|
|
|
|
func oppositeDirection(currentDirection CardinalDirection) CardinalDirection {
|
|
switch currentDirection {
|
|
case north:
|
|
return south
|
|
case east:
|
|
return west
|
|
case south:
|
|
return north
|
|
case west:
|
|
return east
|
|
}
|
|
return north
|
|
}
|
|
|
|
type Colour int
|
|
|
|
const (
|
|
red Colour = iota
|
|
green
|
|
yellow
|
|
)
|
|
|
|
func (colour Colour) String() string {
|
|
switch colour {
|
|
case red:
|
|
return "Red"
|
|
case yellow:
|
|
return "Yellow"
|
|
case green:
|
|
return "Green"
|
|
default:
|
|
return "null"
|
|
}
|
|
}
|
|
|
|
func nextColour(colour Colour) Colour {
|
|
return (colour + 1) % (yellow + 1)
|
|
}
|
|
|
|
var northChannel = make(chan string)
|
|
var southChannel = make(chan string)
|
|
var eastChannel = make(chan string)
|
|
var westChannel = make(chan string)
|
|
|
|
func getChannel(direction CardinalDirection) chan string {
|
|
switch direction {
|
|
case north:
|
|
return northChannel
|
|
case south:
|
|
return northChannel
|
|
case east:
|
|
return eastChannel
|
|
case west:
|
|
return eastChannel
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
var quitChannel = make(chan string)
|
|
|
|
go TrafficLight(north)
|
|
go TrafficLight(south)
|
|
go TrafficLight(east)
|
|
go TrafficLight(west)
|
|
|
|
<-quitChannel
|
|
}
|
|
|
|
func TrafficLight(direction CardinalDirection) {
|
|
var colour = red
|
|
|
|
if direction == east || direction == west {
|
|
handover("changeDirection", direction)
|
|
}
|
|
|
|
for {
|
|
show(direction, colour)
|
|
|
|
if colour == red {
|
|
sync("wait", direction)
|
|
handover("changeDirection", direction)
|
|
}
|
|
|
|
sync("changeLight"+string(nextColour(colour)), direction)
|
|
colour = nextColour(colour)
|
|
}
|
|
}
|
|
|
|
func handover(message string, direction CardinalDirection) {
|
|
getChannel(nextDirection(direction)) <- message
|
|
|
|
select {
|
|
case msg := <-getChannel(direction):
|
|
debug(msg)
|
|
}
|
|
}
|
|
|
|
func sync(message string, direction CardinalDirection) {
|
|
defer debug(string(direction) + " done with message " + message)
|
|
|
|
debug(string(direction) + " sync with message " + message)
|
|
|
|
select {
|
|
case getChannel(direction) <- message:
|
|
case msg := <-getChannel(direction):
|
|
debug(msg)
|
|
}
|
|
|
|
}
|
|
|
|
func show(direction CardinalDirection, colour Colour) {
|
|
fmt.Println(string(direction), " : ", colour.String())
|
|
}
|
|
|
|
func debug(message string) {
|
|
if printDebugMessages {
|
|
fmt.Println("Debug: " + message)
|
|
}
|
|
}
|