Scratch2MCPI プログラミング③チェック模様の床を作る




③チェック模様の床を作る

Image

チェック模様の床はかっこいいです。でも自分で建築してみるとわかると思いますが、白と黒を交互に設置していくのは面倒です。大きな床を敷き詰めるとなると、かなり時間もかかります。こういった作業はコンピューターに任せてしまいましょう。

コンピューターが得意なのは同じ作業の繰り返しです。白、黒、白、黒… と繰り返し、ブロックを設置していくスクリプトを考えていきます。

サイズ10 x 10 の真っ白な床を作る

Image

前回作った壁と同じように、床を作っていきます。壁は上(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 の縞模様(白黒)の床を作る

今までは同じブロックを積み上げていったので簡単でしたが、途中でブロックの種類を変えるにはどうすればよいでしょうか?

コンピューターに「こういうときは白のブロックを置け。そうじゃないときは黒のブロックを置け。」と命令をしなくてはならないのです。これが「条件分岐」と言われるものです。

Image

つまり条件分岐とは、プログラムの途中で処理が2つに分かれて、「条件式に合致した(YES)ときは処理1を実行せよ。合致しない(NO)ときは処理2を実行せよ」と命令するということです。

Image

カウンター変数を設定する

条件分岐の使い方について、具体的に考えていきましょう。縞模様の床を作るのですから、X方向に動くたびに、白を置く、黒を置く、白を置く、黒を置く… と処理を変えなくてはなりません。その目印として、カウンター変数を設定します。カウンター変数とは、処理の回数を数えておいて、それを目印として処理の仕方を変えるときに使う変数のことです。

Image

カテゴリ「変数」→「新しい変数を作る」→変数名「i(英文字のアイ)」を作成します。同じように「j(ジェイ)」「k(ケイ)」を作ります。(カウンター変数には慣習的に、i, j, k が使われます。別のプログラミング言語に移るときに迷わないように、カウンター変数として、「i」「j」「k」の英文字を使いました。)

Image

カウンター変数を使えるようにスクリプトを変更します。

[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で割った余りを見ればよいのです。

Image

条件分岐は次のようになります。

(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 のチェック模様(白黒)の床を作る

Image

チェック模様を作るには、Z方向にもカウンター変数を設置しましょう。そして条件式を少し変更するだけでチェック模様が現れます。

2つ目のカウンター変数の設置

Image

先ほどと同じように、変数として、[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 … と増えていくスクリプトができました。

条件式の修正

Image

条件式の部分も修正が必要です。結論から言うと、「i」を「i + j」にするだけです。上の図を見てください。「i + j」の値が書かれていますが、偶数に「白を置く」、奇数に「黒を置く」と、目的通りにチェック模様ができるのです。

したがって条件式は以下のようになります。

 
もし <(((i)+(j)) を (2) で割った余り) = [0]> なら 
  [blockData v] を [0] にする
でなければ  
  [blockData v] を [15] にする
end

スクリプトを実行してみると、チェック模様の床が作成されました。成功です。

バグフィックス(bug fix)

「これでOK !」と言いたいところですが、あと一つだけ作業が残っています。「X方向の繰り返しが10回の時はうまくいったが、別の回数の時はどうなるか?」の検証です。これがバグフィックスと言われている修正作業で、ある条件でうまくいっても、別の条件ならうまくいかないことが多いので、色々条件を変えてやってみる。バグ(プログラム上の誤り)があれば修正(fix)する、を繰り返すわけです。

このスクリプトの場合は、繰り返し回数が偶数ならうまくいくが、奇数ならうまくいかない(縞模様になってしまう)ことがわかりました。

Image

バグフィックスは簡単でした。繰り返し処理の最後に、[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」回(奇数)にして検証し、成功しました。

これで完璧です(のはずです)。

Image

最後に、「ファイル」→「名前を付けて保存」から、「mcpi_check_floor」として保存しておきましょう。

縞模様からチェック模様に改造するのは、思ったより簡単でした。難しそうな課題(チェック模様)が与えられたときは、より簡単な課題(縞模様)から考えていくと、うまくいくことが多いのです。プログラミングで迷ったときは、そのことを思い出してください。

今まで習った「繰り返し処理」「条件分岐」を使えば、家作りの多くのプロセスを自動化することができます。

次回は、「窓付きの壁」をプログラミングしてみましょう。今までの知識でそれほど難しくなくできるはずです。

このプロジェクト(mcpi_check_floor.sb)はダウンロードして、自分で確かめることがきます。

サンプルプログラムのページへ

(サンプルプログラムのページに移動します。ダウンロードしたいファイルのリンクをマウスで右クリックして、「対象をファイルに保存」などのメニューを実行してください。)

【追加ミッション】2 x 2 のチェック模様を作ってみる

Image

さらにスクリプトを改造していきます。改造するのは楽しいだけでなく、プログラミングの力をアップしてくれます。

幅が 2 の縞模様を作る

Image

先ほどと同じで、まずは簡単な縞模様から考えます。条件によって「白を置く処理」「黒を置く処理」を分けるところは変わりませんから、「条件式」を変更するだけで済みそうです。

カウンター変数 「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」のときは「黒を置く処理」をさせれば、縞模様が書けるはずです。条件式を変更してみましょう。

Image

条件式を書き換えてみましょう。

もし <((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方向にも縞模様が書けるはずです。

Image

条件式を書き換えました。新しいブロック< >かつ< >は、カウンター変数「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

スクリプトを実行すると、チェック模様ができました。しかし黒の部分が多すぎて、目的の模様になっていないのです。黒の部分にさらに改造が必要です。もう一歩です。(これはこれで綺麗な模様です。)

コラム 集合について

Image

集合で「A かつ B」は図の黄色の部分を表します。「共通部分(または積集合)」と呼ばれ、記号は「A∩B」となります。この例では、「ネコも犬も両方好きな人」が属するグループのことです。

Image

集合で「A または B」は図の黄色の部分を表します。「和集合」と呼ばれ、記号は「A∪B」となります。この例では、「ネコも犬も両方好きな人」と「ネコだけ好きな人」と「犬だけ好きな人」が属するグループのことです。

2 x 2 チェック模様の床の完成

Image

黒を置く処理の部分に、条件式を追加しました。意味は、カウンター変数「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 チェック模様を作成せよ。

Image

自分で考えて、手を動かして、とにかくやってみる。

うまくいかなかったら、なぜうまくいかないか考える。

うまくいったら、なぜうまくいったか考える。それがプログラミング上達の秘訣です。

【付録】blockTypeId, blockData について

マインクラフトのプログラミングでは、ブロックの種類を2つの変数(blockTypeId, blockData)で表します。家作りでよく使うブロックについて、リストを上げておきます。建築の参考にしてください。「blockTypeId」「blockData」の値を調べることができます。(別のブロックを使いたいときは、「ブロックid」をネットで検索してみてください。)

blockTypeId blockData image name 名前
0 0 image air 空気
1 0 image stone
2 0 image grass
3 0 image dirt
4 0 image cobblestone 丸石
5 0 image plank 木材
20 0 image glass ガラス
35 0 image white_wool 白の羊毛
35 1 image orange_wool オレンジの羊毛
35 2 image magenta_wool マゼンタの羊毛
35 3 image light_blue_wool ライトブルーの羊毛
35 4 image yellow_wool 黄色の羊毛
35 5 image lime_wool ライムの羊毛
35 6 image pink_wool ピンクの羊毛
35 7 image gray_wool グレイの羊毛
35 8 image light_gray_wool ライトグレイの羊毛
35 9 image cyan_wool シアンの羊毛
35 10 image purple_wool 紫の羊毛
35 11 image blue_wool 青の羊毛
35 12 image brown_wool 茶色の羊毛
35 13 image green_wool 緑の羊毛
35 14 image red_wool 赤の羊毛
35 15 image black_wool 黒の羊毛
45 0 image brick レンガ
64 0 image oak_door オークのドア
85 0 image fence フェンス
107 0 image fence_gate フェンスゲート
355 0 image bed ベッド



Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください