1 package main
2 import ( "fmt"; "os"; "flag"; "strconv"; "rand"; "time" )
3
4
5 type Throw int
6 const ( ROCK Throw = iota; PAPER; SCISSORS; NUM_THROWS )
7
8
9 func beats(me Throw, you Throw) bool {
10 return (me == ROCK && you == SCISSORS) ||
11 (me == SCISSORS && you == PAPER) ||
12 (me == PAPER && you == ROCK)
13 }
14
15
16 func random_throw() Throw { return Throw(rand.Intn(int(NUM_THROWS))) }
17
18
19 type Packet struct { throw Throw; lifetime int }
20
21
22 type Result struct { player int; score int }
23
24
25
26
27
28
29
30
31
32
33
34
35
36 func play_rounds(read chan Packet, write chan Packet, n int) int {
37 score := 0
38
39 for r := 0; r < 1000; r++ {
40 throw := random_throw()
41 write <- Packet { throw, n - 1 }
42
43
44 for got := 1; got < n; got++ {
45 opp := <- read
46 if beats(throw, opp.throw) { score++ }
47
48
49 opp.lifetime--
50 if opp.lifetime != 0 { write <- opp }
51 }
52 }
53
54 return score
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 func player(write chan Packet, report chan Result, id int, n int) chan Packet {
71 read := make(chan Packet, n)
72
73 go func() {
74 score := play_rounds(read, write, n);
75 report <- Result { id, score }
76 }()
77
78 return read
79 }
80
81
82
83
84 func main() {
85 if flag.NArg() != 1 {
86 os.Stderr.WriteString("Usage: jkp <N>\n")
87 os.Exit(1)
88 }
89
90 n, err := strconv.Atoi(flag.Arg(0))
91
92 if err != nil {
93 fmt.Fprintf(os.Stderr, "The argument must be a number (%v)\n", err)
94 os.Exit(1)
95 }
96
97 if n < 2 {
98 fmt.Fprintf(os.Stderr, "The argument must be 2 or greater (not %d)\n", n)
99 os.Exit(1)
100 }
101
102 rand.Seed(time.Nanoseconds())
103
104
105
106
107
108
109
110
111 report := make(chan Result)
112 ring := make(chan Packet, n)
113
114
115 read := ring
116
117 for i := 1; i < n; i++ {
118 ring = player(ring, report, i, n)
119 }
120
121 write := ring
122
123
124 score := play_rounds(read, write, n);
125
126
127 fmt.Printf("Player %d Score %d\n", 0, score)
128
129 for i := 1; i < n; i++ {
130 r := <- report
131 fmt.Printf("Player %d Score %d\n", r.player, r.score)
132 }
133 }