Skip to content

kadai3-1-en-ken #29

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 8 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
5 changes: 5 additions & 0 deletions kadai3/en-ken/kadai3/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

var Execute = execute

var InputRoutine = inputRoutine
63 changes: 63 additions & 0 deletions kadai3/en-ken/kadai3/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package main

import (
"bufio"
"fmt"
"io"
"os"
"time"

typing "github.com/gopherdojo/dojo6/kadai3/en-ken"
)

func main() {
const timeoutSec = 10
textDict := []string{"foo", "bar", "baz", "qux"}
t := typing.NewTyping(textDict)

chInput := inputRoutine(os.Stdin)
chFinish := time.After(time.Duration(timeoutSec) * time.Second)

execute(chInput, chFinish, os.Stdout, t)
}

// Typing is interface to typing.Typing
type Typing interface {
GetNextText() string
IsCorrect(input string) bool
}

func execute(chInput <-chan string, chFinish <-chan time.Time, stdout io.Writer, t Typing) {

score := 0
for i := 1; ; i++ {
fmt.Fprintf(stdout, "[%03d]: %v\n", i, t.GetNextText())
fmt.Fprint(stdout, "type>>")
select {
case text := <-chInput:
if t.IsCorrect(text) {
score++
fmt.Fprintln(stdout, "Correct!")
} else {
fmt.Fprintln(stdout, "Miss!")
}
case <-chFinish:
fmt.Fprintln(stdout, "\nTime's up!!")
fmt.Fprintf(stdout, "You Scored: %v\n", score)
return
}
}
}

func inputRoutine(r io.Reader) <-chan string {
ch := make(chan string)

go func() {
s := bufio.NewScanner(r)
for s.Scan() {
ch <- s.Text()
}
}()

return ch
}
44 changes: 44 additions & 0 deletions kadai3/en-ken/kadai3/main_mock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main_test

import (
"io"
)

//Stdin
type StdinMock struct {
i int
input []string
}

func (stdin *StdinMock) Read(p []byte) (n int, err error) {
if stdin.i >= len(stdin.input) {
return 0, io.EOF
}
b := []byte(stdin.input[stdin.i] + "\n") //Scanが回るようにLF追加
copy(p, b)
stdin.i++
return len(b), nil
}

//Stdout
type StdoutMock struct {
output []string
}

func (stdout *StdoutMock) Write(p []byte) (n int, err error) {
str := string(p)
stdout.output = append(stdout.output, str)
return len(str), nil
}

//Typing
type TypingMock struct {
}

func (typ *TypingMock) GetNextText() string {
return "FOO"
}

func (typ *TypingMock) IsCorrect(input string) bool {
return "FOO" == input
}
77 changes: 77 additions & 0 deletions kadai3/en-ken/kadai3/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package main_test

import (
"bytes"
"testing"
"time"

main "github.com/gopherdojo/dojo6/kadai3/en-ken/kadai3"
)

func TestInputRoutine(t *testing.T) {
input := []string{"foo", "bar", "baz", "qux"}
stdin := &StdinMock{
i: 0,
input: input,
}

ch := main.InputRoutine(stdin)

for _, expected := range input {
actual := <-ch
if actual != expected {
t.Errorf("expected:%v, actual:%v", expected, actual)
}
}
}

func TestExecute(t *testing.T) {
chInput := make(chan string, 3)
chFinish := make(chan time.Time, 1)

scenario := []struct {
inputText string
time time.Time
}{
{
inputText: "FOO",
},
{
inputText: "BAR",
},
{
inputText: "FOO",
},
{
time: time.Now(),
},
}

buf := bytes.NewBufferString("")
typ := &TypingMock{}

go func() {
for _, s := range scenario {
time.Sleep(100 * time.Millisecond) //DASAI
if s.inputText != "" {
chInput <- s.inputText
}
if !s.time.IsZero() {
chFinish <- s.time
}
}
}()
main.Execute(chInput, chFinish, buf, typ)

expected := []byte("" +
"[001]: FOO\n" + "type>>" + "Correct!\n" +
"[002]: FOO\n" + "type>>" + "Miss!\n" +
"[003]: FOO\n" + "type>>" + "Correct!\n" +
"[004]: FOO\n" + "type>>" +
"\nTime's up!!\n" +
"You Scored: 2\n")

if bytes.Compare(buf.Bytes(), expected) != 0 {
t.Errorf("[expected]:\n%s\n[actual]:\n%s", expected, buf.Bytes())
}
}
14 changes: 14 additions & 0 deletions kadai3/en-ken/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# 課題3

## タイピングゲームを作ろう

- [x] 標準出力に英単語を出す(出すものは自由)
- [x] 標準入力から1行受け取る
- [x] 制限時間内に何問解けたか表示する

## 使い方

```go
go get github.com/gopherdojo/dojo6/kadai3/en-ken/kadai3
kadai3
```
33 changes: 33 additions & 0 deletions kadai3/en-ken/typing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package typing

import (
"math/rand"
"time"
)

// Typing is the class to judge input
type Typing struct {
dict []string
nextText string
}

// NewTyping is a constructor
func NewTyping(textDict []string) *Typing {
rand.Seed(time.Now().UnixNano())

return &Typing{
dict: textDict,
}
}

// GetNextText returns next text
func (t *Typing) GetNextText() string {
i := rand.Int() % len(t.dict)
t.nextText = t.dict[i]
return t.nextText
}

// IsCorrect judges if input is correct or not.
func (t *Typing) IsCorrect(inputText string) bool {
return t.nextText == inputText
}
46 changes: 46 additions & 0 deletions kadai3/en-ken/typing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package typing_test

import (
"testing"

typing "github.com/gopherdojo/dojo6/kadai3/en-ken"
)

var dict = []string{"ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZ"}

func contains(s string) bool {
for _, v := range dict {
if v == s {
return true
}
}
return false
}

func TestTypingCanGetNextText(t *testing.T) {
typ := typing.NewTyping(dict)
for i := 0; i < 100; i++ {
txt := typ.GetNextText()
if !contains(txt) {
t.Errorf("actual: %v\n", txt)
}
}
}

func TestTypingIsCorrect(t *testing.T) {
typ := typing.NewTyping(dict)
txt := typ.GetNextText()

if !typ.IsCorrect(txt) {
t.Errorf("IsCorrect() must be true")
}
}

func TestTypingIsCorrectFailed(t *testing.T) {
typ := typing.NewTyping(dict)
typ.GetNextText()

if typ.IsCorrect("YZZ") {
t.Errorf("IsCorrect() must be false")
}
}