8
8
"math/rand"
9
9
"os"
10
10
"time"
11
+
12
+ "github.com/hashicorp/go-multierror"
11
13
)
12
14
13
15
// Words stores a slice of words which is used for the game.
@@ -21,38 +23,42 @@ type Game struct {
21
23
22
24
// Execute starts the game using standard input and output.
23
25
func Execute (g Game ) error {
24
- g .run (inputChannel (os .Stdin ), os .Stdout )
25
- return nil
26
+ err := g .run (inputChannel (os .Stdin ), os .Stdout )
27
+ return err
26
28
}
27
29
28
- func (g * Game ) run (ch <- chan string , w io.Writer ) {
30
+ func (g * Game ) run (ch <- chan string , w io.Writer ) error {
31
+ var result error
32
+
29
33
bc := context .Background ()
30
34
ctx , cancel := context .WithTimeout (bc , g .TimeLimit )
31
35
defer cancel ()
32
36
33
- fmt . Fprintln ( w , "Let's type the standard package names! ( Time limit:" , g .TimeLimit , ")" )
37
+ result = printWithMultiErr ( w , result , "Let's type the standard package names! ( Time limit:" , g .TimeLimit , ")" )
34
38
35
39
var score int
36
40
rand .Seed (time .Now ().UnixNano ())
37
41
word := g .Words [rand .Intn (len (g .Words ))]
38
42
LOOP:
39
43
for {
40
- fmt . Fprintln ( w , ">" , word )
44
+ result = printWithMultiErr ( w , result , ">" , word )
41
45
select {
42
46
case input := <- ch :
43
47
if input == word {
44
48
score ++
45
- fmt . Fprintln ( w , input , "... OK! current score:" , score )
49
+ result = printWithMultiErr ( w , result , input , "... OK! current score:" , score )
46
50
word = g .Words [rand .Intn (len (g .Words ))]
47
51
} else {
48
- fmt . Fprintln ( w , input , "... NG: try again." )
52
+ result = printWithMultiErr ( w , result , input , "... NG: try again." )
49
53
}
50
54
case <- ctx .Done ():
51
- fmt . Fprintln ( w )
52
- fmt . Fprintln ( w , g .TimeLimit , "has passed: you correctly typed" , score , "package(s)!" )
55
+ result = printWithMultiErr ( w , result )
56
+ result = printWithMultiErr ( w , result , g .TimeLimit , "has passed: you correctly typed" , score , "package(s)!" )
53
57
break LOOP
54
58
}
55
59
}
60
+
61
+ return result
56
62
}
57
63
58
64
func inputChannel (r io.Reader ) <- chan string {
@@ -66,3 +72,10 @@ func inputChannel(r io.Reader) <-chan string {
66
72
}()
67
73
return ch
68
74
}
75
+
76
+ func printWithMultiErr (w io.Writer , result error , a ... interface {}) error {
77
+ if _ , err := fmt .Fprintln (w , a ... ); err != nil {
78
+ result = multierror .Append (result , err )
79
+ }
80
+ return result
81
+ }
0 commit comments