package main import ( "flag" "fmt" "log" "math/rand" "sync" "time" ) func main() { numPlayers := flag.Int("n", 2, "Number of players") sides := flag.Int("sides", 6, "How many sides the die should have") flag.Parse() if *numPlayers < 2 { log.Fatalf("we need at least 2 players") } if *sides < 2 { log.Fatalf("die needs at least two sides") } fmt.Println("Welcome to the game") fmt.Printf("There are %d players, each with a %d-sided die\n", *numPlayers, *sides) game(*numPlayers, *sides) } type Score struct { id int score int } // The player with the lowest score wins. func game(numPlayers, faces int) { // Get the game's winning number by throwing the die once. winningNumber := throwDie(faces) fmt.Printf("Winning number is %d\n", winningNumber) // The scores channel communicates the number of turns a // player took to hit the winning number. scores := make(chan Score) var wg sync.WaitGroup for i := range numPlayers { id := i + 1 // Spawn a player. wg.Go(func() { var score int // Start rolling the dice! for { score++ outcome := throwDie(faces) fmt.Printf("Player %d threw a %d\n", id, outcome) if outcome == winningNumber { scores <- Score{id: id, score: score} return } time.Sleep(1 * time.Second) } }) } go func() { wg.Wait() close(scores) }() for score := range scores { fmt.Printf("%v\n", score) } } func throwDie(faces int) int { return rand.Intn(faces) + 1 }