開啟與關閉傳送門
Portal On and Off
// 紀錄數量
var gems = 0 // 收集的寶石數
var turns = 0 // 轉反方向的次數 (每次迴轉都會 +2)
let portal = purplePortal
// 關閉傳送門
portal.close()
// 如果收集的寶石不到 7 個,就繼續走。
while gems < 7 {
walk(along: .left, onMove: {
// 往前走時,如果遇到寶石就收集、遇到開關就打開
if isOnGem {
collectGem()
gems += 1
} else if isOnClosedSwitch {
toggleSwitch()
}
}, onTurnOtherSide: { // 往反方向轉時,紀錄轉向的次數
turns += 1
if turns == 2 { portal.open() } // 第一次迴轉時,打開傳送門
if turns == 4 { portal.close() } // 第二次迴轉時,關閉傳送門
})
}
extension Portal {
func close() { isActive = false }
func open () { isActive = true }
}
// 貼著哪邊走的選項
enum Side {
case left, right
}
// 將「左右邊被擋住」的狀況放到同一個函數中處理。
func isBlockedOn(_ side: Side) -> Bool {
side == .left ? isBlockedLeft : isBlockedRight
}
// 將「向左右轉」放到同一個函數中處理。
func turn(_ side: Side) {
side == .left ? turnLeft() : turnRight()
}
// 轉反方向
func turnOtherSide(from side: Side) {
side == .left ? turnRight() : turnLeft()
}
typealias Handler = () -> Void
// ⭐️ 沿著某一邊走的策略,
// 將來可以寫入 Actor 的 extension 中。
func walk(
along side : Side = .left, // 沿著哪邊走(預設左邊)
onMove : Handler = {}, // 往前走一步時要做的事
onTurnOtherSide: Handler = {} // 往反方向轉時要做的事
) {
if !isBlockedOn(side) { // 如果指定邊沒擋住,就走這一邊
turn(side)
moveForward()
onMove()
} else if !isBlocked { // 不然如果前面沒擋住,就走前面
moveForward()
onMove()
} else { // 否則就轉向另一邊
turnOtherSide(from: side)
onTurnOtherSide()
}
}
Last updated