Skip to content

Kadai3 1 pchatsu #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions kadai3-1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

## 課題

```
タイピングゲームを作ろう
標準出力に英単語を出す(出すものは自由)
標準入力から1行受け取る
制限時間内に何問解けたか表示する
```

## 実装

* [x] `bufio.Scanner`を使って標準入力から1行ずつ読み取りチャンネルに送る。
* [x] `time.After` を使って時間が来たら知らせるチャンネルを作成。
* [x] for select を使って、タイマーのチャンネルと標準入力を受け取るチャンネルを待つ。
12 changes: 12 additions & 0 deletions kadai3-1/pchatsu/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import (
"os"

"github.com/gopherdojo/dojo3/kadai3-1/pchatsu"
)

func main() {
tg := typinggame.NewTypingGame(60, os.Stdin, os.Stdout)
tg.Play()
}
81 changes: 81 additions & 0 deletions kadai3-1/pchatsu/questions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package typinggame

var (
questions = []string{
"time",
"person",
"year",
"way",
"day",
"thing",
"man",
"world",
"life",
"hand",
"part",
"child",
"eye",
"woman",
"place",
"work",
"week",
"case",
"point",
"government",
"company",
"number",
"group",
"problem",
"fact",
"good",
"new",
"first",
"last",
"long",
"great",
"little",
"own",
"other",
"old",
"right",
"big",
"high",
"different",
"small",
"large",
"next",
"early",
"young",
"important",
"few",
"public",
"bad",
"same",
"able",
"be",
"have",
"do",
"say",
"get",
"make",
"go",
"know",
"take",
"see",
"come",
"think",
"look",
"want",
"give",
"use",
"find",
"tell",
"ask",
"work",
"seem",
"feel",
"try",
"leave",
"call",
}
)
55 changes: 55 additions & 0 deletions kadai3-1/pchatsu/typing_game.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package typinggame

import (
"bufio"
"io"
"strconv"
"time"
)

type TypingGame struct {
limitSec int
correct int
r io.Reader
w io.Writer
}

func NewTypingGame(limitSec int, r io.Reader, w io.Writer) *TypingGame {
tg := TypingGame{
limitSec: limitSec,
r: r,
w: w,
}
return &tg
}

func readAnswer(r io.Reader, ch chan<- string) {
sc := bufio.NewScanner(r)
for sc.Scan() {
ch <- sc.Text()
}
}

func (t *TypingGame) Play() {
ch := make(chan string)
go readAnswer(t.r, ch)

timer := time.After(time.Duration(t.limitSec) * time.Second)
question := questions[t.correct]

t.w.Write([]byte(question + "\n"))
LOOP:
for {
select {
case s := <-ch:
if question == s {
t.correct++
question = questions[t.correct%len(questions)]
t.w.Write([]byte(question + "\n"))
}
case <-timer:
t.w.Write([]byte("time over! correct:" + strconv.Itoa(t.correct)))
break LOOP
}
}
}
85 changes: 85 additions & 0 deletions kadai3-1/pchatsu/typing_game_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package typinggame

import (
"bytes"
"io"
"reflect"
"testing"
)

func TestNewTypingGame(t *testing.T) {
type args struct {
limitSec int
r io.Reader
w io.Writer
}
tests := []struct {
name string
args args
want *TypingGame
}{
{"#1 normal case", args{5, bytes.NewBufferString("a"), &bytes.Buffer{}}, &TypingGame{limitSec: 5, r: bytes.NewBufferString("a"), w: &bytes.Buffer{}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := &bytes.Buffer{}
if got := NewTypingGame(tt.args.limitSec, tt.args.r, w); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewTypingGame() = %v, want %v", got, tt.want)
}
})
}
}

func Test_readAnswer(t *testing.T) {
type args struct {
r io.Reader
}
tests := []struct {
name string
args args
want []string
}{
{"#1 normal case", args{bytes.NewBufferString("foo\nbar\nbaz\n")}, []string{"foo", "bar", "baz"}},
{"#2 normal case", args{bytes.NewBufferString("foo\nbar\nbaz")}, []string{"foo", "bar"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ch := make(chan string)
go readAnswer(tt.args.r, ch)
for _, w := range tt.want {
if got := <-ch; got != w {
t.Errorf("channel got = %v, want %v", got, w)
}
}
})
}
}

func TestTypingGame_Play(t *testing.T) {
// for tests
questions = []string{"foo", "bar", "baz"}

tests := []struct {
name string
r io.Reader
wantCorrect int
wantW string
}{
{"#1 normal case", bytes.NewBufferString("foo\nbar\n"), 2, "foo\nbar\nbaz\ntime over! correct:2"},
{"#2 1 mistake case", bytes.NewBufferString("foo\nbaz\nbar"), 2, "foo\nbar\nbaz\ntime over! correct:2"},
{"#3 loop case", bytes.NewBufferString("foo\nbar\nbaz\nfoo\n"), 4, "foo\nbar\nbaz\nfoo\nbar\ntime over! correct:4"},
}
for _, tt := range tests {
w := &bytes.Buffer{}
tg := NewTypingGame(1, tt.r, w)
t.Run(tt.name, func(t *testing.T) {
tg.Play()
if gotCorrect := tg.correct; gotCorrect != tt.wantCorrect {
t.Errorf("correct got = %v, want %v", gotCorrect, tt.wantW)
}
if gotW := w.String(); gotW != tt.wantW {
t.Errorf("io.Writer got = %v, want %v", gotW, tt.wantW)
}
})
}
}