ズンドコキヨシを見かけた男子中学生がプログラミングを勉強していく話　第1話

# はじまりと Hello World!

　俺はその日Twitterを見ていて、運命を変えるツイートに出会った。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから<br>「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ！」って出力した後終了って関数作ったら満点で単位貰ってた</p>&mdash; てくも (@kumiromilk) <a href="https://twitter.com/kumiromilk/status/707437861881180160">2016年3月9日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

　なにこれ面白そう！俺もやってみたい！最近姉貴もプログラミングしてるらしいから、パソコン借りてやってみよう。おーい、姉貴ー！って、いないな、姉貴。まあいいや。後から言うことにしてパソコン借りよう。

　まずプログラミング言語ってやつがあるらしいな。JavaScriptとかRubyとか。あ、これ姉貴のノートだ。Rubyって表紙に書いてある。じゃあこのノートを見ながらRubyでやってみるか。
　なになに。

> 実行環境は整えた。確認のためにターミナルから、`ruby -v`と打ってみたら、バージョン情報が表示された。実行環境を作るのには成功したらしい。

　どれどれ、ターミナルってソフトがあった。文字を打ち込めるらしいな。じゃあとりあえず`ruby -v`と打ってみるか。

```
ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
```

　おお、どうやら入ってるっぽい。実行環境とかよくわからんけど、このパソコンにはもうRubyを動かす環境が整ってそうだな。

> 作者注：実行環境の入れ方はOSごとに違うので、自分のパソコンに合わせた実行環境の入れ方を調べてください。

　次は…？

> コードはテキストファイルで保存する。テキストファイルはテキストエディタで作る。Wordとかじゃダメ。テキストエディタはたくさんあるけど、私はAtomというテキストエディタを使うことにした。

あ、Atomってやつ見つけた。じゃあこれを使おう。

> まずは初めてのプログラム。Hello World!と表示してみる。`puts "Hello World!"
`と入力し、`Hello.rb`という名前で保存する。
Rubyのプログラムはファイル名の最後に、`.rb`をつけること。


ほうほう。

```ruby:Hello.rb
puts "Hello World!"
```


って、どこに保存すればいいんだろう？とりあえずホームフォルダの下に`ruby_programs`というフォルダを作ってそこに保存しよう。
そして、

> `cd`と打ってから、ファイルが保存されているフォルダをターミナルにドラッグアンドドロップする。

フォルダをターミナルにドラッグアンドドロップする。やってみたぞ。なんかフォルダの名前が出てきた。

```
cd ~/ruby_programs/
```

> それからリターンキーを押すと、ファイルが保存されているフォルダに移動できて、あとはそのフォルダの中のファイルを操作できるようになる。

えーと、そうするとターミナルから`ruby_programs`っていうフォルダに移動することができて、あとはそのフォルダの中のファイルをターミナルから操作できる、ってことらしいな。うむ、わからんが後回しだ。

> Rubyのプログラムを実行するには、ターミナルからファイルが保存されているフォルダに移動して、`ruby ファイル名.rb`と打ち込む。
`Hello.rb`を実行するには、`ruby Hello.rb`と入力すること。

　ほう。フォルダの移動はさっきやったので、今度は

```
ruby Hello.rb
```

と入力してみる。

```
Hello World!
```

　おお、なんかできた。こっから俺のズンドコ節が始まるわけだな！

# まずは『ズンドコ』を表示する

　じゃあ、次は『ズンドコ』って表示されるプログラムを作ってみよう。さっきの`puts "Hello World!"`のうち、表示されたのは`Hello World!`の部分だけ。じゃあこの部分だけ『ズンドコ』にしたらいいのかな。

```ruby:Zundoko.rb
puts ズンドコ
```

　よし、実行！`ruby Zundoko.rb`！あれ、なんかエラーが出た。

