ステージを作る 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です。

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

ステージを作る 2. 道をつなぐ

ブロックは同じ座標に配置すると、上へ積み上がっていきます。今回はそれを利用して道を平らにして通れるようにする必要があります。手前から3本の脇道があり、それぞれに、2つ、1つ、2つのブロック、計5つを配置します。

ルートとして、高低差があるものの「2つ進み、右に曲がり、突き当たりの宝石を取り、戻る」を3回繰り返せばいけそうです。これを設問文の指示通り、ループと関数で書いてみます。名前を考えるのが面倒でpattern1としてしまいました、、

ステージを作る 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に変更しました。