百億のマインクラフトと千億のタートル

つまり、マイクラワールド1つあたりタートルが10匹生息しているわけですね。

タートルプログラミングの基本: 繰り返しfor文の説明と使い方

はじめに

前回の記事の最後に課題を出しましたができましたか?

hevo2.hatenablog.com

「床ブロックを6歩先まで敷き詰めるプログラム」の解答例はココ

turtle.up()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

「床ブロックを6歩先まで敷き詰めたら、そのまま折り返して(Uターンして)戻ってくるプログラム」の解答例はココ

turtle.up()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.placeDown()
turtle.forward()

turtle.turnRight()
turtle.turnRight()

turtle.forward()
turtle.forward()
turtle.forward()
turtle.forward()
turtle.forward()
turtle.forward()

わざわざ振り返らなくても、バックで(turtle.back())戻ってきてもいいかも。

これらプログラムの問題点

前回の課題もそうですが、プログラムを書いているうちに思いませんでしたか?

「めんどくさい」「何度も同じこと書くのなんとかならないの?」

ですよね。実はわざとそういう課題を出しました。(意地の悪い笑顔)

実はプログラミング言語Luaには、このような「何度も同じことをする」ときに、もっと簡単に記述する方法が何通りもあります。

今回はそのうちの一つ、「繰り返しfor文」を紹介しましょう。

繰り返しfor文 の紹介

同じ手順を何度も繰り返す際に、その繰り返す回数があらかじめわかっているなら「繰り返しfor文」が利用できます。

以下は使用例です。

for count=1,6 do
  turtle.forward()
end

この記述は次の記述とほぼ同じ記述となります。

turtle.forward()
turtle.forward()
turtle.forward()
turtle.forward()
turtle.forward()
turtle.forward()

つまりこの繰り返しFor文を使うことで、回数指定して同じ手順を繰り返すことができるわけです。

初めて出てきた文なので、もう少しこの文の使い方を詳しく説明しましょう。

まず基本的な構造は以下のように説明できます。

for カウンタ変数名 = 初期値, 最終値 do
  繰り返したい手順
end

緑色の部分が一番大きな構造です。 つまり「for カウンタの設定 do 繰り返したい内容 end」という構造になっています。

このうち、「繰り返したい手順」についてはいくらでも好きに書けばいいので問題ないとして、理解しづらいのは「カウンタの設定」部分でしょう。

数取器 って知ってる?

ここでいうカウンタとは、いわば数取器(かずとりき、度数計とも)のようなものです。

ja.wikipedia.org

日本野鳥の会の人が鳥の数をカウントしたり、交通量調査のアルバイトしている人が車などをカウントするために、カチカチカチとボタンを押して数字を増やしていく機器ですね。

この数取器に現在カウントした値を覚えさせておくことができ、後からその値を参照できるところがポイントです。

count=1, 6

プログラムではこのカウンタに好きな名前をつけることができるので、今回は「count」という名前をつけています1。その上で、最初の値を「1」に設定しています。

繰り返しfor文は内容を繰り返すごとにこのカウンタの値を1ずつ増やしていきます。 最終値として「6」と書いていますので、最終的にこのカウンタの値が「6」になったときに繰り返しを終了します。

つまり、以下の繰り返しfor文の内容を厳密に説明するならば、次のようになるわけです。

for count=1,6 do
  turtle.forward()
end
  • まず、カウンタ変数「count」の値を1にしてFor文のdo〜end内を実行するよ!
  • turtle.forward() 一歩進む
  • カウンタ変数「count」の値を2にしてFor文のdo〜end内を実行するよ!
  • turtle.forward() 一歩進む
  • カウンタ変数「count」の値を3にしてFor文のdo〜end内を実行するよ!
  • turtle.forward() 一歩進む
  • カウンタ変数「count」の値を4にしてFor文のdo〜end内を実行するよ!
  • turtle.forward() 一歩進む
  • カウンタ変数「count」の値を5にしてFor文のdo〜end内を実行するよ!
  • turtle.forward() 一歩進む
  • カウンタ変数「count」の値を6にしてFor文のdo〜end内を実行するよ!
  • turtle.forward() 一歩進む
  • カウンタ変数「count」の値は最終値の6になっているからもうおしまい!