```
Zundoko.rb:1:in `<main>': undefined local variable or method `ズンドコ' for main:Object (NameError)
```

　え、英語？これどういう意味だ？ええと、辞書辞書。定義されてない、局所的な、変数、または、メソッド。メソッドって方法って意味か。よくわからん。よくわからんけど、俺が間違ってるんだよな。Hello.rbとZundoko.rbをよく見比べてみよう…。
 あ、`"Hello World!"`と`ズンドコ`がなんか違う！なんか点々で囲まれてるのと囲まれてないのだ。じゃあ、こうやったら動くかな。

```ruby:Zundoko.rb
puts "ズンドコ"
```

　よし、再び実行！`ruby Zundoko.rb`！

```
ズンドコ
```

　おっしゃ！思った通りうまくいった！文字を表示したいなら、`""`で囲め、ってことだな！

　ところでさっきのエラーメッセージ、なんだったんだろう？なんか変数もメソッドとやらも関係なかった気が。書き方が間違ってるだけで方法は合ってたんだから。
　でも、このパソコンは俺の心なんて読めないんだから、俺がやりたいことがどうやったら出来るか的確に教えてくれるわけないよな。パソコンなりに「多分こうじゃないですか？」って判断してメッセージを出してくれてるだけなんだから、パソコンがどう判断してこのメッセージが出てきたか考えるのが正解だな。そのためには、もっとプログラミングのことを知らねば。

# ランダムに『ズン』『ドコ』を表示する

　さて、ズンドコキヨシに必要なのは、

1. ズンとドコをランダムに出す
2. 『ズン、ズン、ズン、ズン、ドコ』が出たら、『キ・ヨ・シ！』と表示する

の二つだな。次はズンとドコをランダムに出す、に取り掛かってみよう。ええと、Rubyでランダムに表示を変えるには、と。姉貴のノートをペラペラ〜と。

> ランダムな数字を作るのには、`Random.rand`を使う。これは0.0から1.0までのランダムな数字を返す

　ふむふむ。数字じゃなくて表示を変えたいんだけどな。でもまずはいいや。
　本当にランダムな数字が出てくるのかな？ちょっと試してみよう。

```ruby:Random.rb
puts "Random.rand"
```

 えい、`ruby Random.rb`。

```
Random.rand
```

　あれ、出ない。なんでだ？今度はエラーメッセージもでてこないなぁ。つまり、俺が間違っているけどパソコン的には正しい命令を受け取っている、というパターンか。そういや`""`で囲むのは囲んだ文字を出したいときだった気が。今回、`"Random.rand"`って囲んじゃったからそのまま出てきただけか。じゃあ次はわざと間違えてみよう。それをこのパソコンはどう解釈するんだろう？

```ruby:Random.rb
puts Random.rand
```

　とう、`ruby Random.rb`。

```
0.733234825428422
```

　あれ、さっきは間違いって出たやつなのに、今度は正しく動く。いや、違うな。俺がわざと間違えてみたと思い込んでいたものなのに、パソコン的には正しい命令だった、と。
　さっきのエラーメッセージを思い出してみようか。

```
Zundoko.rb:1:in `<main>': undefined local variable or method `ズンドコ' for main:Object (NameError)
```

　これはNameErrorとも書いてあるから、ズンドコっていう名前の変数もメソッドも定義されてないって意味に受け取れる。逆に言えば、ズンドコって書いていあった部分が変数かメソッドの名前だったら正しいってことじゃないか！？
　で、今回書いた`Random.rand`ってやつは変数とメソッドのどっちだろう？うーん、わからん。ランダムな数字が入っている変数なのか、ランダムな数字を作るメソッドなのか。ちょっとこれはもう少し後で調べてみよう。とりあえず今はランダムな数字を表示できるぞ、ということで。
　何度か`ruby Random.rb`を動かしてみよう。おお、毎回値が変わる。
　
　でもやりたいことはランダムに数字を出すんじゃなくて、ランダムに『ズン』『ドコ』を出すんだぞ。これはどうやって作ればいいんだ？　
　うーん、`Random.rand`は0から1.0までの数字を返すんだよな。じゃあ、**もし**0.5未満の数字が出てきたら『ズン』で、**もし**0.5より大きい数字が出てきたら『ドコ』を出す、という仕組みで作れそうだ。

## **もし**をプログラムで表現する

　さて、この**もし**はプログラミングでどう表現するんだろう？ええと、ノートを読んでと。

> 「もしも〜だったら...しろ」というのは、`if 条件式 then ... end`で表現する。条件式が正しかったら、`then`から`end`までの間に書いてあることを実行する。 
条件式のルールは様々だが、主に以下の3つがある。
`a > b`は、aがbより大きかったら
`a < b`は、aがbより小さかったら
`a == b`は、aとbが等しかったら

　ってことか。じゃあ試しに使ってみよう。`Random.rand`が0.5より小さければいいんだから

```ruby:Zundoko.rb
if Random.rand < 0.5 then
  puts "ズン"
