見出し画像

(7)M5GOとUIFlowでプログラミング - 分岐

最後は、「分岐」処理です。プログラムにおいて(5)や(6)でやった「順次」「反復」に加えて「分岐」の3要素が基本になります。この3要素で原理的には世の中にある全てのプログラムが実現できます。

分岐

プログラムでは、条件によって処理を分けることができます。これを分岐、といいます。(6)では、「ずっと」ブロックの中で処理が繰り返され、スピーカーが鳴り続けていました。これを、M5GOに搭載されている「ボタンが押された」か「ボタンが押されていない」かによって処理を分けるようにしてみましょう。そうすれば、「ボタンが押されているときだけ」音がなるようにすることができます。

ボタンの押下の取得

イベントの中に「ボタンAがpressedである」ブロックがあります。

「ボタンAがpressedである」ブロック

赤い文字列の手前のブロックです。

「イベント」のブロック群

まずは、ラベルを設置して、ブロックの中身を表示させてみます。
スピーカーを鳴らすブロックは、一旦外しておきます。

「ボタンAがpressedである」の中身を表示してみます

プログラムを実行すると「False」が表示されると思います。

ボタンを押していないとき

ここで、ボタンA(左のボタン)を押すと、押している間だけ、表示が「True」に変わると思います。

ボタンを押しているとき

「True」は「真」、「False」は「偽」を表し、ある条件に当てはまっているときは「True(真)」、当てはまっていないときは「False(偽)」になります。
この変化を利用して処理を分岐させてみましょう。

「論理」ブロック群。①~③のブロックを使う

「論理」の中に、分岐用のブロックがあります。①が基本のブロックです。
「もし(条件)であれば(処理)」の
「もし(条件)」の「(条件)」の部分に条件が入ります。
「であれば(処理)」の「(処理)」の部分にその「条件」を満たしたとき(Trueのとき)の処理が入ります。

(条件)が満たされている(=True)ときだけ(処理)を行う

② が条件用のブロックです。右辺と左辺を比較して正しければ「True」を、違っていれば「 False」を返します。
例えば、今回の条件であれば、③ と組み合わせて、

「条件」ブロック。(左辺)=(右辺)ならTrueを返す

のように使います。「ボタンAがpressedである」 と「true」を比較して同じ(「=」)のとき、「true」が返され、処理が行われます。
処理は、何でも良いのですが、前回の「スピーカーを鳴らす」ブロックにしてみます。ラベルはひとまず外しておきます。

ボタンが押されているときだけスピーカーが鳴る

すると、ボタンAを押しているときだけ、スピーカーが鳴るようになります。

ボタン押下の検出ブロックの違い

また、よく似たブロックに、「ボタンAがwasPressedである」というブロックがあります。
「wasPressed」は、「押された」、であり、「pressed」は、「押されている」に相当します。動作の違いは、ブロックを変えて実行してみると分かると思います。

wasPressedとpressedブロック

LEDバーを点灯させてみる

スピーカーの代わりにLEDバーを使用してみます。

「RGBカラー」ブロック群

LEDバーは、ハードウェアの中のRGBカラーで操作可能です。
スピーカーを鳴らすブロックと入れ替えてみます。ついでに、ラベルの表示ブロックを復活させておきます。ラベルの表示ブロックは、位置に注意してください。「もし」ブロックの外、「ずっと」ブロックの中です。

スピーカーのブロックをLEDバーに変更する

プログラムを転送後、押したり押すのをやめたりしてみてください。

動作の様子

何か気づくでしょうか?

この状態で書き込んでみると、確かにボタンを押すとLEDが点灯します。しかし、ボタンを押すのをやめても、ディスプレイには「False」と表示されるものの、LEDは点灯したままになってしまっています。ボタンを押すのをやめたら、LEDが消灯するのが直感的な操作なのですが、これは、なぜでしょうか。

これは、条件に「ボタンを押した場合」しかないためです。ボタンを押すのをやめた場合にLEDを消灯するためには「ボタンを押すのをやめた」場合についても書かなくてはいけません。

このように、コンピュータに命令をする上では、あらかじめすべて動作を定義しておく必要があります。定義しておいたものは確実に行ってくれますが、定義されてないことはしません。
これが「プログラム」の本質であり「プロ(pr-)」「グラム(gram)」と呼ぶ所以です。つまり「あらかじめ(pr-)」「書いておいたもの(gram)」です。運動会や文化祭のプログラムなんかも、その日やることを「あらかじめ書いておいたもの」ですね。

さて、この問題を解決するにはどうすればよいでしょうか。
一番簡単なのは、「もし~」ブロックをもう1つ作ることです。このパターンは2つ考えられ、1つは、1つ目の「もし」ブロックの条件が「=true」2つ目の「もし」ブロックの条件を「=false」にするパターンで、

「もし」ブロック2つのパターン1(=falseの条件)

 もう1つのパターンは、2つ目の「もし」ブロックの条件を「≠ true」にするパターンです。「= false」と「≠true」では、多少論理的な意味は違いますが動作としては同じになります。

「もし」ブロック2つのパターン2(≠trueの条件)

 「≠」は、「ノットイコール」と呼ばれ、「同じではない」という条件です。「≠」は条件用ブロックの「=」の部分をクリックすることでリストから選べます。

 また、「もし」ブロックの左の「歯車」マークを押すことで出るウインドウから、「もし」ブロックの種類を変えられます。標準は「もし」(if)ブロックのみですが、「でなければもし」(else if)、「そうでなければ」(else)と、1つの「もし」ブロックに複数条件を設定することができます。ちなみに、ここは日本語に翻訳されていません。

歯車でブロックの種類を変更できる

 「もし」ブロックの種類を変えて、「if - else if」のタイプのブロックにしたもので、上のプログラムと同等に書くと、このようになります。

if- else if(そうでなくもし)のパターン1(=false)

もちろん、「そうでなくもし」の条件は「≠ true」のパターンも考えられます。

if- else if(そうでなくもし)のパターン2(≠true)

そして、これらは書き方は違いますが、プログラム的には(ほぼ)等価です。

さらに、「if - else」タイプでも同じ動作は実現できます。

if-else(そうでなければ)のパターン

ちょっと高度な話

 もっというと、そもそも、「もし」ブロックは(条件)がtrueだったら(処理)をするというブロックです。
この(条件)に「ボタンAがpressedである = true」を当てはめました。
つまり「ボタンAがpressedである = true」全体が「もし」ブロックに対して「True」もしくは「False」を返します。

ブロック全体がTrueまたはFalseを返す

つまり、ブロック全体はこういうことになります。

ブロック全体はこれらのブロックと等価

「ボタンAがpressedである」ブロックはボタンが押されていれば「True」、押されてなければ「False」を返すので、条件に直接「ボタンAがpressedである」を当てはめても同じことになります。

これもTrue、もしくはFalseを返す
条件ブロックを「ボタンAがpressedである」ブロックに変更しても同じ

 このように、同じ機能を実現するにしても、書き方はいろいろあります。したがって、動きが同じでも、プログラムを書く人によって書き方は違ってきたりします。「この書き方が妥当かなぁ」というのはあっても、「この書き方が正解!」というものはないのです。
 ちなみに、個人的には一番最後のパターンがプログラム的にはすっきりしていてよいかなぁと思います。あくまで個人的には、ですが。

 どの書き方でもよいので、プログラムを転送すると、ボタンを押すとLEDが赤く点灯し、押すのを止めるとLEDが消灯すると思います。

いいなと思ったら応援しよう!