From b310a1443a3cc9a065766cb7cae702d5b85bced8 Mon Sep 17 00:00:00 2001 From: Takashi Nishiyama Date: Wed, 7 Aug 2019 11:53:48 +0900 Subject: [PATCH 1/3] first commit --- kadai3/dobuzora/README.md | 9 +++ kadai3/dobuzora/cmd/type-game/main.go | 20 ++++++ kadai3/dobuzora/go.mod | 3 + kadai3/dobuzora/internal/game/game.go | 87 +++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 kadai3/dobuzora/README.md create mode 100644 kadai3/dobuzora/cmd/type-game/main.go create mode 100644 kadai3/dobuzora/go.mod create mode 100644 kadai3/dobuzora/internal/game/game.go diff --git a/kadai3/dobuzora/README.md b/kadai3/dobuzora/README.md new file mode 100644 index 0000000..2210873 --- /dev/null +++ b/kadai3/dobuzora/README.md @@ -0,0 +1,9 @@ +題課3-1 +=== + +タイピングゲームを作ろう +- 標準出力に英単語を出す +- 標準入力から1文字受け取る +- 制限時間内に何問解けたかを表示する + + diff --git a/kadai3/dobuzora/cmd/type-game/main.go b/kadai3/dobuzora/cmd/type-game/main.go new file mode 100644 index 0000000..a16c28a --- /dev/null +++ b/kadai3/dobuzora/cmd/type-game/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "os" + + "github.com/gopherdojo/dojo6/kadai3/dobuzora/internal/game" +) + +const timeLimit = 10 + +var ( + reader = os.Stdin + writer = os.Stdout + questions = []string{"public", "void", "func", "return", "continue"} +) + +func main() { + g := game.New(reader, writer, timeLimit, questions) + g.Play() +} diff --git a/kadai3/dobuzora/go.mod b/kadai3/dobuzora/go.mod new file mode 100644 index 0000000..42ccb50 --- /dev/null +++ b/kadai3/dobuzora/go.mod @@ -0,0 +1,3 @@ +module github.com/gopherdojo/dojo6/kadai3/dobuzora + +go 1.12 diff --git a/kadai3/dobuzora/internal/game/game.go b/kadai3/dobuzora/internal/game/game.go new file mode 100644 index 0000000..1790a27 --- /dev/null +++ b/kadai3/dobuzora/internal/game/game.go @@ -0,0 +1,87 @@ +package game + +import ( + "bufio" + "context" + "fmt" + "io" + "time" +) + +// ゲームの情報を管理 +type Game struct { + r io.Reader + w io.Writer + timeLimit time.Duration + questions []string + answerNum int + correctAnswerNum int +} + +func New(reader io.Reader, writer io.Writer, timeLimit time.Duration, questions []string) *Game { + return &Game{ + r: reader, + w: writer, + timeLimit: timeLimit, + questions: questions, + } +} + +func (gm *Game) Play() { + gm.displayRule() + gm.playGame() +} + +func (gm *Game) displayRule() { + fmt.Fprintf(gm.w, "画面に表示される英単語を入力しましょう!") + fmt.Fprintf(gm.w, "制限時間は%dです\n", gm.timeLimit) +} + +func (gm *Game) playGame() { + ctx, cancel := context.WithTimeout(context.Background(), gm.timeLimit*time.Second) + defer cancel() + + ch := gm.input() + +gameLoop: + for i := 0; i < len(gm.questions); i++ { + question := gm.questions[i] + fmt.Fprintf(gm.w, "%d問目: %s\n", i+1, question) + fmt.Fprint(gm.w, ">") + + var in string + var ok bool + select { + case in, ok = <-ch: + if !ok { + break gameLoop + } + gm.answerNum++ + case <-ctx.Done(): + break gameLoop + } + + if in == question { + gm.correctAnswerNum++ + fmt.Fprint(gm.w, "正解!") + } else { + fmt.Fprint(gm.w, "不正解...") + } + fmt.Fprintf(gm.w, " 現在の正答率:%d/%d\n", gm.correctAnswerNum, gm.answerNum) + } +} + +func (gm *Game) displayResult() { +} + +func (gm *Game) input() <-chan string { + ch := make(chan string) + go func() { + s := bufio.NewScanner(gm.r) + for s.Scan() { + ch <- s.Text() + } + close(ch) + }() + return ch +} From 1d7177f450a4b2e9abbe39a13374e7f6ebacd933 Mon Sep 17 00:00:00 2001 From: Takashi Nishiyama Date: Wed, 7 Aug 2019 12:07:23 +0900 Subject: [PATCH 2/3] add .gitignore --- kadai3/dobuzora/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 kadai3/dobuzora/.gitignore diff --git a/kadai3/dobuzora/.gitignore b/kadai3/dobuzora/.gitignore new file mode 100644 index 0000000..796a479 --- /dev/null +++ b/kadai3/dobuzora/.gitignore @@ -0,0 +1 @@ +_bin From 00191ca0642bdad8d1f40a4e24aaadcaeb730374 Mon Sep 17 00:00:00 2001 From: Takashi Nishiyama Date: Wed, 7 Aug 2019 16:12:24 +0900 Subject: [PATCH 3/3] add shuffle function --- kadai3/dobuzora/README.md | 7 +++++++ kadai3/dobuzora/cmd/type-game/main.go | 2 +- kadai3/dobuzora/internal/game/game.go | 29 ++++++++++++++++++++++----- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/kadai3/dobuzora/README.md b/kadai3/dobuzora/README.md index 2210873..3af26af 100644 --- a/kadai3/dobuzora/README.md +++ b/kadai3/dobuzora/README.md @@ -6,4 +6,11 @@ - 標準入力から1文字受け取る - 制限時間内に何問解けたかを表示する +## Install +``` +export GOBIN=`pwd`/_bin +go install github.com/gopherdojo/dojo6/kadai3/dobuzora/cmd/type-game +_bin/cmd +``` + diff --git a/kadai3/dobuzora/cmd/type-game/main.go b/kadai3/dobuzora/cmd/type-game/main.go index a16c28a..a1fa301 100644 --- a/kadai3/dobuzora/cmd/type-game/main.go +++ b/kadai3/dobuzora/cmd/type-game/main.go @@ -11,7 +11,7 @@ const timeLimit = 10 var ( reader = os.Stdin writer = os.Stdout - questions = []string{"public", "void", "func", "return", "continue"} + questions = []string{"public", "void", "func", "return", "continue", "for", "go", "float"} ) func main() { diff --git a/kadai3/dobuzora/internal/game/game.go b/kadai3/dobuzora/internal/game/game.go index 1790a27..5abae52 100644 --- a/kadai3/dobuzora/internal/game/game.go +++ b/kadai3/dobuzora/internal/game/game.go @@ -1,3 +1,6 @@ +/* +Package game implements typing game for terminal. +*/ package game import ( @@ -5,10 +8,10 @@ import ( "context" "fmt" "io" + "math/rand" "time" ) -// ゲームの情報を管理 type Game struct { r io.Reader w io.Writer @@ -18,6 +21,7 @@ type Game struct { correctAnswerNum int } +// New for game package func New(reader io.Reader, writer io.Writer, timeLimit time.Duration, questions []string) *Game { return &Game{ r: reader, @@ -27,18 +31,23 @@ func New(reader io.Reader, writer io.Writer, timeLimit time.Duration, questions } } +// Play is to start type game. func (gm *Game) Play() { gm.displayRule() + gm.shuffleQuestion() gm.playGame() } +// displayRule is to display rules of type game. func (gm *Game) displayRule() { fmt.Fprintf(gm.w, "画面に表示される英単語を入力しましょう!") fmt.Fprintf(gm.w, "制限時間は%dです\n", gm.timeLimit) } +// playGame is type-game core logic. func (gm *Game) playGame() { - ctx, cancel := context.WithTimeout(context.Background(), gm.timeLimit*time.Second) + bc := context.Background() + ctx, cancel := context.WithTimeout(bc, gm.timeLimit*time.Second) defer cancel() ch := gm.input() @@ -71,15 +80,25 @@ gameLoop: } } +// displayResult is to display the result of type game. func (gm *Game) displayResult() { } +// shuffleQuestion is to shuffle given questions of typing game. +func (gm *Game) shuffleQuestion() { + n := len(gm.questions) + for i := n - 1; i >= 0; i-- { + j := rand.Intn(i + 1) + gm.questions[i], gm.questions[j] = gm.questions[j], gm.questions[i] + } +} + func (gm *Game) input() <-chan string { ch := make(chan string) go func() { - s := bufio.NewScanner(gm.r) - for s.Scan() { - ch <- s.Text() + sc := bufio.NewScanner(gm.r) + for sc.Scan() { + ch <- sc.Text() } close(ch) }()