end
```

　とう、`ruby Zundoko.rb`。あ、何も出ない。も一回`ruby Zundoko.rb`。今度は`ズン`って出た。ランダムでズンを表示するのは出来たぞ。
　じゃあ、今度はRandom.randが0.5より大きいときには『ドコ』って表示するようにしよう。

```ruby:Zundoko.rb
if Random.rand < 0.5 then
  puts "ズン"
end
if Random.rand > 0.5 then
  puts "ドコ"
end
```

　てやっ、`ruby Zundoko.rb`。お、`ズン`って出た。も一回`ruby Zundoko.rb`。今度は`ドコ`だった。なんか楽しいなー。もうちょっと繰り返してみよう。お、また`ドコ`。`ズン`。`ドコ`。`ドコ`。。あれ、何も出ない。気のせいかな。もう一回。あれ、やっぱり何も出ない。もう一回。今度は

```
ズン
ドコ
```
が出た。何だこれ、何が間違ってるのかなー。
　ちょっと整理して考えてみよう。最初の式は、もしもRandom.randが0.5より小さかったら、ズンと表示する。次の式はもしもRandom.randが0.5より大きかったらドコと表示する。で、おかしいのはズンもドコも表示されない時と、ズンとドコ両方が表示される時。でも、ズンしか表示されない時とドコしか表示されない時はちゃんとある。
　この条件を満たしている仮説は…、もしかして`Random.rand`って一つのプログラムでずっと同じ数字なんじゃなくて、一回書かれる毎に違う数字になるってことか？ちょっと試してみよう。

```ruby:Random.rb
puts Random.rand
puts Random.rand
puts Random.rand
puts Random.rand
puts Random.rand
```

　そいや！`ruby Random.rb`！

```
0.6111804025789562
0.8667532661085872
0.34587773702102564
0.38976622350782963
0.10275974791125175
```

　おお！5回とも値が違う！とすると、パソコンに起こっていたのはこんなことだったんだ！

- `ズン`だけ表示される
 - たまたま最初の`Random.rand`が0.5より小さくて次の`Random.rand`も0.5より小さかった
- `ドコ`だけ表示される
 - たまたま最初の`Random.rand`が0.5より大きくて次の`Random.rand`も0.5より大きかった
- `ズン`と`ドコ`が表示される
 - 最初の`Random.rand`が0.5より小さくて次の`Random.rand`は0.5より大きかった
- 何も表示されない
 - 最初の`Random.rand`が0.5より大きくて次の`Random.rand`は0.5より小さかった

　さて、納得はいったぞ。しかし、だったらどうやれば上手くいくんだろう？

## 変数を学ぶ

　まず、`Random.rand`を書く回数は一回にしなければならない。でも、ifは2回書かなきゃいけない。うーん。なんか`Random.rand`の値を箱みたいなものに入れておくことができればなぁ。ちょっとノートをペラ見してみるか。おお、なんか箱の絵があるぞ。

> この箱は変数のイメージ。名前の付いているこの箱に何かを入れることを、変数に値を代入するという。
変数の名前は基本的に好きなものをつけていい。

　ふむ。とりあえずサンプルを打ち込んでみるか。

```ruby:variable.rb
variable = 3
puts variable
```

　`ruby variable.rb`っと。

```
3
```

　ふーん。これは1行目でvariableって名前の変数に3を代入して、2行目でvariableって名前の変数の中身を出力しろ、って言ってるのか。で、ノートによると変数名は基本的に自由な名前をつけられるらしいな。じゃあ、

```ruby:variable.rb
kiyoshi = 3
puts kiyoshi
```

　`ruby variable.rb`っと。

```
3
```

　うん、なんとなくわかった。

## 文字列と変数名

　じゃあこれを改造して、

```ruby:variable.rb
kiyoshi = ズン
puts kiyoshi
```

　`ruby variable.rb`っと。

```
variable.rb:1:in `<main>': undefined local variable or method `ズン' for main:Object (NameError)
```

 お、さっきと同じエラーだ。さっきは`""`で囲んだら直ったんだっけ。この`""`の意味をそろそろ知りたいぞ。

```ruby:variable.rb
kiyoshi = "ズン"
puts kiyoshi
```

 `ruby variable.rb`っと。

```
ズン
```

　おし、直った。
　ちなみに、`puts "kiyoshi"`ってやったらどうなるんだろう？試してみるか。

```ruby:variable.rb
kiyoshi = "ズン"
puts "kiyoshi"
```

　`ruby variable.rb`っと。

```
kiyoshi
```

　へー、『ズン』じゃなくて`kiyoshi`って出た。`""`の謎は深いぞ。
　ノートをペラペラ〜っと見て、`""`の箇所は、あ、あった！なになに、
> ""で囲まれた文字は文字列になる。文字列とは、文字のかたまりのこと。

　………、わからーん！
　まぁでも、`kiyoshi`っていうのは変数の名前で`"kiyoshi"`ってのは文字のかたまりで、パソコンの中では全く別物になってるんだな、きっと。`""`で囲んだら、変数の名前としての意味が失われるっぽい。だから変数の中身が表示されずに、文字列のkiyoshiが出力されたと。ふむふむ。

## Random.randは変数？メソッド？

　じゃあやりたかったことに戻ろう。Random.randの値を変数に入れて保存したい。
　と、ちょっと待てよ。Random.randって変数なのかメソッドなのか、さっき迷ったよな。これをわざわざ変数に入れる必要があるんだから、メソッドっぽい感じ。もし変数だとしたら他の数字が入れられるはずなんで、試してみるか。

```ruby:var_test.rb
Random.rand = 3
puts Random.rand
```

　うーん、とりあえず書いてみたけど、`Random.rand`って書くたびに値が変わるんだよな。変数は値を保存しておく箱なのに、その名前を書くたびに値が変わったら変数としての役割を果たしてないことになるよな。すごく、エラーが出そうです。。。とりあえず実行！`ruby var_test.rb`！

```
var_test.rb:1:in `<main>': undefined method `rand=' for Random:Class (NoMethodError)
```

　うん、エラーだった。じゃあこの`Random.rand`ってのはメソッドだと思っておこう。じゃあ改めて、Random.randの値を変数に入れて保存してみるぞ。

```ruby:random_var.rb
random_var = Random.rand

