やることがたくさんあるので頭が混乱しそうですが、以下の三つの作業に分割して考えてみましょう。
- 角を適切に曲がりつつ前進
- 宝石をみつけたら3つまで取りつつカウント
- 閉スイッチを見つけたら4つまで開けつつカウント
ワープゾーンに惑わされずにコースを眺めると、宝石ゾーンが先、スイッチゾーンが後に続いていることがわかります。そこで、一番外側のループは「閉スイッチ4つを開け終わるまで」として、その繰り返しの中で宝石があれば3つまで取るというアプローチで考えてみます(もちろん他にも方法はあります)。
変数toggleは最初0で段々増えていきますので、「4未満ならば(<4)」という条件式でwhileループを組みます。toggleが3の時はループを実行します。4ならしません。ループを実行中に1増える可能性があるので、もし「4以下ならば」(<=4)にしてしまうと、toggleが4の時にもループが実行され最大で5になってしまう場合があるので、今回は「4未満」が適しています。
ナビゲーション処理としては、右に曲がるべき時と左に曲がるべき時があります。全ての角はどちらか一方にしか曲がれないようなので、isBlockLeftやisBlockRightを活用して反対側に曲がるようにします。また前方が行き止まりであることは共通条件なので、二重ifにして外に出して、
1 2 3 4 5 6 7 |
if isBlocked { if isBlockedLeft { turnRight() } else { turnLeft() } } |
のように書く方法もあります。 宝石処理、スイッチ処理はいままで何度も出てきた通りですが、処理をするのとセットでカウンターに1を足すのを忘れずに。
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 |
var gem = 0 //取った宝石のカウンター var toggle = 0 //開いたスイッチのカウンター //スイッチを4つ開くまで繰り返す while toggle < 4 { moveForward() //ナビゲーション処理 if isBlockedLeft && isBlocked { turnRight() } else if isBlocked { turnLeft() } //途中、宝石があったら処理 if isOnGem { if gem < 3 { gem += 1 collectGem() } } //途中、閉スイッチがあったら処理 if isOnClosedSwitch { if toggle < 4 { toggle = toggle + 1 toggleSwitch() } } } |
14行目と15行目、21行目と22行目は、それぞれ二重のif文ですが、&&を使ってまとめることもできます。是非チャレンジしてみてください。