From 21c5cb655631fbc4f0b9c38f71f00ff21df0cd55 Mon Sep 17 00:00:00 2001 From: YoheiMiyamoto Date: Sun, 25 Nov 2018 22:07:27 +0900 Subject: [PATCH 1/5] add kadai3-1 --- kadai3-1/yoheimiyamoto/README.md | 4 ++ kadai3-1/yoheimiyamoto/main.go | 12 ++++ kadai3-1/yoheimiyamoto/pingpong/doc.go | 5 ++ kadai3-1/yoheimiyamoto/pingpong/pingpong.go | 57 +++++++++++++++++++ .../yoheimiyamoto/pingpong/pingpong_test.go | 1 + kadai3-1/yoheimiyamoto/pingpong/result.go | 29 ++++++++++ .../yoheimiyamoto/pingpong/result_test.go | 14 +++++ 7 files changed, 122 insertions(+) create mode 100644 kadai3-1/yoheimiyamoto/README.md create mode 100644 kadai3-1/yoheimiyamoto/main.go create mode 100644 kadai3-1/yoheimiyamoto/pingpong/doc.go create mode 100644 kadai3-1/yoheimiyamoto/pingpong/pingpong.go create mode 100644 kadai3-1/yoheimiyamoto/pingpong/pingpong_test.go create mode 100644 kadai3-1/yoheimiyamoto/pingpong/result.go create mode 100644 kadai3-1/yoheimiyamoto/pingpong/result_test.go diff --git a/kadai3-1/yoheimiyamoto/README.md b/kadai3-1/yoheimiyamoto/README.md new file mode 100644 index 0000000..f17eb64 --- /dev/null +++ b/kadai3-1/yoheimiyamoto/README.md @@ -0,0 +1,4 @@ +タイピングゲームを作ろう +標準出力に英単語を出す(出すものは自由) +標準入力から1行受け取る +制限時間内に何問解けたか表示する diff --git a/kadai3-1/yoheimiyamoto/main.go b/kadai3-1/yoheimiyamoto/main.go new file mode 100644 index 0000000..ab510cf --- /dev/null +++ b/kadai3-1/yoheimiyamoto/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "os" + + "github.com/YoheiMiyamoto/dojo4/kadai3-1/yoheimiyamoto/pingpong" +) + +func main() { + words := []string{"one", "two", "three"} + pingpong.Play(os.Stdin, os.Stdout, words) +} diff --git a/kadai3-1/yoheimiyamoto/pingpong/doc.go b/kadai3-1/yoheimiyamoto/pingpong/doc.go new file mode 100644 index 0000000..3312dd2 --- /dev/null +++ b/kadai3-1/yoheimiyamoto/pingpong/doc.go @@ -0,0 +1,5 @@ +/* +Package pingpong ... + +*/ +package pingpong diff --git a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go new file mode 100644 index 0000000..2c0294b --- /dev/null +++ b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go @@ -0,0 +1,57 @@ +package pingpong + +import ( + "bufio" + "fmt" + "os" +) + +// Play ... +// words -> 出題するワード一覧 +func Play(stdin, stdout *os.File, words []string) { + fmt.Println("ゲームスタート!\nゲームを途中で終了する場合はexitを入力してください。") + inputCh := make(chan string) + done := make(chan struct{}) + var r result + input(os.Stdin, inputCh, done) + var count int + for { + word := words[count] + fmt.Println(word) + + select { + case a := <-inputCh: + if a == word { + fmt.Fprintln(stdout, "正解!") + r.addCorrect() + } else { + fmt.Fprintln(stdout, "不正解!") + r.addIncorrect() + } + if count == (len(words) - 1) { + fmt.Println(r) + os.Exit(0) + } + count++ + case <-done: + fmt.Fprintln(stdout, "終了します。") + fmt.Println(r) + os.Exit(0) + } + } +} + +// 標準入力から受け取ったテキストをchチャネルに送信。 +// 標準入力から「exit」というワードを受け取った場合は、doneチャネルをcloseする。 +func input(stdin *os.File, ch chan<- string, done chan<- struct{}) { + scanner := bufio.NewScanner(stdin) + go func() { + for scanner.Scan() { + t := scanner.Text() + if t == "exit" { + close(done) + } + ch <- t + } + }() +} diff --git a/kadai3-1/yoheimiyamoto/pingpong/pingpong_test.go b/kadai3-1/yoheimiyamoto/pingpong/pingpong_test.go new file mode 100644 index 0000000..dd4e821 --- /dev/null +++ b/kadai3-1/yoheimiyamoto/pingpong/pingpong_test.go @@ -0,0 +1 @@ +package pingpong diff --git a/kadai3-1/yoheimiyamoto/pingpong/result.go b/kadai3-1/yoheimiyamoto/pingpong/result.go new file mode 100644 index 0000000..7a39a72 --- /dev/null +++ b/kadai3-1/yoheimiyamoto/pingpong/result.go @@ -0,0 +1,29 @@ +package pingpong + +import "fmt" + +type result struct { + correct int + incorrect int +} + +func (r *result) addCorrect() { + r.correct++ +} + +func (r *result) addIncorrect() { + r.incorrect++ +} + +func (r result) rate() float32 { + if r.correct == 0 { + return 0 + } + sum := float32(r.correct) + float32(r.incorrect) + return float32(r.correct) / sum * 100 +} + +func (r result) String() string { + sum := r.correct + r.incorrect + return fmt.Sprintf(`正解率: %.2f %%(%d/%d)`, r.rate(), r.correct, sum) +} diff --git a/kadai3-1/yoheimiyamoto/pingpong/result_test.go b/kadai3-1/yoheimiyamoto/pingpong/result_test.go new file mode 100644 index 0000000..b7bc305 --- /dev/null +++ b/kadai3-1/yoheimiyamoto/pingpong/result_test.go @@ -0,0 +1,14 @@ +package pingpong + +import ( + "fmt" + "testing" +) + +func TestResult(t *testing.T) { + var r result + r.addCorrect() + r.addCorrect() + r.addIncorrect() + fmt.Println(r) +} From 3bae4ae75ba0d504b986bbbd1161ebd83110564f Mon Sep 17 00:00:00 2001 From: YoheiMiyamoto Date: Mon, 26 Nov 2018 07:43:13 +0900 Subject: [PATCH 2/5] update --- kadai3-1/yoheimiyamoto/main.go | 2 +- kadai3-1/yoheimiyamoto/pingpong/pingpong.go | 71 +++++++++++-------- kadai3-1/yoheimiyamoto/pingpong/result.go | 29 -------- .../yoheimiyamoto/pingpong/result_test.go | 14 ---- kadai3-1/yoheimiyamoto/pingpong/score.go | 38 ++++++++++ 5 files changed, 82 insertions(+), 72 deletions(-) delete mode 100644 kadai3-1/yoheimiyamoto/pingpong/result.go delete mode 100644 kadai3-1/yoheimiyamoto/pingpong/result_test.go create mode 100644 kadai3-1/yoheimiyamoto/pingpong/score.go diff --git a/kadai3-1/yoheimiyamoto/main.go b/kadai3-1/yoheimiyamoto/main.go index ab510cf..4ada1bb 100644 --- a/kadai3-1/yoheimiyamoto/main.go +++ b/kadai3-1/yoheimiyamoto/main.go @@ -8,5 +8,5 @@ import ( func main() { words := []string{"one", "two", "three"} - pingpong.Play(os.Stdin, os.Stdout, words) + pingpong.Play(os.Stdin, words) } diff --git a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go index 2c0294b..6282fae 100644 --- a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go +++ b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go @@ -3,55 +3,70 @@ package pingpong import ( "bufio" "fmt" + "io" "os" + "time" ) // Play ... // words -> 出題するワード一覧 -func Play(stdin, stdout *os.File, words []string) { - fmt.Println("ゲームスタート!\nゲームを途中で終了する場合はexitを入力してください。") +func Play(w io.Writer, words []string) { inputCh := make(chan string) - done := make(chan struct{}) - var r result - input(os.Stdin, inputCh, done) - var count int + inputDone := make(chan struct{}, 1) + input(os.Stdin, inputCh, inputDone) + + var s score + + fmt.Fprintln(w, "ゲームスタート!") +GAME: for { - word := words[count] - fmt.Println(word) + // wordsをすべて回答したらゲームを終了させる + if s.count() == (len(words) - 1) { + break GAME + } + + word := words[s.count()] + fmt.Fprintln(w, word) select { - case a := <-inputCh: - if a == word { - fmt.Fprintln(stdout, "正解!") - r.addCorrect() + case i := <-inputCh: + if i == word { + fmt.Fprintln(w, "正解!") + s.addCorrect() } else { - fmt.Fprintln(stdout, "不正解!") - r.addIncorrect() + fmt.Fprintln(w, "不正解!") + s.addIncorrect() } - if count == (len(words) - 1) { - fmt.Println(r) - os.Exit(0) - } - count++ - case <-done: - fmt.Fprintln(stdout, "終了します。") - fmt.Println(r) - os.Exit(0) + case <-time.After(5 * time.Second): + break GAME } } + close(inputDone) // inputのチャネルを閉じる + fmt.Fprintln(w, "タイムアウト。ゲーム終了") + fmt.Println(s.Result()) } // 標準入力から受け取ったテキストをchチャネルに送信。 -// 標準入力から「exit」というワードを受け取った場合は、doneチャネルをcloseする。 -func input(stdin *os.File, ch chan<- string, done chan<- struct{}) { +func input(stdin *os.File, ch chan<- string, done <-chan struct{}) { scanner := bufio.NewScanner(stdin) go func() { for scanner.Scan() { t := scanner.Text() - if t == "exit" { - close(done) - } ch <- t } }() + + // ゲームが終了した場合、inputも終了させる。 + go func() { + select { + case <-done: + return + } + }() + + // 上記を以下のようにgoroutine使わずに記述するとゲームがフリーズしてしまう理由が理解できていないです。 + // select { + // case <-done: + // return + // } } diff --git a/kadai3-1/yoheimiyamoto/pingpong/result.go b/kadai3-1/yoheimiyamoto/pingpong/result.go deleted file mode 100644 index 7a39a72..0000000 --- a/kadai3-1/yoheimiyamoto/pingpong/result.go +++ /dev/null @@ -1,29 +0,0 @@ -package pingpong - -import "fmt" - -type result struct { - correct int - incorrect int -} - -func (r *result) addCorrect() { - r.correct++ -} - -func (r *result) addIncorrect() { - r.incorrect++ -} - -func (r result) rate() float32 { - if r.correct == 0 { - return 0 - } - sum := float32(r.correct) + float32(r.incorrect) - return float32(r.correct) / sum * 100 -} - -func (r result) String() string { - sum := r.correct + r.incorrect - return fmt.Sprintf(`正解率: %.2f %%(%d/%d)`, r.rate(), r.correct, sum) -} diff --git a/kadai3-1/yoheimiyamoto/pingpong/result_test.go b/kadai3-1/yoheimiyamoto/pingpong/result_test.go deleted file mode 100644 index b7bc305..0000000 --- a/kadai3-1/yoheimiyamoto/pingpong/result_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package pingpong - -import ( - "fmt" - "testing" -) - -func TestResult(t *testing.T) { - var r result - r.addCorrect() - r.addCorrect() - r.addIncorrect() - fmt.Println(r) -} diff --git a/kadai3-1/yoheimiyamoto/pingpong/score.go b/kadai3-1/yoheimiyamoto/pingpong/score.go new file mode 100644 index 0000000..9e521de --- /dev/null +++ b/kadai3-1/yoheimiyamoto/pingpong/score.go @@ -0,0 +1,38 @@ +package pingpong + +import "fmt" + +// 正解、不正解のスコアをカウント +type score struct { + correct int + incorrect int +} + +// 正解をカウントアップ +func (s *score) addCorrect() { + s.correct++ +} + +// 不正解をカウントアップ +func (s *score) addIncorrect() { + s.incorrect++ +} + +func (s *score) count() int { + return s.correct + s.incorrect +} + +// 正解率の算出 +func (s score) rate() float32 { + if s.correct == 0 { + return 0 + } + sum := float32(s.correct) + float32(s.incorrect) + return float32(s.correct) / sum * 100 +} + +// 結果を出力 +func (s score) Result() string { + sum := s.correct + s.incorrect + return fmt.Sprintf(`正解率: %.2f %%(%d/%d)`, s.rate(), s.correct, sum) +} From 1b420e19321f188fd1a7c49636a257a41e71902e Mon Sep 17 00:00:00 2001 From: YoheiMiyamoto Date: Mon, 26 Nov 2018 07:52:26 +0900 Subject: [PATCH 3/5] update --- kadai3-1/yoheimiyamoto/main.go | 3 ++- kadai3-1/yoheimiyamoto/pingpong/pingpong.go | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kadai3-1/yoheimiyamoto/main.go b/kadai3-1/yoheimiyamoto/main.go index 4ada1bb..a7ee9df 100644 --- a/kadai3-1/yoheimiyamoto/main.go +++ b/kadai3-1/yoheimiyamoto/main.go @@ -8,5 +8,6 @@ import ( func main() { words := []string{"one", "two", "three"} - pingpong.Play(os.Stdin, words) + pingpong.Play(os.Stdin, os.Stdout, words) + } diff --git a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go index 6282fae..68d4522 100644 --- a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go +++ b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go @@ -4,20 +4,19 @@ import ( "bufio" "fmt" "io" - "os" "time" ) // Play ... // words -> 出題するワード一覧 -func Play(w io.Writer, words []string) { +func Play(r io.Reader, w io.Writer, words []string) { inputCh := make(chan string) inputDone := make(chan struct{}, 1) - input(os.Stdin, inputCh, inputDone) + input(r, inputCh, inputDone) var s score - fmt.Fprintln(w, "ゲームスタート!") + fmt.Fprintln(w, "ゲームスタート!制限時間は1分") GAME: for { // wordsをすべて回答したらゲームを終了させる @@ -47,8 +46,8 @@ GAME: } // 標準入力から受け取ったテキストをchチャネルに送信。 -func input(stdin *os.File, ch chan<- string, done <-chan struct{}) { - scanner := bufio.NewScanner(stdin) +func input(r io.Reader, ch chan<- string, done <-chan struct{}) { + scanner := bufio.NewScanner(r) go func() { for scanner.Scan() { t := scanner.Text() From 5a62fcdc0dc5b483cb3069bcb136b08c1ab2c5d5 Mon Sep 17 00:00:00 2001 From: YoheiMiyamoto Date: Mon, 26 Nov 2018 07:59:15 +0900 Subject: [PATCH 4/5] update --- kadai3-1/yoheimiyamoto/main.go | 2 +- kadai3-1/yoheimiyamoto/pingpong/pingpong.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kadai3-1/yoheimiyamoto/main.go b/kadai3-1/yoheimiyamoto/main.go index a7ee9df..86f67f1 100644 --- a/kadai3-1/yoheimiyamoto/main.go +++ b/kadai3-1/yoheimiyamoto/main.go @@ -7,7 +7,7 @@ import ( ) func main() { - words := []string{"one", "two", "three"} + words := []string{"one", "two", "three", "four", "five"} pingpong.Play(os.Stdin, os.Stdout, words) } diff --git a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go index 68d4522..a075952 100644 --- a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go +++ b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go @@ -16,7 +16,7 @@ func Play(r io.Reader, w io.Writer, words []string) { var s score - fmt.Fprintln(w, "ゲームスタート!制限時間は1分") + fmt.Fprintln(w, "ゲームスタート!制限時間は5秒!") GAME: for { // wordsをすべて回答したらゲームを終了させる From 5a272ef5266918a2a2dbbf1295b3bc11dc1b262b Mon Sep 17 00:00:00 2001 From: yoheimiyamoto Date: Thu, 29 Nov 2018 18:53:48 +0900 Subject: [PATCH 5/5] Update pingpong.go --- kadai3-1/yoheimiyamoto/pingpong/pingpong.go | 68 ++++++++++----------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go index a075952..8daa115 100644 --- a/kadai3-1/yoheimiyamoto/pingpong/pingpong.go +++ b/kadai3-1/yoheimiyamoto/pingpong/pingpong.go @@ -11,42 +11,50 @@ import ( // words -> 出題するワード一覧 func Play(r io.Reader, w io.Writer, words []string) { inputCh := make(chan string) - inputDone := make(chan struct{}, 1) - input(r, inputCh, inputDone) + scoreCh := make(chan score) - var s score + input(r, inputCh) fmt.Fprintln(w, "ゲームスタート!制限時間は5秒!") -GAME: + go game(w, words, inputCh, scoreCh) + + s := <-scoreCh + fmt.Fprintln(w, "ゲーム終了") + fmt.Fprintln(w, s.Result()) +} + +func game(w io.Writer, words []string, inputCh <-chan string, scoreCh chan<- score) { + var s score + + go func() { + select { + case <-time.After(5 * time.Second): + fmt.Fprintln(w, "タイムアウト!") + scoreCh <- s + } + }() + for { // wordsをすべて回答したらゲームを終了させる - if s.count() == (len(words) - 1) { - break GAME + if s.count() == len(words) { + scoreCh <- s + break } - word := words[s.count()] fmt.Fprintln(w, word) - - select { - case i := <-inputCh: - if i == word { - fmt.Fprintln(w, "正解!") - s.addCorrect() - } else { - fmt.Fprintln(w, "不正解!") - s.addIncorrect() - } - case <-time.After(5 * time.Second): - break GAME + i := <-inputCh + if i == word { + fmt.Fprintln(w, "正解!") + s.addCorrect() + } else { + fmt.Fprintln(w, "不正解!") + s.addIncorrect() } } - close(inputDone) // inputのチャネルを閉じる - fmt.Fprintln(w, "タイムアウト。ゲーム終了") - fmt.Println(s.Result()) } // 標準入力から受け取ったテキストをchチャネルに送信。 -func input(r io.Reader, ch chan<- string, done <-chan struct{}) { +func input(r io.Reader, ch chan<- string) { scanner := bufio.NewScanner(r) go func() { for scanner.Scan() { @@ -54,18 +62,4 @@ func input(r io.Reader, ch chan<- string, done <-chan struct{}) { ch <- t } }() - - // ゲームが終了した場合、inputも終了させる。 - go func() { - select { - case <-done: - return - } - }() - - // 上記を以下のようにgoroutine使わずに記述するとゲームがフリーズしてしまう理由が理解できていないです。 - // select { - // case <-done: - // return - // } }