diff --git a/kadai3_1/.gitignore b/kadai3_1/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/kadai3_1/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/kadai3_1/asuke-yasukuni/README.md b/kadai3_1/asuke-yasukuni/README.md new file mode 100644 index 0000000..a5d970e --- /dev/null +++ b/kadai3_1/asuke-yasukuni/README.md @@ -0,0 +1,16 @@ +## dojo7 [課題3-1] タイピングゲームを作ろう + +課題3-2が重いため、かなり簡素な感じにしました。 +インターフェースの概念に慣れてないせいで、チャネルが絡むテストを書くのが以外に難しかったです。 + +最終的には割とちゃんと書けた気がします(気がするだけかもしれない)。 + +## 回答 + +- 標準出力に英単語を出す(出すものは自由) + - OK +- 標準入力から1行受け取る + - OK +- 制限時間内に何問解けたか表示する + - OK + diff --git a/kadai3_1/asuke-yasukuni/go.mod b/kadai3_1/asuke-yasukuni/go.mod new file mode 100644 index 0000000..0f88375 --- /dev/null +++ b/kadai3_1/asuke-yasukuni/go.mod @@ -0,0 +1,3 @@ +module github.com/dojo7/kadai3_1/asuke-yasukuni + +go 1.12 diff --git a/kadai3_1/asuke-yasukuni/main.go b/kadai3_1/asuke-yasukuni/main.go new file mode 100644 index 0000000..e2d7d85 --- /dev/null +++ b/kadai3_1/asuke-yasukuni/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "github.com/dojo7/kadai3_1/asuke-yasukuni/typing" +) + +func main() { + typing.SetGame([]string{ + "tanuki", + "gouge", + "english", + }).Do() +} diff --git a/kadai3_1/asuke-yasukuni/typing/game.go b/kadai3_1/asuke-yasukuni/typing/game.go new file mode 100644 index 0000000..bc73ac3 --- /dev/null +++ b/kadai3_1/asuke-yasukuni/typing/game.go @@ -0,0 +1,86 @@ +package typing + +import ( + "bufio" + "fmt" + "math/rand" + "os" + "time" +) + +type InputReader interface { + Input() <-chan string +} + +type Reader struct{} + +func (r *Reader) Input() <-chan string { + ch := make(chan string) + + go func() { + s := bufio.NewScanner(os.Stdin) + for s.Scan() { + ch <- s.Text() + } + close(ch) + }() + return ch +} + +type OutputWriter interface { + Output(string) +} + +type Writer struct{} + +func (w Writer) Output(outputText string) { + fmt.Println(outputText) +} + +type Game struct { + Time time.Duration + Words []string + Reader InputReader + Writer OutputWriter +} + +func SetGame(words []string) *Game { + return &Game{ + Time: 5, + Words: words, + Reader: &Reader{}, + Writer: Writer{}, + } +} + +func (g *Game) Do() (clearCount int) { + ch := g.Reader.Input() + timeUp := time.After(g.Time * time.Second) + + t := time.Now().UnixNano() + rand.Seed(t) + +L: + for { + i := rand.Intn(len(g.Words)) + selectWord := g.Words[i] + g.Writer.Output(selectWord) + + select { + case text := <-ch: + if selectWord == text { + clearCount++ + g.Writer.Output("OK") + } else { + g.Writer.Output("NG") + } + case <-timeUp: + g.Writer.Output("========") + g.Writer.Output("time up") + g.Writer.Output(fmt.Sprintf("clear count %d", clearCount)) + break L + } + } + + return +} diff --git a/kadai3_1/asuke-yasukuni/typing/game_test.go b/kadai3_1/asuke-yasukuni/typing/game_test.go new file mode 100644 index 0000000..c77f5b5 --- /dev/null +++ b/kadai3_1/asuke-yasukuni/typing/game_test.go @@ -0,0 +1,55 @@ +package typing + +import ( + "testing" + "time" +) + +type TestReader struct { + TestWord []string +} + +func (r *TestReader) Input() <-chan string { + ch := make(chan string) + go func() { + for _, word := range r.TestWord { + ch <- word + } + time.Sleep(1 * time.Second) + close(ch) + }() + return ch +} + +type TestWriter struct{} + +func (w TestWriter) Output(outputText string) {} + +func TestTyping(t *testing.T) { + + var testCase = []struct { + Name string + Question []string + Word []string + Count int + }{ + {"all clear", []string{"hoge", "hoge", "hoge", "hoge"}, []string{"hoge", "hoge", "hoge", "hoge"}, 4}, + {"all fail", []string{"neeko", "enga", "els", "gezi"}, []string{"neko", "english", "eigo", "genzin"}, 0}, + {"1 clear", []string{"hoge"}, []string{"neko", "hoge", "eigo", "genzin"}, 1}, + } + + for _, tc := range testCase { + game := &Game{ + Time: 1, + Words: tc.Question, + Reader: &TestReader{TestWord: tc.Word}, + Writer: TestWriter{}, + } + t.Run(tc.Name, func(t *testing.T) { + count := game.Do() + if count != tc.Count { + t.Errorf("%d == %d not equal", count, tc.Count) + } + }) + } +}