ステージを作る 7. 自分だけのステージ

ここは特にクリア条件もなく、world.place()メソッドで好きなオブジェクトを置いてみましょう、というステージなので、それこそ正解はないので今まで憶えたパターンをおさらいしてみましょう。
座標は列番号columnと行番号rowの組み合わせで指定します。マップ上の特定のコマをタップすると(0,0)のような形で表示されますので、自分で数えるよりも早いでしょう。

ステージを作る 6. ループを作る

一見すると4カ所の隙間をふさいで長方形のステージにしてしまえば、あとは規定宝石数集めるまでグルグルまわればいい気がしますが、ワープがあるのでそうもいきません。
私は2箇所だけつないで、4ブロックが真っ直ぐ並ぶ島が4つ、という状態にしました。実はこれでワープを通ると長い一本道と同じことになるのです。あとは、そこをひたすら往復して宝石を集めていけばいつか必要数集めて終わることができます。つまりポイントは、「行き止まりになったら振り返る」「宝石があったら取る」「規定数宝石を集めるまで繰り返す」ということになります。

なお、集めなければならない宝石の数totalGemsはコードを実行する度に変化します。不完全なコードでも、totalGemsがたまたま2とか少ない数だと上手くクリアできてしいまう場合があります。何度か実行してどんな数になってもクリアできることを確認しましょう(その時々の集めないといけない数は実行した時に空の左上のところに出ます)。

ちなみにワープポータルの上にブロック置いて塞いでやれば冒頭に書いたように大きな長方形ステージにできるんじゃないかと思ったんですが、どうもワープポータルは積み上がったブロックの上に出現してしまうようですね。
また最初からあるワープポータルは呼び名がわからないので、.isActive = falseでオフにすることもできなそうです。

方向転換処理のところは、

とも書けるでしょう。ただし3つのif全てに isBlocked & がついているので、これを外側の大きなif文として囲ってネストにしています。こうすると、個々のif文の条件式が1項減って見やすくなる気がしませんか?また、今回は正面だけが行き止まりというパターンはないので、外側のif文で正面が行き止まり(isBlocked)を条件とした後、残る可能性は「両側行き止まり」「右が行き止まり」「左が行き止まり」だけになります。なので、最後はelse ifにする必要もなく、32行目はただのelseで済ますことができます。

ステージを作る 5. 島を渡る

なかなか複雑なステージです。というか単純に1ステップずつコードに落としていく分には簡単ですが、上手く関数やループでまとめようとするとなかなかやり甲斐のあるパズルのようなステージです。
説明文にある通りやり方は無数にあると思うので、自分なりの方法を考えてみてほしいのですが、とりあえず以下の例では、「宝石を基点に見て、90°違いの2方向の1コマ隣に閉スイッチ」という組み合わせが3カ所にあるという点に着目し、1かたまりを処理した後、ワープを使って他のペアに移動する、という流れで考えました。向きとワープをON/OFFするタイミングがキモです。

ステージを作る 4. 階段を置く

今度は階段を作ります。階段の場合、インスタンス、向き、座標(行と列)の4つのパラメーターを.place()メソッドに渡してあげます。
ただし、今回は8つも階段を作る必要があり、いちいち、

などと8つもインスタンスを作って、それをさらに.place()で配置していくのは面倒です。また、ポータルのように後で名前を指定して操作(ON/OFFなど)をする必要がないので、どれがどんな名前か自分で把握しておく必要もありません。
こういう時には出題文にあるちょっとした省略形が使えます。Stair()をいちいちletで変数に入れなくても、.place()文の1つめのパラメーターとして直接書くことができます。こうすることで毎回適当な名前で別々のStair()型インスタンスが出来て、続く向きや座標の通りに.place()文で配置されます。ただしそれぞれがなんて名前なのかはわからないので、後から変更したりはできないことになります。
このように、後で名前を指定して参照する必要がないオブジェクトならば自分でletで名前付きで宣言せずに直接.place文に型だけ指定する方法があると憶えておきましょう。逆に、CharacterやExpert、Portalなど、後から、ドット記法でch.moveForward()のように操作する必要がある場合は、自分でletから書いて名前を付けておく、という使い分け方です。

ステージを作る 3. ワープを作る

このステージで登場するワープポータルを作るためのPortal()ではパラメーターとして色を指定する必要があります。入力候補で「Portal」を選び続けて「(」をタップすると、候補に「(color: Color)」が出てきます。この大文字のColorの部分に実際の色を書く必要があります。この時、入力候補中に写真赤枠のようにグレーの正方形が出てくるので、それを選び、吹き出しから希望の色を選びます。そうすると選んだ色の正方形がコード内に挿入されることでしょう。

例えば緑を選んだらこんな感じになっていればOKです。

greenPortalという名前で緑色のワープポータルを作成したことになります。色を変えたい時はもう一度その正方形をタップします。

ただし、パソコンにコピーすると1行目は以下のように「#colorLiteral(red: 0.4028071761, green: 0.7315050364, blue: 0.2071235478, alpha: 1)」と置き換わってしまいます。どちらでも同じことなのでアプリ上では緑の正方形を出すように入力してください。以後、コメントで色を書き添えるようにします。実際には全く同じ色でなくても大丈夫です。

さて、ステージですが、同じ形、同じ宝石レイアウトで、草の島と砂の島があります。2つはつながっていないので、このステージから使えるようになった方法でワープポータルを自分で設置します。前ステージまでと同じくworld.place()文を使いますが、

のように5つのパラメーターを書き込みます。.place文は最初のパラメータがポータル型のインスタンスであることを認識して、後の4つがワープ元とワープ先の座標であることを理解してくれます。ポータル型のインスタンスには先ほど作っておいたgreenPortalを使えばOKです。

作るタイミングですが、最初からワープポータルがあると邪魔なので、まず草の島で全ての宝石を取り終えて、それからがいいでしょう。