Skip to content

Commit

Permalink
タイピングゲームの実装
Browse files Browse the repository at this point in the history
  • Loading branch information
simady committed Aug 6, 2019
1 parent 1b40d34 commit ef1325d
Show file tree
Hide file tree
Showing 11 changed files with 585 additions and 0 deletions.
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 {
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() {
s := bufio.NewScanner(gm.r)
for s.Scan() {
ch <- s.Text()
}
close(ch)
}()
return ch
}
Loading

0 comments on commit ef1325d

Please sign in to comment.