小学校の先生のためのSwift Playgrounds講座 コードを学ぼう1<forループ>【解答】
こんばんは。ツムさんです。
プログラミングなんてやったことないぜキリッ
という先生のための Swift Playgrounds を使ったセミナーです。
前回は、同じコマンドをまとめる「関数」を作りました。
今回は、「forループ」です。
forループって何?
ループの意味は、言葉で書くと、「繰り返す」になります。何を繰り返すかと言えば、「コマンド」となるわけです。同じコマンドを何度も繰り返し実行するような場合にforループは使えます。
たとえば、「1マス進む」コマンドを5回繰り返したい場合(要は5マス進みたい場合)、今までは、moveForwardコマンドを並べて、
moveForward() // 1マス進む
moveForward() // 1マス進む
moveForward() // 1マス進む
moveForward() // 1マス進む
moveForward() // 1マス進む
と書いていました。
これを、forループを使うと
for i in 1 ... 5 {
moveForward()
}
こんな感じに書けます。1 ... 5の部分が5回繰り返すことを意味しています。10回繰り返す場合は、1 ... 10となります。繰り返すコマンドは {} の間に描きます。i in は、今は気にしなくても大丈夫です。(変数の概念を学んだあとに意味を成します。ここで言うプログラミングにおける変数とは、数学の変数と同じ意味です。)
これが100回や1000回繰り返すような場合、forループのほうがはるかに短く書けることが分かると思います。
ループを使う
forループの最初のステージは、ワープマスを駆使して5個の宝石をGetします。一見大変そうですが、ワープマスは隣の列へ移動するためのもので、ひたすら真っすぐ進みつつ宝石を取っていけます。
numberの欄に、繰り返したい回数を入力します。今回は、5列同じコマンドを繰り返すので、ここは5を入力します。繰り返したいコマンドは、簡単ですよね。2マス進んで宝石を取って1マス進むだけです。ワープマスに入ると、丁度スタート位置に戻ってくるので、そのままコマンドを繰り返すだけでこのステージはクリアできてしまいます。
クリアしました!
4辺でループする
このステージも前のステージ同様に、繰り返したい処理の単位を見つけるのがポイントです。ステージのタイトルにあるとおり、4辺をグルっと回りながら宝石を取ります。1辺あたりの処理を4回繰り返せばよさそうだというイメージがつかめますか?
1辺は、1マス進んで宝石を取って、3マス進んで右を向くというコマンドで処理でききます。4辺とも宝石の位置は同じですし、マスの数も同じなので、4回同じ処理を繰り返せばよさそうです。
単純にforループで括ってあげて、繰り返し回数は4回っと、
無事にクリアできました!
端まで行って戻る
ステージを見ると繰り返すべき処理のまとまりが見えてくるようになりましたか?このステージ「端まで行って戻る」も、前2つのステージと同様です。
ステージには8個のスイッチが置かれていますが、四隅のスイッチは既に点灯状態なので押す必要がありません。階段を下りた先のスイッチを押します。
4つのOFF状態のスイッチはどれも階段の先に置かれていて、スタート位置から2マス進んだ先にあります。ということは、スイッチとスタートのマスを往復することを4回繰り返せばよさそうです。ただし、スタート位置に戻ってきたあと、90°ずつ方向転換しなければならない点に注意が必要です。そうしなければ、4回繰り返しても押すことができるスイッチは向かい合った2つだけになってしまいます。
あと一つ。。
方向転換は、forループの中の最後のturnLeftコマンドが対応しています。このコマンドのおかげで、中央のマスに戻ったあと、90°方向を変えながら他のスイッチを押しに行くことができます。
クリアできました!
ワープしてループして
このステージはワープマスが置かれているうえに、繰り返す処理の単位がパッと見で分かり辛いです。一体どこで区切ると、上手にループさせることができるでしょうか。
目印を置いて見てみると繰り返しの構造が浮かんできます。目印はもちろん「宝石」です。宝石を区切りとして、最後に宝石を取る処理を考えてみましょう。
- 1マス進む
- 左を向く
- 2マス進む
- 宝石を取る
- 右を向く
宝石を取ったあと右を向くことで、丁度スタートに立ったときの向きに合わせられます。
どうですか?Byteくんの動作がイメージできていますか?
宝石は全部で5個あるので、5回繰り返してみると、、
クリアできました!ワープマスは、単なる目くらましでした。
3つの分かれ道
このステージはどうでしょうか?前のステージよりも繰り返しの処理をイメージしやすそうです。3つの長い道の先にスイッチが置いてあります。長い道のマスの数はどれも同じ7マスです。繰り返し処理できそうですね。
7マスの道のりをひたすら進む部分を「関数」で作ってみました。関数名は moveSevenStepです。この中に、moveForwardコマンドを7つ並べてもいいのですが、せっかくforループを学んだので、7回繰り返してみます。
あとは、moveSevenStep関数を使いつつスイッチを押す関数を作ります。隣の列へ移動して向きを変える部分を作ります。ループ中の最後にtrunRightコマンドを置くのがポイントです。これにより、スタート位置から数えて丁度同じ処理を3回繰り返してゴールすることができるようになります。
1つ目のスイッチを押しました。
2つ目も順調です。よしよし。
3つ目も無事に押せました!
上のプログラムの最後のforループが3つの列の処理を繰り返している箇所になります。
クリアしました!
右にも左にも
このステージは少しややこしそうです。Byteくんの右には宝石が、左にはスイッチが置かれています。そして、宝石とスイッチが3列同じ間隔で配置されています。
宝石もスイッチも処理するプログラムをいきなり考えるのは大変なので、まずは宝石だけ、スイッチだけ処理するプログラムを考えてみます。
スタート位置から右へ向きを変えて突き当りまで往復すれば宝石を2個回収することが出来ます。これはどの列でも同じ処理になります。ここでは、moveThenGetGem関数にしました。
中身は、1マスずつ進みながら宝石を取り後ろを向いて戻ってくるコマンドを書いています。
スイッチ側の処理も同様に、moveThenToggle関数を作りました。1マスずつ進みながらスイッチを押します。突き当りまで進んだら後ろを向いて戻ってきます。
最後は、moveThenGetGemとmoveThenToggle関数を使いながらforループで3回繰り返しましょう。繰り返すときは、隣の列へ移動するコマンドも必要です。
スタートするとまずは右を向いて(turnRight)宝石を取りに行きます(moveThenGenGem)。往復してスタートのマスに戻ってくると、スイッチの方向を向いているので、そのままスイッチを押しに行きます(moveThenToggle)。スイッチを押してスタートのマスに戻ってきた後は、隣の列へ移るために、左へ向きを変え(turnLeft)1マス進みます(moveForward)。
クリアしました!
4つの場所に4つの宝石
forループの最終ステージです。ここはワープマスで区切られた4つのエリアに4つの宝石が置かれています。エリアが区切られているという意味で繰り返す単位はイメージしやすいと思います。
ステージの宝石の位置とプログラムを対応させて読んでみてください。1つのエリアの4つの宝石を取るプログラムを素直に1つの関数にべた書きしました。
moveThenGetGem関数のポイントは最後にワープマスに「入らないように」します。c実は、最後のcollectGemの後ろにmoveForwardを置いてワープマスに入る部分まで関数にしても問題なくステージをクリアすることができます。
しかし、そのプログラムでは4つ目のエリアの最後の宝石を取ったあとはワープマスが「無い」ため、Byteくんは行き止まりの壁にぶつかってしまいます。
宝石は全部とれるのでステージはクリアとなりますが、Byteくんをぶつけてしまってはかわいそうなので、ここでは上のように、ワープマスに入るためのコマンドは、forループの中に書いています(moveThenGetGem関数の下のmoveForwardがそれです)。そして繰り返し回数を4回ではなく3回として、最後の1回(4エリア目)はループの外で実行しています(最後のmoveThenGetGem)
Byteくんを無傷でゴールさせてあげましょう!!