puts random_var
puts random_var
```

　これで2回とも同じ数字が出れば…！

```
0.06327292558924758
0.06327292558924758
```

　計画通り！これをさっきのzundoko.rbに応用すれば！

```ruby:zundoko.rb
random_var = Random.rand

if random_var < 0.5 then
  puts "ズン"
end
if random_var > 0.5 then
  puts "ドコ"
end
```

　今度は正しくズンドコが出るっぽいぞ！

## 境界の値

　でも、なんかちょっと気になるな、このプログラム。もしもだけど、random_varに0.5が入ってたらどう動くんだろう？ちょっと試してみようか。

```ruby:zundoko.rb
random_var = 0.5

if random_var < 0.5 then
  puts "ズン"
end
if random_var > 0.5 then
  puts "ドコ"
end
```

　`ruby zundoko.rb`、ッツターン！何も表示されないな。何度やっても結果は変わらん。これは0.5が境界の値だからなんだろうけど、そういやこの`<`とか`>`の記号とか、学校で習った意味そのままだと、より小さいとかより大きいとかっていう意味で、0.5自身は含まないんだったな。ここはプログラミングでも同じなのか。じゃあこうやって書いてみよう。

```ruby:zundoko.rb
random_var = 0.5

if random_var <= 0.5 then
  puts "ズン"
