ステージを作る 1. 道を作る

この章ではステージ自体に手を加えることができるようになります。まず最初のステージでは途切れている道をつないで通行可能にします。
作業は
1. ブロック型のインスタンスを作成する
2. 作成したインスタンスを指定の場所に設置する
の2ステップが必要です。
コードにすると

となります。
少しおさらいするとインスタンスはある決まった性質をもった型から作られた実体です。ひとつの型からたくさんのインスタンスを作ることができます。たい焼きの型を使ってつくる実際のたい焼きひとつひとつがインスタンスと言えます。今までにも、ExpertやCharacterといった型で個人であるexくんやchちゃんを作ってきたのと同じです。
さて、ブロック自身には移動能力がないようで、

などのようにして移動を指示することができません。
かわりにworldという世界のインスタンスに対して、.place()というコマンドで特定のインスタンスを特定の場所に置きます。placeとは「場所」という意味の英語ですが、動詞では「置く」という意味にもなりますね。world.place()というドット表記は「worldに対して、置くという指示を出す」ということになります。そして具体的に指示するには、「なにを」と「どこに」を決めてあげる必要があり、これを()の中にパラメータとしてくっつけてやります。場所の指定は今までと同じく座標を使います。Block型の場合、向きは気にしなくて良いので、パラメーターにも含める必要はありません。

ステージで反対端の閉スイッチまで行くには、途中どうしても渡れない切れ目があります。ここにブロックを置いてやれば良いわけです。置きたい場所をタップすると座標が(3,3)と出ますので、これを使います。
道さえつながってしまえばあとはそう難しいステージではないでしょう。

パラメータ 8. 2つの山

大きく3種類の道から成っているステージです。両側の砂の道、草の道、そして真ん中のフロート板7枚で構成された道です。真ん中のフロート板の道を1段階上げてやると、両側の道の片方の端と高さが揃って、歩いて行き来できる一本道になります。ので、N字のように往復しながら宝石を規定数(totalGem)集めていきます。
まずフロート板の上げ下げ係のexくん(Expert型)を作り、スイッチ前に移動させます。彼の仕事はフロート板を1段終わりだけで終わりです。
次にchくん(Character型)を作りスタート地点に移動。今回は3つの道のそれぞれで、端から端まで移動しつつ宝石を取る動作をひとまとまりとし、関数jumpToEdge()を作りました。砂の道と草の道は段差があるのでmoveForward()だけでなくjump()も使い分けなければなりません(ぶっちゃけ全部jump()で進めるのですが、まぁプログラミングの練習なので一応if文で行き止まりかどうかで分岐させてます)。とった宝石の数はgemsという変数で記録していきます。collectGem()したら必ず+=1しておきましょう。

本編では「規定数の宝石を集める」のがゴールなので、「とった宝石数gemsが規定数totalGemに満たない場合は繰り返す」whileループをメインループとしています。その中でjumpToEdge()を呼んで今いる道の反対側の端まで行き、端の行き止まり状況に応じて左右に向きをかえる分岐をしています。

2019.1.17編集

Swift 4.2版では昇降スイッチの位置が変わったようで、それを操作するexくんの配置座標をatColumn:1 row:4からAtColumn:0 row:4に変更しました。

whileループ 7. ループをネストする

ネストという言葉は前にも一度出てきましたね。「入れ子」という意味です。「ループをネストする」というのは「ループの中に別のループを入れる」ということを指します。
どちらも{}という記号でループ内容をサンドしているので、見た目が紛らわしいですが、「ループの中身は行頭を字下げする」という書き方をすると少し見やすくなります。字下げとはインデントとも呼びますが、行の頭に空白を入れて右へズラすことをいいます。Swift Playgroundでは空白(半角スペース)を4つ入れるのを字下げのルールとしているようなので、それに従いましょう。字下げするのはwhile {行と最後の}行の間の処理です。{の後で改行ボタンを押すと自動で空白4つ分字下げをしてくれる場合もあります。今回のようにループがネスト(入れ子)になる場合、内側のループの{}の中身は4+4で8文字分字下げすることになります。ループが深くなればなるほど4文字ずつ右にズレていくイメージです。
字下げはしてもしなくてもプログラムの動きには影響しませんが、コードが複雑になって頭がこんがらがって来た時に必ず助けになりますので、するクセをつけておくと良いでしょう。

さてステージは、うずまき状に内側へと進んでいく作りです。一番中にいくと行き止まって進めなくなるので、全体としては行き止まりまで進むことにします。次に曲がり角ですが、そこには必ず宝石があるようです。「宝石があるまでは直進し、宝石まで来たら(取ってから)左に曲がる」というループを内側に置きます。これを行き止まるまでループするのです。

なお字下げルールは、whileだけでなく、func文やif文など{}で処理内容を挟む場合全般に使用します。

whileループ 6. 方法はたくさん

ステージの長さが毎回変化するので、まずは毎回端まで進むようなループを考えます。
次に真正面に進む間、各コマにスイッチ(開または閉)があり、右側に必ず宝石、その向こうにスイッチが必ず存在します。左端と右端のスイッチは反対になっているようです。
ここもタイトル通りたくさんのやり方が考えられます。

以下の例では、
スイッチの開閉をあまり意識しないで済むよう、「閉ならオンにする」という関数switchOn()を作成し、開閉どちらでもスイッチがあればswitchOnを呼び出す、というコードにしました。ループの中では、メインストリートのスイッチを処理、右の宝石とゲット、さらに向こうのスイッチを処理、戻る、という処理を連続して行っていますが、スイッチの部分に関してはswitchOn()を呼び出すだけにできるので、ループ内の見通しが良くなります。

もう少し無駄のないコードにするとしたら、「そもそもメインストリート上のスイッチが閉だった場合、そこをオンにすれば、反対側のスイッチまでは行く必要がなく、宝石だけとって戻ればいい」という考え方があります。是非チャレンジしてみてください。メインストリート上のスイッチが閉か開から別々の処理に分岐するか別々の関数を呼び出すのです。

whileループ 5. 回る

このステージは本当に色々なやり方ができます。
例はあくまで例として考えて、自分なりのやり方を考えてみましょう。

こちらの例では、まず宝石が2つずつ並んだ辺をひとまとまりのパターンとして、それを4回繰り替えるという考え方をしています。またパターン内で2つの宝石を取るのも移動を含めて繰り返しにできたので、結果として、4回のループの中で2回の子ループを回すという形になっています。辺から辺への移動をどこに入れ込むか、各ループの基点(スタート地点)をどこにするかが思案のしどころでしょう。