キャラクターをステージの好きな位置に移動する.placeメソッドに向きを指定できるプロパティが追加されました。同じ.placeでも
前ステージやったのはこういう形でした。
1 |
world.place(ex, atColumn: 1, row: 8) |
今回はこうです。
1 |
world.place(ex, facing: .south, atColumn: 1, row: 8) |
facing:が2番目のパラメータとして追加されていますね。facingにもたせるべき値は向きを示す東西南北の情報ですが、説明文によるとDirection.east、Direction.west、Direction.north、Direction.southという「列挙」という形式で指定するとあります。列挙がなにかはここではあまり気にしなくて良いでしょう。Bool型がtrueとfalseしか受け付けないように、予め決まった候補だけを指定できるものと考えておいてください。ただしDirectionは省略して、.west、.southなどドット以降だけで大丈夫とも書かれています。というか、予測候補には単にwest、southとドットもなしで出てくるし、実際それでエラーにもならないみたいですね。まぁ、これは.placeメソッドの設計がたまたまそうであるということで、常にメソッドのパラメーターはそういうものである、ということではないので、ここではそういうものだと思っておきましょう。いつか自分でメソッドを設計することになったら、自分でその辺りも決めることになります。
今回、expertと打つのがめんどくさいので省略してexとしました。その場合、他のあらゆる部分でもそれに統一していることに注目してください(もちろんいままで通りexpertとしてもいいですし、全然別の名前をつけてみてもOKです)。
ナビゲーションとしては、「行き止まりまで進みつつ、途中見つけた宝石を取っていく」と「それをした後、突き当たりにあるスイッチを操作。また左右曲がれる方向に曲がる」という2つの関数を作成しました。スイッチ操作は上げるべき箇所と下げるべき箇所があるので、さっそくパラメータをもたせる技を活用してみました。以前のステージであったように、func文の先頭行にある()にup:boolと書いておきます。
1 |
func 行き止まりまで進みロック操作(<span style="color: #ff0000;">up</span>:Bool) { |
そうするとupという名前でtrueかfalseのどちらかを受け付けるようになります。そして関数内の処理で実際にturnLockする時のupにupを指定します。
1 |
ex.turnLock(up: <span style="color: #ff0000;">up</span>, numberOfTimes: 1) |
ややこしいですが、ひとつめのupはturnLockメソッドのパラメーターを区別する名前、:の後の2つ目のupはfunc文で決めた変数の名前です。赤字部分同士が対応付いています。
もし、区別しやすくするなら、それぞれisUpと変えてもOKです。
これで、上げるか下げるかだけは都度変更できる関数が実現し、一箇所違うだけなのにわざわざ別々の関数を用意する必要がなくなりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
//ex君を作成&配置。 let ex = Expert() world.place(ex, facing: south, atColumn: 1, row: 8) //2つの関数を用有 func 行き止まりまで宝石を集める() { while !ex.isBlocked { if ex.isOnGem { ex.collectGem() } ex.moveForward() } } //2つ目の関数。upという名前のBool値をパラメータとして受け付ける func 行き止まりまで進みロック操作(up:Bool) { //最初は1つ目の関数と同じ処理なので呼び出して済ませる 行き止まりまで宝石を集める() //ここからは2つ目の関数独自の処理 ex.turnLock(up: up, numberOfTimes: 1) //1つ目の関数で行き止まりまで進んで来た直後なので、ここでは //isBlockedかどうか確認せず、左右のブロック状態だけ見ればOK if ex.isBlockedLeft { ex.turnRight() } else { ex.turnLeft() } } //ここから本編 行き止まりまで進みロック操作(up: false) //upパラメータにfalseを指定して呼び出す 行き止まりまで進みロック操作(up: true) //upパラメータにtrueを指定して呼び出す 行き止まりまで宝石を集める() |
ワープを使ってみました
———————————————–
let expert = Expert()
var count = 1
func gem(Column:Int, Row:Int) {
world.place(expert, facing: .west, atColumn: Column, row: Row)
expert.collectGem()
}
func warp(roop:Int, C:Int, R:Int) {
var count = R
for i in 1 … roop {
gem(Column: C, Row: count)
count += 1
}
}
warp(roop: 5, C: 5, R: 1)
warp(roop:1, C:4, R:5)
warp(roop:4, C:1, R:5)