③チェック模様の床を作る
チェック模様の床はかっこいいです。でも自分で建築してみるとわかると思いますが、白と黒を交互に設置していくのは面倒です。大きな床を敷き詰めるとなると、かなり時間もかかります。こういった作業はコンピューターに任せてしまいましょう。
コンピューターが得意なのは同じ作業の繰り返しです。白、黒、白、黒… と繰り返し、ブロックを設置していくスクリプトを考えていきます。
サイズ10 x 10 の真っ白な床を作る
前回作った壁と同じように、床を作っていきます。壁は上(Y)方向に伸ばしていきましたが、床はZ方向に伸ばしていきます。blockTypeId = 35、blockData = 0(白い羊毛)に変えました。
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする (10) 回繰り返す (10) 回繰り返す [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える end
ここまでは前回のおさらいです。
サイズ10 x 10 の縞模様(白黒)の床を作る
今までは同じブロックを積み上げていったので簡単でしたが、途中でブロックの種類を変えるにはどうすればよいでしょうか?
コンピューターに「こういうときは白のブロックを置け。そうじゃないときは黒のブロックを置け。」と命令をしなくてはならないのです。これが「条件分岐」と言われるものです。
つまり条件分岐とは、プログラムの途中で処理が2つに分かれて、「条件式に合致した(YES)ときは処理1を実行せよ。合致しない(NO)ときは処理2を実行せよ」と命令するということです。
カウンター変数を設定する
条件分岐の使い方について、具体的に考えていきましょう。縞模様の床を作るのですから、X方向に動くたびに、白を置く、黒を置く、白を置く、黒を置く… と処理を変えなくてはなりません。その目印として、カウンター変数を設定します。カウンター変数とは、処理の回数を数えておいて、それを目印として処理の仕方を変えるときに使う変数のことです。
カテゴリ「変数」→「新しい変数を作る」→変数名「i(英文字のアイ)」を作成します。同じように「j(ジェイ)」「k(ケイ)」を作ります。(カウンター変数には慣習的に、i, j, k が使われます。別のプログラミング言語に移るときに迷わないように、カウンター変数として、「i」「j」「k」の英文字を使いました。)
カウンター変数を使えるようにスクリプトを変更します。
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする [i v] を [0] にする (10) 回繰り返す (10) 回繰り返す [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える [i v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える end
変数として、[i v]を[0]にする
を追加します。数を数えるときは、1, 2, 3, 4, 5 …と数えるのが普通ですが、プログラミングの世界では、0 から数えていくのです。違和感があるかもしれませんが、今は素直に「0 から数えるんだ」と覚えておいていただければ十分です。
X方向に10回繰り返す部分には、[i v]を(1)ずつ変える
を追加しました。これで処理のたびに、i の値が、0, 1, 2, 3, 4 … と増えていくスクリプトができました。
縞模様のための条件分岐
i の値によって「白を置く処理」と「黒を置く処理」を分岐させる部分を作っていきます。
i の値が、0, 1, 2, 3, 4 … と増えていくのですが、これを偶数と奇数に分けるにはどうすればよいでしょう?
もし <((i)を(2)で割った余り) = [0]> なら [blockData v]を[0]にする でなければ [blockData v]を[15]にする end
偶数とは2で割り切れる数、奇数は2で割り切れない数です。つまり2で割った余りを見ればよいのです。
条件分岐は次のようになります。
(i)を(2)で割った余り
が 0(偶数)のときは、 [blockData v]を[0]にする
(白の羊毛)
(i)を(2)で割った余り
が 1(奇数)のときは、 [blockData v]を[15]にする
(黒の羊毛)
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする [i v] を [0] にする (10) 回繰り返す (10) 回繰り返す もし <((i) を (2) で割った余り) = [0]> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える [i v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える end
これを上のスクリーンショットのように条件分岐にして、[setBlock v]を送る
の処理の前に置けば完成です。スクリプトを実行して、縞模様ができることを確認してください。
サイズ10 x 10 のチェック模様(白黒)の床を作る
チェック模様を作るには、Z方向にもカウンター変数を設置しましょう。そして条件式を少し変更するだけでチェック模様が現れます。
2つ目のカウンター変数の設置
先ほどと同じように、変数として、[j v]を[0]にする
を追加します。繰り返し処理の最後に、[j v]を(1)ずつ変える
を追加しました。
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする [i v] を [0] にする [j v] を [0] にする (10) 回繰り返す (10) 回繰り返す もし <(((i)+(j)) を (2) で割った余り) = [0]> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える [i v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える [j v] を (1) ずつ変える end
これで処理のたびに、j の値が、0, 1, 2, 3, 4 … と増えていくスクリプトができました。
条件式の修正
条件式の部分も修正が必要です。結論から言うと、「i」を「i + j」にするだけです。上の図を見てください。「i + j」の値が書かれていますが、偶数に「白を置く」、奇数に「黒を置く」と、目的通りにチェック模様ができるのです。
したがって条件式は以下のようになります。
もし <(((i)+(j)) を (2) で割った余り) = [0]> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end
スクリプトを実行してみると、チェック模様の床が作成されました。成功です。
バグフィックス(bug fix)
「これでOK !」と言いたいところですが、あと一つだけ作業が残っています。「X方向の繰り返しが10回の時はうまくいったが、別の回数の時はどうなるか?」の検証です。これがバグフィックスと言われている修正作業で、ある条件でうまくいっても、別の条件ならうまくいかないことが多いので、色々条件を変えてやってみる。バグ(プログラム上の誤り)があれば修正(fix)する、を繰り返すわけです。
このスクリプトの場合は、繰り返し回数が偶数ならうまくいくが、奇数ならうまくいかない(縞模様になってしまう)ことがわかりました。
バグフィックスは簡単でした。繰り返し処理の最後に、[i v]を[0]にする
を追加することです。
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする [i v] を [0] にする [j v] を [0] にする (10) 回繰り返す (10) 回繰り返す もし <(((i)+(j)) を (2) で割った余り) = [0]> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える [i v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える [i v] を [0] にする [j v] を (1) ずつ変える end
X方向の繰り返しの前に、必ずカウンター変数「i」の値を 0(偶数)にリセットしてやることで、目的の動作を得ることができました。X方向の繰り返しを「11」回(奇数)にして検証し、成功しました。
これで完璧です(のはずです)。
最後に、「ファイル」→「名前を付けて保存」から、「mcpi_check_floor」として保存しておきましょう。
縞模様からチェック模様に改造するのは、思ったより簡単でした。難しそうな課題(チェック模様)が与えられたときは、より簡単な課題(縞模様)から考えていくと、うまくいくことが多いのです。プログラミングで迷ったときは、そのことを思い出してください。
今まで習った「繰り返し処理」「条件分岐」を使えば、家作りの多くのプロセスを自動化することができます。
次回は、「窓付きの壁」をプログラミングしてみましょう。今までの知識でそれほど難しくなくできるはずです。
このプロジェクト(mcpi_check_floor.sb)はダウンロードして、自分で確かめることがきます。
(サンプルプログラムのページに移動します。ダウンロードしたいファイルのリンクをマウスで右クリックして、「対象をファイルに保存」などのメニューを実行してください。)
【追加ミッション】2 x 2 のチェック模様を作ってみる
さらにスクリプトを改造していきます。改造するのは楽しいだけでなく、プログラミングの力をアップしてくれます。
幅が 2 の縞模様を作る
先ほどと同じで、まずは簡単な縞模様から考えます。条件によって「白を置く処理」「黒を置く処理」を分けるところは変わりませんから、「条件式」を変更するだけで済みそうです。
カウンター変数 「i」の値は、0, 1, 2, 3, 4, 5, 6, 7, 8 と増えていきます。「0, 1」は白、「2, 3」は黒、「4, 5」は白、「6, 7」は黒を置けばよい。つまり4回ごとに「白黒」が繰り返していることになります。
カウンター変数「i」を 4で割った余りは、0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 … のように繰り返します。だから「0, 1」のときは「白を置く処理」、「2, 3」のときは「黒を置く処理」をさせれば、縞模様が書けるはずです。条件式を変更してみましょう。
条件式を書き換えてみましょう。
もし <((i) を (4) で割った余り) < [2]> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end
作成したスクリプトをクリックしてみると、幅が 2の模様の床が作成されました。成功です。
2 x 2 のチェック模様を作る
条件式の部分のみ見直します。今度は Z方向のカウンター変数「j」についても修正しなければなりません。カウンター変数「i」と同じように、カウンター変数「j」も 4で割った余りを考えれば良さそうです。4で割った余りが「0, 1」のときは「白を置く処理」、「2, 3」のときは「黒を置く処理」をさせれば、Z方向にも縞模様が書けるはずです。
条件式を書き換えました。新しいブロック< >かつ< >
は、カウンター変数「i」も「j」も共に、4で割った余りが「0, 1」だったときは「白を置く」という意味です。
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする [i v] を [0] にする [j v] を [0] にする (10) 回繰り返す (10) 回繰り返す もし <<((i) を (4) で割った余り) < [2]> かつ <((j) を (4) で割った余り) < [2]>> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える [i v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える [i v] を [0] にする [j v] を (1) ずつ変える end
スクリプトを実行すると、チェック模様ができました。しかし黒の部分が多すぎて、目的の模様になっていないのです。黒の部分にさらに改造が必要です。もう一歩です。(これはこれで綺麗な模様です。)
コラム 集合について
集合で「A かつ B」は図の黄色の部分を表します。「共通部分(または積集合)」と呼ばれ、記号は「A∩B」となります。この例では、「ネコも犬も両方好きな人」が属するグループのことです。
集合で「A または B」は図の黄色の部分を表します。「和集合」と呼ばれ、記号は「A∪B」となります。この例では、「ネコも犬も両方好きな人」と「ネコだけ好きな人」と「犬だけ好きな人」が属するグループのことです。
2 x 2 チェック模様の床の完成
黒を置く処理の部分に、条件式を追加しました。意味は、カウンター変数「i」も「j」も共に、4で割った余りが「2, 3」だったときは「白を置く」という意味です。
スクリプトを実行すると、「2 x 2 のチェック模様」が現れました。成功です。
[mcpiX v] を [0] にする [mcpiY v] を [0] にする [mcpiZ v] を [10] にする [blockTypeId v] を [35] にする [blockData v] を [0] にする [i v] を [0] にする [j v] を [0] にする (10) 回繰り返す (10) 回繰り返す もし <<((i) を (4) で割った余り) < [2]> かつ <((j) を (4) で割った余り) < [2]>> なら [blockData v] を [0] にする でなければ もし <<((i) を (4) で割った余り) > [1]> かつ <((j) を (4) で割った余り) > [1]>> なら [blockData v] を [0] にする でなければ [blockData v] を [15] にする end end [setBlock v] を送る (0.1) 秒待つ [mcpiX v] を (1) ずつ変える [i v] を (1) ずつ変える end [mcpiX v] を [0] にする [mcpiZ v] を (1) ずつ変える [i v] を [0] にする [j v] を (1) ずつ変える end
【宿題】3 x 3 のチェック模様を作成せよ
条件式を見直すことにより、3 x 3 チェック模様を作成せよ。
自分で考えて、手を動かして、とにかくやってみる。
うまくいかなかったら、なぜうまくいかないか考える。
うまくいったら、なぜうまくいったか考える。それがプログラミング上達の秘訣です。
【付録】blockTypeId, blockData について
マインクラフトのプログラミングでは、ブロックの種類を2つの変数(blockTypeId, blockData)で表します。家作りでよく使うブロックについて、リストを上げておきます。建築の参考にしてください。「blockTypeId」「blockData」の値を調べることができます。(別のブロックを使いたいときは、「ブロックid」をネットで検索してみてください。)
blockTypeId | blockData | image | name | 名前 |
---|---|---|---|---|
0 | 0 | ![]() | air | 空気 |
1 | 0 | ![]() | stone | 石 |
2 | 0 | ![]() | grass | 草 |
3 | 0 | ![]() | dirt | 土 |
4 | 0 | ![]() | cobblestone | 丸石 |
5 | 0 | ![]() | plank | 木材 |
20 | 0 | ![]() | glass | ガラス |
35 | 0 | ![]() | white_wool | 白の羊毛 |
35 | 1 | ![]() | orange_wool | オレンジの羊毛 |
35 | 2 | ![]() | magenta_wool | マゼンタの羊毛 |
35 | 3 | ![]() | light_blue_wool | ライトブルーの羊毛 |
35 | 4 | ![]() | yellow_wool | 黄色の羊毛 |
35 | 5 | ![]() | lime_wool | ライムの羊毛 |
35 | 6 | ![]() | pink_wool | ピンクの羊毛 |
35 | 7 | ![]() | gray_wool | グレイの羊毛 |
35 | 8 | ![]() | light_gray_wool | ライトグレイの羊毛 |
35 | 9 | ![]() | cyan_wool | シアンの羊毛 |
35 | 10 | ![]() | purple_wool | 紫の羊毛 |
35 | 11 | ![]() | blue_wool | 青の羊毛 |
35 | 12 | ![]() | brown_wool | 茶色の羊毛 |
35 | 13 | ![]() | green_wool | 緑の羊毛 |
35 | 14 | ![]() | red_wool | 赤の羊毛 |
35 | 15 | ![]() | black_wool | 黒の羊毛 |
45 | 0 | ![]() | brick | レンガ |
64 | 0 | ![]() | oak_door | オークのドア |
85 | 0 | ![]() | fence | フェンス |
107 | 0 | ![]() | fence_gate | フェンスゲート |
355 | 0 | ![]() | bed | ベッド |