Skip to content
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

Kadai3-1-simady #26

Open
wants to merge 1 commit 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
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# GoLand
.idea/*
.env
35 changes: 35 additions & 0 deletions kadai3/simady/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## 課題内容
タイピングゲームを作ろう
- 標準出力に英単語を出す(出すものは自由)
- 標準入力から1行受け取る
- 制限時間内に何問解けたか表示する

## 実行例
```$xslt
$ typing-game
【タイピングゲーム】画面に表示される英単語をできるだけ多く入力しましょう!
制限時間は10秒です。
1問目: apple
>apple
正解! 現在の正答率:1/1
2問目: bake
>bake
正解! 現在の正答率:2/2
3問目: cup
>cup
正解! 現在の正答率:3/3
4問目: dog
>cat
不正解... 現在の正答率:3/4
5問目: egg
>
タイムアップ!
***
4問中3問正解
***
お疲れ様でした!
```

## その他
- 制限時間や問題等が固定になっているので可変にしたい
- テストパッケージを分けたい
111 changes: 111 additions & 0 deletions kadai3/simady/gamemaster/gamemaster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package gamemaster

import (
"bufio"
"context"
"fmt"
"io"
"time"
)

type GameMaster interface {
Play()
}

type gameMaster struct {
// 入力元
r io.Reader
// 出力先
w io.Writer
// 制限時間(分)
timeLimit time.Duration
// 問題
problems []string
// 回答数
answerNum int
// 正答数
correctAnswerNum int
}

// New GameMasterを生成する.
func New(reader io.Reader, writer io.Writer, timeLimit time.Duration, problems []string) GameMaster {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

引数はもっと短くてよいのでは?

return &gameMaster{
r: reader,
w: writer,
timeLimit: timeLimit,
problems: problems,
}
}

func (gm *gameMaster) Play() {
gm.displayRule()
gm.game()
gm.displayResult()
}

// displayRule ルールを表示する.
func (gm *gameMaster) displayRule() {
fmt.Fprintln(gm.w, "【タイピングゲーム】画面に表示される英単語をできるだけ多く入力しましょう!")
fmt.Fprintf(gm.w, "制限時間は%d秒です。\n", gm.timeLimit)
}

// game ゲームを行う.
func (gm *gameMaster) game() {
ctx, cancel := context.WithTimeout(context.Background(), gm.timeLimit*time.Second)
defer cancel()

ch := gm.input()

gameLoop:
for i := 0; i < len(gm.problems); i++ {
problem := gm.problems[i]
fmt.Fprintf(gm.w, "%d問目: %s\n", i+1, problem)
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 == problem {
gm.correctAnswerNum++
fmt.Fprint(gm.w, "正解!")
} else {
fmt.Fprint(gm.w, "不正解...")
}
fmt.Fprintf(gm.w, " 現在の正答率:%d/%d\n", gm.correctAnswerNum, gm.answerNum)
}
}

// displayResult 結果を表示する.
func (gm *gameMaster) displayResult() {
fmt.Fprintln(gm.w)
if gm.answerNum == len(gm.problems) {
fmt.Fprintln(gm.w, "全問回答しました!")
} else {
fmt.Fprintln(gm.w, "タイムアップ!")
}
fmt.Fprintln(gm.w, "***")
fmt.Fprintf(gm.w, "%d問中%d問正解\n", gm.answerNum, gm.correctAnswerNum)
fmt.Fprintln(gm.w, "***")
fmt.Fprintln(gm.w, "お疲れ様でした!")
}

func (gm *gameMaster) input() <-chan string {
ch := make(chan string)
go func() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

プログラム終了時にはこのゴールーチンが閉じられるがそれ以外では閉じられないので注意。

s := bufio.NewScanner(gm.r)
for s.Scan() {
ch <- s.Text()
}
close(ch)
}()
return ch
}
Loading