LoginSignup
11
6

More than 3 years have passed since last update.

Go 言語で湯婆婆を実装してみる

Posted at

Javaで湯婆婆を実装してみる@Nemesis 様)というのがバズっていたので、
完全に便乗ですが、せっかくだし面白そうなので Go言語で Go婆婆 を実装してみます。

実装

main.go
package main

import (
    "bufio"
    "fmt"
    "math/rand"
    "os"
    "strings"
    "time"
)

func main() {
    fmt.Println("契約書だよ。そこに名前を書きな。")

    stdin := bufio.NewScanner(os.Stdin)
    stdin.Scan()
    name := stdin.Text()
    fmt.Printf("フン。%sというのかい。贅沢な名だねぇ。\n", name)

    nameArray := strings.Split(name, "")
    rand.Seed(time.Now().UnixNano())
    newname := nameArray[rand.Intn(len(nameArray))]

    fmt.Printf("今からお前の名前は%sだ。いいかい、%sだよ。分かったら返事をするんだ、%s!!\n", newname, newname, newname)
}

Go のランタイムがあれば main.go を実行すればそのまま動きます。

$ go run main.go
契約書だよ。そこに名前を書きな。
山田太郎
フン。山田太郎というのかい。贅沢な名だねぇ。
今からお前の名前は山だ。いいかい、山だよ。分かったら返事をするんだ、山!!

コード解説

解説するほど難しいコードではないような気がしますが一応。

標準出力

組み込みの fmt パッケージを使うだけです。

fmt.Println("契約書だよ。そこに名前を書きな。")

標準入力

bufio パッケージを使ってます。
Go での標準入力のやり方は複数あって、fmt.Scan を使うのが一番コード量が少ないんですが、
未入力のリターンを受け付けないので不採用(未入力でのクラッシュを再現したかったので)。

stdin := bufio.NewScanner(os.Stdin)
stdin.Scan()
name := stdin.Text()

名前を奪う

標準入力から受け取った文字列を split で配列に変換して、乱数を利用してインデックス指定で1文字だけ抽出します。
乱数の作成には math/rand を利用しています。

nameArray := strings.Split(name, "")
rand.Seed(time.Now().UnixNano())
newname := nameArray[rand.Intn(len(nameArray))]

クラッシュ

標準入力で何も入力しないと panic します。
本家でもクラッシュさせてたので再現させてみました。
rand.Intn の引数に 0 を指定するなというエラーですね。

panic: invalid argument to Intn

goroutine 1 [running]:
math/rand.(*Rand).Intn(0xc000058180, 0x0, 0x1188ce0)
        /usr/local/opt/go/libexec/src/math/rand/rand.go:169 +0x9c
math/rand.Intn(...)
        /usr/local/opt/go/libexec/src/math/rand/rand.go:337
main.main()
        /Users/nakaya/go/src/yubaba/main.go:22 +0x2ad
exit status 2

ちなみに、クラッシュさせないかつ空文字のみの入力を受け付けないようにするには以下のようにします。

main.go
package main

import (
    "bufio"
    "fmt"
    "math/rand"
    "os"
    "strings"
    "time"
)

func main() {
    var name string
    for len(strings.TrimSpace(name)) == 0 {
        fmt.Println("契約書だよ。そこに名前を書きな。")
        stdin := bufio.NewScanner(os.Stdin)
        stdin.Scan()
        name = stdin.Text()
    }
    fmt.Printf("フン。%sというのかい。贅沢な名だねぇ。\n", name)

    nameArray := strings.Split(name, "")
    rand.Seed(time.Now().UnixNano())
    newname := nameArray[rand.Intn(len(nameArray))]

    fmt.Printf("今からお前の名前は%sだ。いいかい、%sだよ。分かったら返事をするんだ、%s!!\n", newname, newname, newname)
}

何かしらの文字入力があるまで湯婆婆が延々ループします。

$ go run main.go
契約書だよ。そこに名前を書きな。

契約書だよ。そこに名前を書きな。

契約書だよ。そこに名前を書きな。

契約書だよ。そこに名前を書きな。

契約書だよ。そこに名前を書きな。
11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6