まとめると、count が 1のときの実行、2のときの実行、3のときの実行、4のときの実行、5のときの実行、6のときの実行と計6回の繰り返しが行われます。

カウンタ変数って何さ

なお、ここでさりげなく「変数」という用語を使っていますが、プログラミング言語における変数とは「数字や文字など好きなものを一時的に保管しておいてあとで言及できる名前付きの箱」だと覚えておくと、今の段階では概ね問題ないでしょう。

名前付きの一時保管箱なので、「そういえば、countという箱の中って今何が入っていたっけ?」とか「あのcountの中に入っているやつってさ・・・」などと、後で変数名を使ってその中身について言及できるのがポイントです。2

たとえば、次のようなプログラムを書くと、for文の挙動が理解しやすくなるかもしれません。 実際に作って試してほしいので、ターミナル画面からプログラム「hensu0」を書いてみましょう。

> edit hensu0

次のプログラムを書く。

f:id:hevohevo:20190922221405p:plain
カウンタ変数の中身を表示するプログラム

ターミナル画面で実行する

> hensu0

このプログラムは、for文の挙動を理解するのに最適です。

f:id:hevohevo:20190922222157p:plain
実行結果

  • countが1になりました。そのcountの値を画面に表示して! → 1
  • countが2になりました。そのcountの値を画面に表示して! → 2
  • countが3になりました。そのcountの値を画面に表示して! → 3
  • countが4になりました。そのcountの値を画面に表示して! → 4
  • countが5になりました。そのcountの値を画面に表示して! → 5
  • countが6になりました。そのcountの値を画面に表示して! → 6

つまり、for文の繰り返しに伴って変化するカウンタ変数の値を表示するプログラムです。

さあ、for文の使い方がわかりましたね? このfor文を使って今までのプログラムを作り直してみましょう。

「床ブロックを6歩先まで敷き詰めるプログラム」

turtle.up()

for count=1,6 do
  turtle.placeDown()
  turtle.forward()
end

あの無駄に長いプログラムがこんなに簡単に・・・(感無量)

なお、for文で繰り返したい手順は、行頭に半角スペースを2個を入れて字下げすることで見やすく工夫しましょう3。行頭スペースのことをインデントと呼ぶのですが、たとえば、以下のインデントがない悪い例と比べるとわかりやすさが段違いですよね。

わかりやすいプログラムのために、for文で繰り返す手順にはインデントを入れる癖をつけましょう。

turtle.up()

for count=1,6 do
turtle.placeDown()
turtle.forward()
end

「床ブロックを6歩先まで敷き詰めたら、そのまま折り返して(Uターンして)戻ってくるプログラム」

turtle.up()

for count=1,6 do
  turtle.placeDown()
  turtle.forward()
end

turtle.turnRight()
turtle.turnRight()

for count=1,6 do
  turtle.forward()
end

うんうん。短い。シンプル。

まとめと今回の宿題

今回の記事で、繰り返しfor文を使ったプログラムの書き方を学びました。 繰り返し回数があらかじめわかっている時には、繰り返しfor文を使うとプログラムがとてもシンプルになります。

さて、それでは今回の総まとめとして、次の課題を宿題としてやってみましょう。 解答は次回の記事で。

  • 「yuka1」プログラム
    • 「床ブロックを6歩先まで敷き詰めたら、そのまま時計回りにUターンして、床ブロックを6歩分敷き詰めながら戻ってくるプログラム」


  1. 変数名は好きにつけて良いのですが、慣習として、for文内のカウンタ変数名は「i」「j」「k」あたりがよく使われるようです。今回はわかりやすさ重視で「count」と名付けました。

  2. ただし変数には「スコープ」と呼ばれる有効範囲があります。変数はあくまで一時的な保管場所なので、いつでもどこでもその変数を参照できるわけではありません。変数の種類によってプログラム中のどの区間で参照できるかのスコープが決まります。今回のfor文内のカウンタ変数のスコープは、そのfor文の中だけとなります。そのため、そのfor文の外でカウンタ変数を参照しても「そんな変数知らんよ」とまともな答えは返ってきません。

  3. 行頭スペース(インデント)の入れ方には流派があります。半角スペース2個の場合、半角スペース4個の場合、はたまたTabスペースの場合。ここでは私が好きな流派である半角スペース2個を押します^^