はじまりと Hello World!
俺はその日Twitterを見ていて、運命を変えるツイートに出会った。
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも (@kumiromilk) 2016年3月9日
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた
なにこれ面白そう!俺もやってみたい!最近姉貴もプログラミングしてるらしいから、パソコン借りてやってみよう。おーい、姉貴ー!って、いないな、姉貴。まあいいや。後から言うことにしてパソコン借りよう。
まずプログラミング言語ってやつがあるらしいな。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
をつけること。
ほうほう。
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!
の部分だけ。じゃあこの部分だけ『ズンドコ』にしたらいいのかな。
puts ズンドコ
よし、実行!ruby Zundoko.rb
!あれ、なんかエラーが出た。
Zundoko.rb:1:in `<main>': undefined local variable or method `ズンドコ' for main:Object (NameError)
え、英語?これどういう意味だ?ええと、辞書辞書。定義されてない、局所的な、変数、または、メソッド。メソッドって方法って意味か。よくわからん。よくわからんけど、俺が間違ってるんだよな。Hello.rbとZundoko.rbをよく見比べてみよう…。
あ、"Hello World!"
とズンドコ
がなんか違う!なんか点々で囲まれてるのと囲まれてないのだ。じゃあ、こうやったら動くかな。
puts "ズンドコ"
よし、再び実行!ruby Zundoko.rb
!
ズンドコ
おっしゃ!思った通りうまくいった!文字を表示したいなら、""
で囲め、ってことだな!
ところでさっきのエラーメッセージ、なんだったんだろう?なんか変数もメソッドとやらも関係なかった気が。書き方が間違ってるだけで方法は合ってたんだから。
でも、このパソコンは俺の心なんて読めないんだから、俺がやりたいことがどうやったら出来るか的確に教えてくれるわけないよな。パソコンなりに「多分こうじゃないですか?」って判断してメッセージを出してくれてるだけなんだから、パソコンがどう判断してこのメッセージが出てきたか考えるのが正解だな。そのためには、もっとプログラミングのことを知らねば。
ランダムに『ズン』『ドコ』を表示する
さて、ズンドコキヨシに必要なのは、
- ズンとドコをランダムに出す
- 『ズン、ズン、ズン、ズン、ドコ』が出たら、『キ・ヨ・シ!』と表示する
の二つだな。次はズンとドコをランダムに出す、に取り掛かってみよう。ええと、Rubyでランダムに表示を変えるには、と。姉貴のノートをペラペラ〜と。
ランダムな数字を作るのには、
Random.rand
を使う。これは0.0から1.0までのランダムな数字を返す
ふむふむ。数字じゃなくて表示を変えたいんだけどな。でもまずはいいや。
本当にランダムな数字が出てくるのかな?ちょっと試してみよう。
puts "Random.rand"
えい、ruby Random.rb
。
Random.rand
あれ、出ない。なんでだ?今度はエラーメッセージもでてこないなぁ。つまり、俺が間違っているけどパソコン的には正しい命令を受け取っている、というパターンか。そういや""
で囲むのは囲んだ文字を出したいときだった気が。今回、"Random.rand"
って囲んじゃったからそのまま出てきただけか。じゃあ次はわざと間違えてみよう。それをこのパソコンはどう解釈するんだろう?
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より小さければいいんだから
if Random.rand < 0.5 then
puts "ズン"
end
とう、ruby Zundoko.rb
。あ、何も出ない。も一回ruby Zundoko.rb
。今度はズン
って出た。ランダムでズンを表示するのは出来たぞ。
じゃあ、今度はRandom.randが0.5より大きいときには『ドコ』って表示するようにしよう。
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
って一つのプログラムでずっと同じ数字なんじゃなくて、一回書かれる毎に違う数字になるってことか?ちょっと試してみよう。
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
の値を箱みたいなものに入れておくことができればなぁ。ちょっとノートをペラ見してみるか。おお、なんか箱の絵があるぞ。
この箱は変数のイメージ。名前の付いているこの箱に何かを入れることを、変数に値を代入するという。
変数の名前は基本的に好きなものをつけていい。
ふむ。とりあえずサンプルを打ち込んでみるか。
variable = 3
puts variable
ruby variable.rb
っと。
3
ふーん。これは1行目でvariableって名前の変数に3を代入して、2行目でvariableって名前の変数の中身を出力しろ、って言ってるのか。で、ノートによると変数名は基本的に自由な名前をつけられるらしいな。じゃあ、
kiyoshi = 3
puts kiyoshi
ruby variable.rb
っと。
3
うん、なんとなくわかった。
文字列と変数名
じゃあこれを改造して、
kiyoshi = ズン
puts kiyoshi
ruby variable.rb
っと。
variable.rb:1:in `<main>': undefined local variable or method `ズン' for main:Object (NameError)
お、さっきと同じエラーだ。さっきは""
で囲んだら直ったんだっけ。この""
の意味をそろそろ知りたいぞ。
kiyoshi = "ズン"
puts kiyoshi
ruby variable.rb
っと。
ズン
おし、直った。
ちなみに、puts "kiyoshi"
ってやったらどうなるんだろう?試してみるか。
kiyoshi = "ズン"
puts "kiyoshi"
ruby variable.rb
っと。
kiyoshi
へー、『ズン』じゃなくてkiyoshi
って出た。""
の謎は深いぞ。
ノートをペラペラ〜っと見て、""
の箇所は、あ、あった!なになに、
""で囲まれた文字は文字列になる。文字列とは、文字のかたまりのこと。
………、わからーん!
まぁでも、kiyoshi
っていうのは変数の名前で"kiyoshi"
ってのは文字のかたまりで、パソコンの中では全く別物になってるんだな、きっと。""
で囲んだら、変数の名前としての意味が失われるっぽい。だから変数の中身が表示されずに、文字列のkiyoshiが出力されたと。ふむふむ。
Random.randは変数?メソッド?
じゃあやりたかったことに戻ろう。Random.randの値を変数に入れて保存したい。
と、ちょっと待てよ。Random.randって変数なのかメソッドなのか、さっき迷ったよな。これをわざわざ変数に入れる必要があるんだから、メソッドっぽい感じ。もし変数だとしたら他の数字が入れられるはずなんで、試してみるか。
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の値を変数に入れて保存してみるぞ。
random_var = Random.rand
puts random_var
puts random_var
これで2回とも同じ数字が出れば…!
0.06327292558924758
0.06327292558924758
計画通り!これをさっきの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が入ってたらどう動くんだろう?ちょっと試してみようか。
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自身は含まないんだったな。ここはプログラミングでも同じなのか。じゃあこうやって書いてみよう。
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
と書く。後者の書き方は数学の授業で習うものとは違うので注意すること。
へー、なるほど。じゃあこう書いて、
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を含まない記号の>
か<
を使ってやればいいのか。じゃあ次のように書いて。
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
と書いたところを直そう。
random_var = Random.rand
if random_var < 0.5 then
puts "ズン"
end
if random_var >= 0.5 then
puts "ドコ"
end
これでようやく、1つ目のズンとドコをランダムに表示する、という部分ができたぞ。
『ズン、ズン、ズン、ズン、ドコ』が出たら、『キ・ヨ・シ!』と表示する〜ループに挑戦〜
次は2. 『ズン、ズン、ズン、ズン、ドコ』が出たら、『キ・ヨ・シ!』と表示する、だけど、これはどうやったらいいんだろう?そもそもどうやったら何回も『ズン』と『ドコ』を出せるんだろう?
うーん、う〜ん、う〜〜ん…。最初のツイ主さんのTwitterにヒントがないかな?
さっきのキヨシ関数の実装は
— てくも (@kumiromilk) 2016年3月9日
「ズン」が出力…zunカウンターを1プラス
「ドコ」が出力…zunカウンターリセット
ってやって、zunカウンターが4の時に「ドコ」が出力されたらループ終了して「キ・ヨ・シ!!」を出力するだけだよ 簡単
ほうほう…。ループ、ループかぁ!それでずっとランダムに『ズン』と『ドコ』を出し続けて、条件を満たしたらループを終了すればいいのか。ちょっとループについてノートを調べてみよう。なになに、
ループには
while
、until
、for
の3種類がある。ループには条件文がセットで付いてくる。その条件文をどう扱うのかで3種類を使い分ける。
- while 条件を満たしている間、ループし続ける。
- until 条件を満たすまでの間、ループし続ける。
- for 指定した回数だけループする。
とな。今回使えそうなのはどれだろう?ツイートによると、zunカウンターが4の時に『ドコ』が出力されたらループ終了、とあるな。とすると、zunカウンターが4の時に『ドコ』が出力されるまでループし続ける、と言い換えられるから、untilを使えば良さそうだ。
カウンターを作る〜変数の足し算〜
zunカウンターってのはどうやったらプログラミングできるだろう?さっきifの条件文を書くときには変数を使ったけれど、zunカウンターの仕組みも変数を使えば実現できるかな?
変数って足し算できるんだろうか?そもそも足し算をプログラミングするってどうやるのかな?ちょっと実験してみよう。ここはまとめて…。
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ってそのまま書けばいいのかな?わからん、実験だ!
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だったりするのかな?
もう一度試してみよう。
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の間の命令を実行する、ってのに似てるな。じゃあ、こう書けばいいのかな。
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行目の=
は==
であるべき、と。なるほど。単に=
だと変数に値を入れるときの=
と区別がつかないからか。ノートをちらりと。
※代入は
=
を、比較には==
を使う。使い分けに注意。
かぁ。じゃあここを直して、
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
って書いてるのになぁ。もしかして条件式の中で呼び出される前に値をセットしなくちゃいけないのかな?
困った時は実験です。
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に届かないのか。面白いなぁ。
じゃあそれを付け加えて、と。
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
を作ればいいか。そうすると、
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未満と言うのをチェックさせたらどうだろう?
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
これを実行してみると…。やった!「ズン」「ズン」「ズン」「ズン」「ドコ」が出たらちゃんと終わる!
じゃあ最後に"き・よ・し!"を出力する部分を含めて…。
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話に続く〜