4 車を道に沿って走らせてみよう
このプロジェクトでは,直線の道を折り返したり,円形の道に沿って走ったりする少し知的な車をプログラミングすることに挑戦します.
これを実現するためには,道を判別する「センサー」と「場合分け」という概念を学習する必要があります.
プログラムもだんだんと複雑になってくるので,それを整理するために「フローチャート」という図法を活用します.
まずは既にあるプログラムをフローチャートで表現することで,プログラムの構造を理解してみましょう.
次に実行前のプログラムのフローチャートを見て,どんな動作をするのか予想してみましょう.
プログラミングに関するキーワード
Squeakに関するキーワード
4.1 場合分け(1)- 各場合に実行する命令が1つの時
- M先生
- 新しくproject3という名前のプロジェクトを作ってもらえるかな.今まで使ってきた車も用意しておいてね.
- Sくん
- はい.
- M先生
- まずは道路を往復する車を作ってみよう.道の端に車がくると,折り返して走り続けるようにしてみようか.
- Tさん
- すごい.そんなことができるんですね.
- M先生
- 先に必要な部品を作ってしまおう.まず横向きの直線道路を描いてくれるかい?後で必要になるから,道路の両端に印をつけておこう.
あとは道路の真ん中にセンターラインも入れておこう.車は青ハロを使って横向きにしておいてね.
- Sくん
- はい.道路の両端の印は緑色で描いておきました.こんな感じですかね.
- M先生
- いいね.次は車を少し改造するよ.道の端に来たかどうかを判別するために車に「
センサー
」を付けよう.
- Sくん
- えっ,また車を描くのかー.面倒くさいなー.
- Tさん
- 描き直しハロを使えば,センサーだけを描き足すことができるよ.
- Sくん
- おっと.そうか.
- M先生
- センサーは車のボディの色と違う色にするのがポイントだよ.詳しくは後で説明するけれど,こうしておけば車が道の端に来たかどうか検知できるんだ.
- Sくん
- センサーをつけ終わりました.
- M先生
- よし,これで部品は全部そろったね.次は完成させたい車の動きをしっかり確認してみよう.
- Tさん
- 言葉で説明するとしたら,「車は道に沿って直進し,道の両端に来たらそれまで走っていた方向と逆向きに反転する」かな.
- M先生
- 言葉だけで説明するのは難しいね.図も一緒に描くと分かりやすいかな.
- Sくん
- こんな感じですね.
- M先生
- いいね.
- M先生
- さて,いよいよプログラミングをしてみよう.まず,車に「道路を往復する」という名前のスクリプトを作ってくれるかい?
- Sくん
- はい.できました.
- M先生
- まずは,プログラムを組み立てる前に車の動きを整理してみようか.
- Sくん
- はい.
- M先生
- 道路の端に車が来た場合はどのような命令が必要かな?
- Tさん
- 180度回転させればよいと思います.
- M先生
- じゃあ,車が道路の端以外ところにある場合はどうしたらいいかな?
- Sくん
- 進めればよいのではないでしょうか.
- M先生
- そうだね,車が道路の端に来た場合とそれ以外の場合で処理を変えればよいんだ.
- Tさん
- まずは「車が道路の端に来たかどうか調べる」ことがしたいですね.
- Sくん
- うーん,そんなタイルはどのカテゴリにもありませんね.
- M先生
- そこでセンサーの出番だね.センサーを使えるとすると,どのようなことを調べればいいかな?
- Sくん
- 「センサーが道の端を検知したかどうか調べる」ですね.
- Tさん
- でも「センサーが道の端を検知したかどうか調べる」というタイルもないですね.
- M先生
- 「センサーが道の端を検知したかどうか調べる」ことをもっと具体的にしなければいけないんだ.今回は「色」による判定を使ってみよう.
「
センサーカテゴリ
」に「
部分が色に触れているか
」タイルがあるだろう.
- Sくん
- なるほど.このタイルを使えば「車のセンサー(青色)が,道の端の印(緑色)に触れているか」を調べることができるんだ.
- M先生
- では実際にやってみよう.「部分が色に触れているか」タイルを「道路を往復する」スクリプトに入れてみて.
- Sくん
- はい.
- Tさん
- わぁ,タイルが変化しましたね.
- M先生
- 次に色の設定をしよう.まず左側の色から.左側の色の部分をクリックすると,色を選ぶスポイトが表示されるよね.
- Sくん
- このパレットから色を選べばいいんですね.センサーの色にするのが微妙で難しいなー.
- Tさん
- そんなことせずに,センサーの色をスポイトで選択すればいいじゃない.こうやって.
- Sくん
- おっ.鋭いねー.
- M先生
- あとは右側も同じ要領で,道路の端の印の色(緑色)を選択すればいいね.
- Tさん
- 残るはそれぞれの場合に実行する命令ですね.「何もしない」と書いてある部分にタイルが入るんですね.
- Sくん
- えっと,反転させるためには回すタイルを使えばいいから....あれっ?
- Tさん
- 先生,私の方はできました.
- Sくん
- どれどれ.
- Tさん
- ちょっとー.カンニングしないでよ.
- Sくん
- ケチだなー.
No.
3-1 やってみよう! |
道路の両端に印を付けないで,同じ動き方をする車を作ってみましょう.
|
No.
3-2 考えてみよう! |
例題で作ったプログラムに以下のような改造を加えると,車はどのような動きをするか予想し,その理由を説明してみましょう.
- 色に触れているかの判定タイルの左側の色を車のボディの色に変更する
- 車を進めるドット数を大きくする.(ドット数がある値以上になると,車はどのように動くでしょうか)
ヒント
どうしても理由が分からないときは,「実行ボタン」を押してスクリプトを一回ずつ実行し,車の動きを観察してみましょう.
|
4.2 場合分け(2)- 各場合に実行する命令が複数の時
- M先生
- これまで車は一直線に走っていたけれど,次は道の端で折り返すときに車線を変更するようにしてみよう.
- Sくん
- 車の動きを図にするとこんな感じですね.こうすれば車が2台になっても正面衝突しなくなりますね.
- M先生
- よし,じゃプログラムを組み立てていこうか.
- Tさん
- スクリプトを新しく作る必要はありますか?
- M先生
- そうだね.「車線を変更しながら道路を往復する」というスクリプトを作ろう.次に作りたい命令を日本語で説明してみようか.
- Tさん
- 「車が道路の端に来たかどうか調べて,道路の端に来たなら車線を変更して反転させる,それ以外のときは車を進ませる」を繰り返せばOKですね.
- M先生
- さっき作った命令と違うのはどこかな?
- Tさん
- 「車線を変更して反転させる」という部分です.
- Sくん
- 反転してから車線を変更してもいいですよね?
- M先生
- そうだね.ただ,反転してから車線を変更するとプログラムがややこしくなるはずだよ.
- Sくん
- えっ?なんでだー???
- M先生
- じゃあS君は反転してから車線を変更するという方法でやってみなさい.
- Tさん
- 先生,私はできました.それぞれの場合に実行する命令を入れる部分には,複数の命令を入れることができるんですね.
- M先生
- そうだね.複数の命令があれば上から順番に実行されるんだ.
- Sくん
- うーん.できないよー.
No.
3-3 考えてみよう! |
S君が選んだ,「反転させてから車線を変更する」方法ではなぜプログラムがややこしくなるのでしょうか.理由を考えてみましょう.
|
No.
3-4 やってみよう! |
車をコピーし,複数の車を道路に走らせてみましょう.
オブジェクトをコピーすると,スクリプトも一緒にコピーされます.
コピー元のオブジェクトのスクリプトを実行したままコピーするとどうなるかも試してみましょう.
コピーしたオブジェクトのスクリプトを削除してもコピー元のオブジェクトのスクリプトには変化がないことを確認しましょう.
ヒント
複数のオブジェクトのスクリプトを一度に実行する場合は,部品フラップにある「全スクリプト」ツールが役に立ちます.
節[全スクリプト]
に使い方の解説があります.
|
No.
3-5 考えてみよう! |
例題として作った以下のスクリプトをよく見てください.進める命令タイルが2つ入っていますね.
四角で囲んだ2つのドット数(100ドットと10ドット)にはどんな意味があるでしょうか.
道は縦幅より横幅の方が長いはずです.縦方向に走る時のドット数(100ドット)の方が,横を走るときのドット数(10ドット)より大きいのはなぜでしょうか.
|
- M先生
- ちなみに,センサーカテゴリのタイルがなくとも,場合分けタイルだけを取り出すこともできるんだ.
- Sくん
- どうやるんですか?
- M先生
- スクリプトについている時計の横の四角いアイコンをクリックしてみて.
- Sくん
- はい.
- M先生
- 出てきたタイルをスクリプトの中に入れて,「何か」の部分に調べたい事柄を表現したタイルを入れればいいんだ.
- Tさん
- ちょっと面倒くさいですねぇー.
- M先生
- あまり使わないと思うけど,念のため説明しただけだよ.
4.3 フローチャート(1)- 場合分けが1つの時
- Sくん
- 先生,今度はコースを丸くしてみて,どっちが先に道に沿って走る車を完成できるか勝負してます.
- M先生
- なるほどね.どれどれ,プログラムを見せてみて.
- Sくん
- 僕のはこうです.
- Tさん
- 私はちょっと違います.
- M先生
- なるほど.直線道路のプログラムと違うのは,センサーの部分が道路の外にあるかを調べているところだね.
どちらのプログラムでも車はちゃんと道に沿って走れるというわけか.
- M先生
- では,どちらが早くコースを一周できるか競争してみようか.車が速く走るようにプログラムを改造してもいいよ.
- Sくん
- 車を速くするためには,進むドット数を大きくすればいいんだ.30ドット位にしてみようかな.
- Tさん
- 私も.
- Sくん
- ぐはっ,進むドット数を30にすると,僕の車はコースアウトしてしまいました.
- Tさん
- 私の車はコースアウトしませんね.
- M先生
- どうして違う結果になったのか説明できるかな?
- Tさん
- 車が道から外れた時の動きが違うのかも....
- Sくん
- 僕のプログラムでは,車を進める命令が場合分けタイルの外にあるよね.
- Tさん
- うん.問題は車が道から外れた時の動作の違いってことだね.
- Sくん
- 場合分けタイルの外に進める命令があると,道から外れた状態でも車は進んでしまうんだ.
- Tさん
- 私の場合は,車が道の方向に戻るまで進まないよ.
- M先生
- 2人ともいい線いってるね.じゃあ,より整理して考えるために「
フローチャート
」という図法を紹介しよう.
2人のプログラムをフローチャートで表現するとこうなるね.
- Sくん
- 微妙に違いますね.
- M先生
- ひし形が場合分けを表している.四角が命令を表現しているんだ.どこが違うかな?
- Sくん
- 僕のプログラムは,まず進めるが実行されてから,場合分けが実行されるんだ.だから,進むドット数が大きすぎるとコースアウトしてしまうんですね.
- Tさん
- 私のプログラムは,車が道から外れている場合は,回るだけです.だから進めるドット数を大きくしても大丈夫なんですね.
- M先生
- そうだね.Sくんのプログラムは,場合分けタイルの外に進めるという命令があるよね.
これだと車が道から外れているかに関係なく,常に進める命令が実行されるということだ.
- Sくん
- なるほど.だから進めるドット数を大きくすると,コースアウトしてしまうんですね.
- M先生
- 今回は既に作ってあるプログラムを整理するためにフローチャートを使ったけれど,
プログラムを作る前にフローチャートを描いておくと,プログラムがどのように動作するかを考えやすくなるね.
4.4 フローチャート(2)- 場合分けが2つの時
- Sくん
- うーん.車を道の真ん中を走らせるためには....
- Tさん
- どうしたの?
- Sくん
- 今までの車では道の端を走ってしまうから,道の真ん中を走らせようとしているんだ.
- M先生
- それなら色違いのセンサーを2つ用意するのがオススメだね.こんな感じかな.
- Sくん
- そうか.そうすると場合分けタイルが2つ必要になるのか.
- M先生
- まずはプログラムを組み立てたら,車を走らせる前に先生に見せてくれるかい?
- Sくん
- 僕のプログラムはこうなりました.
- Tさん
- 私のはこうなりました.
- Sくん
- わー,場合分けタイルの中に場合分けタイルが入るんだ.はじめて知ったよ.
- M先生
- そうだね.こういう状態を「
入れ子
」と呼ぶよ.
- M先生
- じゃあ,それぞれのプログラムをフローチャートで書くとどうなる?
- Tさん
- こうでしょうか.
- M先生
- どうだろう.このフローチャートを見て,それぞれの車の動きは違うか同じか予想してみよう.
- Sくん
- えっと,僕のは前に作ったのと同じで,必ず進む命令が実行される.
だから,進めるドット数を大きくするとコースアウトしてしまうと思います.
- Tさん
- 私のプログラムは道からはみ出ていない時だけ車が進むから,S君の車と違ってコースアウトはしませんね.
- Sくん
- 実行する前からコースアウトすることが分かるなんて....しょぼーん.
- M先生
- じゃあ実験してみよう.
- Tさん
- やっぱり進めるドット数を大きくするとS君の車はコースアウトね.
- M先生
- まぁまぁ.フローチャートを書くことで,実行する前からプログラムの動作を予測しやすくなっただろ.
S君だってどのように直せばコースアウトしないか分かったはずだよね.
- Sくん
- はい.
No.
3-7 考えてみよう! |
以下のようなヘアピンカーブのあるコースをうまく走るためにはどうしたらよいでしょうか.
|
No.
3-8 考えてみよう! |
以下のようなコースはセンサーが1つの車でうまく走れるでしょうか.うまく走れるかどうかを予想し,その理由を説明してみましょう.
|
No.
3-9 考えてみよう! |
例題で作ったプログラムを,以下のように別々のスクリプトに分割し,同時に実行すると車はどのような動きをするでしょうか.
|
練習問題
4.1
車を走らせたり,止めたりできるスイッチを作りなさい.
4.2
車を左右に操縦できるスイッチを作りなさい.
4.3
決められた範囲内で車を前後に操縦できるスイッチを作りなさい.
4.4
あり集めゲームを作りなさい.
4.5
複数の車を競争させることができるレースゲームを作りなさい.
4.6
一定の幅で左右に移動する反転するカニを作りましょう.