end
if random_var => 0.5 then
  puts "ドコ"
end
```

　`ruby zundoko.rb`でリターンだ！

```
zundoko_bug.rb:7: syntax error, unexpected =>, expecting keyword_then or ';' or '\n'
if random_var => 0.5 then
                ^
```

　あれ、てっきり『ズン』と『ドコ』が表示されると思ってたけどエラーだな。`=>`こんな記号はないぞと言われてる。ええと、ノートによると。。。

> aがb以下は`a <= b`、aがb以上は`a >= b`と書く。後者の書き方は数学の授業で習うものとは違うので注意すること。

　へー、なるほど。じゃあこう書いて、

```ruby:zundoko.rb
random_var = 0.5

if random_var <= 0.5 then
  puts "ズン"
end
if random_var >= 0.5 then
  puts "ドコ"
end
```

　`ruby zundoko.rb`で行ってみよ〜！

```
ズン
ドコ
```

　お、予想通り、『ズン』と『ドコ』が出た。
　じゃあ、0.5が出た時に正しく動くようにするには、上のifと下のifのどっちかで0.5を含まない記号の`>`か`<`を使ってやればいいのか。じゃあ次のように書いて。

```ruby:zundoko.rb
random_var = 0.5

if random_var < 0.5 then
  puts "ズン"
end
if random_var >= 0.5 then
  puts "ドコ"
end
```

　`ruby zundoko.rb`で暴れちゃうぞ！

```
ドコ
```

　よし、じゃあ実験のために`random_var = 0.5`と書いたところを直そう。

```ruby:zundoko.rb
random_var = Random.rand

if random_var < 0.5 then
  puts "ズン"
end
if random_var >= 0.5 then
  puts "ドコ"
end
```

　これでようやく、1つ目のズンとドコをランダムに表示する、という部分ができたぞ。

# 『ズン、ズン、ズン、ズン、ドコ』が出たら、『キ・ヨ・シ！』と表示する〜ループに挑戦〜

　次は2. 『ズン、ズン、ズン、ズン、ドコ』が出たら、『キ・ヨ・シ！』と表示する、だけど、これはどうやったらいいんだろう？そもそもどうやったら何回も『ズン』と『ドコ』を出せるんだろう？
　うーん、う〜ん、う〜〜ん…。最初のツイ主さんのTwitterにヒントがないかな？

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">さっきのキヨシ関数の実装は<br>「ズン」が出力…zunカウンターを1プラス<br>「ドコ」が出力…zunカウンターリセット<br>ってやって、zunカウンターが4の時に「ドコ」が出力されたらループ終了して「キ・ヨ・シ！！」を出力するだけだよ 簡単</p>&mdash; てくも (@kumiromilk) <a href="https://twitter.com/kumiromilk/status/707451885620498432">2016年3月9日</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

　ほうほう…。ループ、ループかぁ！それでずっとランダムに『ズン』と『ドコ』を出し続けて、条件を満たしたらループを終了すればいいのか。ちょっとループについてノートを調べてみよう。なになに、

> ループには`while`、`until`、`for`の3種類がある。ループには条件文がセットで付いてくる。その条件文をどう扱うのかで3種類を使い分ける。
- *while* 条件を満たしている間、ループし続ける。
- *until* 条件を満たすまでの間、ループし続ける。
- *for* 指定した回数だけループする。

　とな。今回使えそうなのはどれだろう？ツイートによると、zunカウンターが4の時に『ドコ』が出力されたらループ終了、とあるな。とすると、zunカウンターが4の時に『ドコ』が出力されるまでループし続ける、と言い換えられるから、*until*を使えば良さそうだ。

## カウンターを作る〜変数の足し算〜

　zunカウンターってのはどうやったらプログラミングできるだろう？さっきifの条件文を書くときには変数を使ったけれど、zunカウンターの仕組みも変数を使えば実現できるかな？
　変数って足し算できるんだろうか？そもそも足し算をプログラミングするってどうやるのかな？ちょっと実験してみよう。ここはまとめて…。

```ruby:sum.rb
answer = 1 + 2
puts answer
puts "---"

