大きく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に変更しました。
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
let totalGem = randomNumberOfGems //totalGemに取るべき宝石の数がセットされる(毎回違う) //昇降スイッチを操作するexくんを作成して配置 let ex = Expert() //world.place(ex, facing: north, atColumn: 1, row: 4) //旧バージョンではatColumn:1でした world.place(ex, facing: north, atColumn: 0, row: 4) //宝石を取るchくんを作成して配置 let ch = Character() world.place(ch, facing: north, atColumn: 3, row: 0) var gems = 0 //取った宝石の数を記録する変数 //今いる道を突き当たりまで進みつつ、宝石があれば取る関数 func jumpToEdge() { for i in 1 ... 6 { //宝石があり、かつまだ取り足りなければ if ch.isOnGem && gems < totalGems{ ch.collectGem() gems += 1 //取ったらカウンタも1増やしていく } //行き止まりならジャンプ、でなければ前進 if ch.isBlocked { ch.jump() } else { ch.moveForward() } } } ex.turnLock(up: true, numberOfTimes: 1) //exくんにフロート板を操作させる //ここから本編 //規定数の宝石を集めてないうちはループ while gems != totalGems { jumpToEdge() //作成した関数を呼び出す //上の関数で端まて来たら隣の道に移動する。 //左右とも行き止まりなら振り返る if ch.isBlockedLeft && ch.isBlockedRight { ch.turnRight() ch.turnRight() //右が行き止まりなら左の道へ } else if ch.isBlockedRight { ch.turnLeft() ch.moveForward() ch.turnLeft() //左が行き止まりなら右の道へ } else if ch.isBlockedLeft { ch.turnRight() ch.moveForward() ch.turnRight() } } |