論理演算子
NOT 演算子を使う
目標: NOT 演算子を使って、マスに宝石がない場合は、進む方向を変えましょう。
回答コード例↓
func turnAround() {
for i in 1 ... 2 {
turnRight()
}
}
for i in 1 ... 4 {
moveForward()
if !isOnGem {
turnLeft()
for forGem in 1 ... 2 {
moveForward()
}
collectGem()
turnAround()
for returnWay in 1 ... 2 {
moveForward()
}
turnLeft()
} else {
collectGem()
}
}
◇何をやってるの?
func
キーワードを使って、振り返るための関数を作っています。- for 文を使って、4 マス進む間に「宝石がない場合」と「宝石がある場合」の 2 通りの処理を書いています。
- if 文と NOT 演算子(!)を使って、マスに宝石がないという場合の動作を定義しています。宝石がなければ左を向き、2 歩進んで宝石を取り、振り返って 2 歩んで戻ってきます。
- 宝石があれば、そのまま宝石を回収します。
◇コードを詳しく見てみよう!
※ turnAround()
はおなじみの関数なので省略しました。
for i in 1 ... 4 {
moveForward()
↑ 一番最初のマス用、および繰り返しの開始時に一歩前に進むようにするため、for 文の最初に moveForward()
を書きました。
if !isOnGem {
turnLeft()
for forGem in 1 ... 2 {
moveForward()
}
collectGem()
turnAround()
for returnWay in 1 ... 2 {
moveForward()
}
turnLeft()
} else {
collectGem()
}
↑ !isOnGem
とあるように、NOT 演算子を用いることで、false であるはずの isOnGem の Bool 値を true にする、すなわち宝石がない場合を表現できます。if 文の最初のブロックは true の場合に実行されるという性質があるので、 NOT 演算子を使って本来 false として判定される条件を true にしました。
宝石がある場合はそのまま collectGem()
を実行すればよいので、else ブロックに宝石を回収する関数を書いています。
NOT で周る
目標: NOT 演算子を使って、行き止まりになったら左に曲がりましょう。
回答コード例↓
for i in 1 ... 14 {
if isOnClosedSwitch {
toggleSwitch()
} else if isBlocked {
turnLeft()
moveForward()
} else if !isBlocked {
moveForward()
} else if !isOnClosedSwitch {
moveForward()
}
}
◇何をやってるの?
- 行き止まりになるまで進み、行き止まりになったら左に曲がるように NOT 演算子を使いつつ for 文を回しています。
- 判定基準は「スイッチの上か否か」、「行き止まりか否か」です。
◇コードを詳しく見てみよう!
if isOnClosedSwitch {
toggleSwitch()
} else if isBlocked {
turnLeft()
moveForward()
} else if !isBlocked {
moveForward()
} else if !isOnClosedSwitch {
moveForward()
}
↑ 最終目標である「オフのスイッチの上かどうか」から順に for 文を使ってコードを書きました。もし if 文の一番最初に isBlocked
が書かれていた場合、turnLeft()
を実行すると for ループから抜けるという挙動になるため、isBlocked
が成立する間、スイッチをトグることができなくなってしまいます。for 文の判断の順序はよく考えて記述するようにしましょう。
両方正しければ合格
目標: AND 演算子を使って、2 つの条件が両方とも当てはまったら道順を変えてみましょう。
回答コード例↓
func turnAround() {
for i in 1 ... 2 {
turnLeft()
}
}
for i in 1 ... 7 {
moveForward()
if isOnGem && !isBlockedLeft {
collectGem()
} else if isOnGem && isBlockedLeft {
collectGem()
turnRight()
for i in 1 ... 2 {
moveForward()
}
toggleSwitch()
turnAround()
for j in 1 ... 2 {
moveForward()
}
turnRight()
}
}
◇何をやってるの?
- 宝石があり、進行方向左が壁でなければ宝石を取って直進します。
- もし、宝石があり、尚且つ進行方向左が壁であれば右を向き、スイッチをトグりに行きます。
◇コードを詳しく見てみよう!
if isOnGem && !isBlockedLeft {
collectGem()
↑ 宝石があり、左側が壁ではない場合の条件分岐。単純に宝石を取るだけです。
} else if isOnGem && isBlockedLeft {
collectGem()
turnRight()
for i in 1 ... 2 {
moveForward()
}
toggleSwitch()
turnAround()
for j in 1 ... 2 {
moveForward()
}
turnRight()
}
↑ 宝石があり、尚且つ左側が壁の場合の条件分岐。右を向き、2 歩進んでスイッチをトグりに行きます。
一方でも正しければ合格
目標: OR 演算子を使って、2 つの条件のどちらかが当てはまる場合は、進む方向を変えましょう。
回答コード例↓
for i in 1 ... 13 {
if isOnGem {
collectGem()
} else if !isBlocked && !isBlockedLeft {
moveForward()
} else if isBlocked || isBlockedLeft {
turnRight()
moveForward()
}
}
◇何をやってるの?
- 前方と左側が両方壁でなければ前に進む、どちらか一方が壁であれば右に曲がります。
- ここでも、最終目的である宝石の回収を if 文の一番最初のブロックに記述して、条件を満たした場合に確実に回収できるようにしています。
このコードでは、特段複雑な分岐はしていないので詳細な説明は割愛します。
論理の迷宮
目標: 論理演算子と条件分岐コードを使って、ステージをクリアしましょう。
回答コード例↓
func turnAround() {
for i in 1 ... 2 {
turnLeft()
}
}
func collectYtoggle() {
collectGem()
toggleSwitch()
turnRight()
for i in 1 ... 2 {
moveForward()
}
collectGem()
turnAround()
for j in 1 ... 2 {
moveForward()
}
turnRight()
}
for i in 1 ... 8 {
moveForward()
if isOnGem && isOnClosedSwitch {
collectYtoggle()
}
else if !isOnGem && isOnClosedSwitch {
toggleSwitch()
turnLeft()
} else if isOnGem && !isOnClosedSwitch {
collectGem()
}
}
◇何をやってるの?
- スイッチの上に宝石があり、尚且つ右側が壁でない場合はその先にも宝石があるので、対応する関数を
collectYtoggle()
という名前で作りました。 - ここでは全て AND 演算子を使って条件判断を行なっています。
- 他の条件に反応してしまわないように、「宝石がある」、「オフのスイッチの上である」という条件を if 文の一番最初のブロックに記述しました。
- 「宝石が無く、オフのスイッチの上」のパターンと「宝石があり、オフのスイッチではない」というパターンの条件分岐も作成し、マップを奥まで進めるようにしています。
このコードも、特段複雑な分岐はしていないので説明は割愛します。