x = 1
answer = x + 3
puts answer
puts "---"

y = 4
answer = x + y
puts answer
```

　で、これの答えが、

```
3
---
4
---
5
```

と。
　なんか簡単かも。で、zunカウンターに1プラス、か。あれ、これってどう書けばいいんだろう？`=`の左はzunカウンター。でも右はどう書こう？右にzunカウンター足す1ってそのまま書けばいいのかな？わからん、実験だ！

```ruby:zun_counter.rb
zun_counter = zun_counter + 1
puts zun_counter
```

　`ruby zun_counter.rb`！

```
zun_counter.rb:1:in `<main>': undefined method `+' for nil:NilClass (NoMethodError)
```

　うん、やっぱりダメだった。だってそもそも右のzun_counterに入ってる値もわかんないんだもんなぁ。ダメに決まって…、うん？もし最初にzun_counterに入ってる値がわかったらOKだったりするのかな？
　もう一度試してみよう。

```ruby:zun_counter.rb
zun_counter = 0
zun_counter = zun_counter + 1
puts zun_counter
```

　`ruby zun_counter.rb`よもう一度！

```
1
```

　やった！できた！
　ええと、それでやりたいことは、zun_counterが4の時に『ドコ』が出たらループ終了、かぁ。とりあえずzun_counterが4になったらループ終了、と簡単化して作ってみよう。`until 条件式 do ... end`って書くらしいな。doからendの間の命令を実行するのか。ここら辺、ifの時に使ったthenからendの間の命令を実行する、ってのに似てるな。じゃあ、こう書けばいいのかな。

```ruby:zundoko.rb
until zun_counter = 4 do
  zun_counter = 0
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zun_counter = zun_counter + 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
  end
end
```

　えい`ruby zundoko.rb`。

```
zundoko.rb:1: warning: found = in conditional, should be ==
```

　お、なんかエラーだ。1行目の`=`は`==`であるべき、と。なるほど。単に`=`だと変数に値を入れるときの`=`と区別がつかないからか。ノートをちらりと。

> ※代入は`=`を、比較には`==`を使う。使い分けに注意。

かぁ。じゃあここを直して、

```ruby:zundoko.rb
until zun_counter == 4 do
  zun_counter = 0
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zun_counter = zun_counter + 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
  end
end
```

`ruby zundoko.rb`。

```
zundoko.rb:1:in `<main>': undefined local variable or method `zun_counter' for main:Object (NameError)
```

　このエラーメッセージよく出てくるなぁ。zun_counterが定義されてない。う〜ん、`zun_counter = 0`って書いてるのになぁ。もしかして条件式の中で呼び出される前に値をセットしなくちゃいけないのかな？
　困った時は実験です。

```ruby:zundoko.rb
zun_counter = 0

until zun_counter == 4 do  
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zun_counter = zun_counter + 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
  end
end
```
　いけ！実験体`ruby zundoko.rb`！

```
ズン
ドコ
ドコ
ドコ
ズン
ズン
ドコ
ズン
```

　うん！動いた！なんか面白いなぁ、ループって。
　で、これだと『ズン』が4回表示されたら終了、だな。『ズン』が4連続で出た時に終了するには、さっきのツイートを見返してみよう。ええと、『ドコ』が出力でzun_counterをリセット、ここが抜けてたのか。
　そうかあ、『ドコ』が出た時点で`zun_counter = 0`にすると、『ズン』が4連続で出ない限りzun_counterが4に届かないのか。面白いなぁ。
　じゃあそれを付け加えて、と。

```ruby:zundoko.rb
zun_counter = 0

until zun_counter == 4 do  
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zun_counter = zun_counter + 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
    zun_counter = 0
  end
end
```

　実験体2号`ruby zundoko.rb`よ！頑張れ！

```
ドコ
ズン
ドコ
ドコ
ズン
ズン
ズン
ドコ
ドコ
ズン
ズン
ズン
ズン
```

　おお、『ズン』が4連続で出て止まる、ってできてる。も一回。おお、もう一回。できてるー！なんか嬉しい。
　じゃあ次は『ズン』が4連続で出た後に『ドコ』が出力されたらループ終了、ってことだな。うん？『ズン』が4連続で出て、次に『ドコ』が出力されたら、ってどう書けばいいんだ？『ズン』が4連続で出たその次にまた『ズン』が出たら終了しないんだよな。その場合『ズン』が5回続いて出てるってことだよな。5回続いて出てる？？


## 真のループ条件

　ちょっと頭を冷やして考えよう。最初のツイートは、「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ！」って出力した後終了って書いてあった。『ズン』が4回で、『ドコ』が続いてる。
　で、『ズン』と『ドコ』のどちらかがランダムで出てくる以上、『ズン』が5回かそれ以上に続くこともあり得る。その場合をどうするかだけど、例えば「ズン」「ズン」「ズン」「ズン」「ズン」「ズン」「ドコ」みたいに『ズン』が6回続いて『ドコ』が出た場合を考えると、この中には「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が含まれている。つまり、この場合も「キ・ヨ・シ！」と出力するべきだな。
　そうすると、作るべきプログラムは『ズン』が4連続以上出力されてから『ドコ』が出たら終了、と考えるべきだ。

　となると、真のループの条件文は、**ズンが4回以上連続で出て、かつドコが出たら**となるべきだ。この**かつ**がミソだな。
　条件文の中の**かつ**というのはどう書けばいいんだろう？ノートには、

> 条件文は、『かつ』『または』で繋いで複雑な表現をすることができる。例えば`(a <= b) && (c <= d)`は、『aがb以下かつcがd以下』という意味になる。『または』の場合は`(a <= b) || (c <= d)`というように書く。括弧は数式で計算順を指定するのと同じような意味で、括弧に括られた式を先に評価する。

　とあるな。じゃあ、`(zun_counter >= 4) && (『ドコ』が出力された)`と書けばいい。この『ドコ』が出力された、というのはどう書けばいいかな？
　単純に考えて、『ズン』が出力されたら`1`を、『ドコ』が出力されたら`0`を入れる変数`zundoko`を作ればいいか。そうすると、

```ruby:zundoko.rb
zun_counter = 0
zundoko = 0

until (zun_counter >= 4) && (zundoko == 0) do
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zundoko = 1
    zun_counter = zun_counter + 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
    zundoko = 0
    zun_counter = 0
  end
end
```

　えい、`ruby zundoko.rb`！
　あれ、ひたすらにズンドコが続いていつまで経ってもプログラムが終わらない！！！！どうしたらいいんだ、姉貴〜！！ノート！なんか最後のページに大きな赤い字が！

> **プログラムがバグって終了しない時は、即座にControlキーとcを同時に押すこと。プログラムを強制終了させることができる。ダメだと感じた時はためらうな。**

　なるほど！`ctl + c`！お、終わったー。びっくりしたー。
　さて、プログラムが終わらなかったのは、普通に考えてループが終わらなかったからだよな。ちゃんと「ズン」「ズン」「ズン」「ズン」「ドコ」になってる部分があるのに終わってない。どうしてだろう？プログラムをよーく眺めて…。

　まず、「ズン」「ズン」「ズン」「ズン」「ドコ」になってるのに終わらない理由を考えよう。
　最初に、zun_counterもzundokoも0になっている。で『ズン』が出たらzun_counterは1、zundokoは1だからループが終わる条件文`(zun_counter >= 4) && (doko_counter == 0)`に合わなくて続く。
　次に『ズン』が出たらzun_counterは2、zundokoは1でやっぱり条件文に合わないから続く。3回目のズンと4回目のズンも同じ。そして最後に『ドコ』が出た時。
　ここで終わって欲しいんだけど、この時zundokoが0でzun_counterも0になる。これを条件文と比べると…。ここかぁ！zundokoは0だけどzun_counterがリセットされて0になってるから終わらないのかぁ！
　うーん、でもzun_counterは『ドコ』が表示されたらリセットしなくちゃならないんだぞ？それを考えると、どう直したらいいんだろう？

　zun_counterをリセットする条件をもっとよく考えてみよう。単純に『ドコ』が出たときじゃなくて、正確には『ズン』が4回未満連続で出て次に『ドコ』が出た時だ。
　じゃあ、『ドコ』が出てzun_counterをリセットする時にzun_counterが4未満と言うのをチェックさせたらどうだろう？

```ruby:zundoko.rb
zun_counter = 0
zundoko = 0

until (zun_counter >= 4) && (zundoko == 0) do
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zun_counter = zun_counter + 1
    zundoko = 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
    zundoko = 0
    if zun_counter < 4 then
      zun_counter = 0
    end
  end
end

```

　これを実行してみると…。やった！「ズン」「ズン」「ズン」「ズン」「ドコ」が出たらちゃんと終わる！
　じゃあ最後に"き・よ・し！"を出力する部分を含めて…。

```ruby:zundoko.rb
zun_counter = 0
zundoko = 0

until (zun_counter >= 4) && (zundoko == 0) do
  random_var = Random.rand

  if random_var < 0.5 then
    puts "ズン"
    zun_counter = zun_counter + 1
    zundoko = 1
  end
  if random_var >= 0.5 then
    puts "ドコ"
    zundoko = 0
    if zun_counter < 4 then
      zun_counter = 0
    end
  end
end

puts "き・よ・し！"
```

で、実行してみたら

```
ドコ
ドコ
ズン
ドコ
ドコ
ドコ
ズン
ズン
ズン
ズン
ドコ
き・よ・し！
```

　やったー！！長かったけど出来たー！！！疲れたけど楽しかったぞー！！！

「あんた、わたしのパソコンで何してるの？」
「あ、姉貴！」
「ターミナルなんか開いて。もしかしてプログラミング？」
「うん！ズンドコキヨシができたんだぜ。すごいだろ！」
「へぇー、あのツイッターで有名な。ちょっと見せてみなさいよ」
「おう！」
「ふーん……。まあ初めてにしちゃすごいんじゃない？」
「なんか言いたいことがありそうだな、姉貴」
「そりゃあるわよ」
「姉貴はプログラミング詳しいのか？ノートとってたけど」
「私も勉強し始めてそんなに長いわけじゃないわよ。でも、それでもこのプログラムがまだまだだってことは分かるわ」
「そうなんだ。よかったら教えてくれないか？」
「あんたが勉強したがるなんてねぇ。いいわよ。今日はもう遅いから明日以降ね」
「了解。ありがとう」
「ふふ、覚悟しておきなさいよ」

*〜第2話に続く〜*