使用 && 或 || 转义 while 循环组合条件语句

Escaping while loop using && or || to combine conditional statements

我一直在使用 Swift Playgrounds 应用程序开始学习如何编程,所以不用说我是初学者(对我放轻松!)。

我正处于学习编码 1 的最后阶段 - 向右滚动,向左滚动。 None 我可以在网上找到的解决方案看起来像我的,但我的有效。

让我感到困惑的是为什么它会起作用——特别是它如何跳出 while 循环。

我找到的解决方案:

func navigateWall() {
    if isBlockedLeft && !isBlocked {
        moveForward()
    } else if isBlockedLeft && isBlocked {
        turnRight()
    } else if isBlockedRight && !isBlocked {
        moveForward()
    } else if isBlocked {
        turnLeft()
    }
}

while !isBlocked || !isBlockedLeft || !isBlockedRight {
    navigateWall()
    if isOnClosedSwitch {
        toggleSwitch()
    } else if isOnGem {
        collectGem()
    }
}

让我困惑的部分是逃避 while 循环。我在底部的内容似乎用伪代码读取为 "While Byte is not blocked forward or not blocked left or not blocked right, solve the puzzle."

但我真正想说的是,当字节到达迷宫的尽头时,他被挡在了右边 AND (&&) 左边 AND (&&) 前面,然后停止。

但是如果我使用

while !isBlocked && !isBlockedLeft && !isBlockedRight {

...Byte 一开始根本没有动 - 表面上是因为他被挡在了左边。

这是一段视频,其中有人解决了这个谜题,但使用了更多骇人听闻的代码而不是真正的算法(即,如果每次 运行 迷宫都重置为新配置,它就不会工作,比如有些关卡可以)。

https://www.youtube.com/watch?v=8xpEaCVSaTg

行:

while !isBlocked || !isBlockedLeft || !isBlockedRight {

应读作:

Keep going if either value is false. Don't stop until all are true

利用De Morgan's laws的魔力,可以写成:

while !(isBlocked && isBlockedLeft && isBlockedRight) {

可以读作:

Keep going until all are true

这两个是相同的条件,但一个比另一个更清楚。所以你的原始代码可以工作,但不太明显。

您的错误代码为:

while !isBlocked && !isBlockedLeft && !isBlockedRight {

表示:

Keep going as long as none are blocked.

当然这意味着一旦其中一个变为真,条件就等于真。不是你想要的。

在学习代码如何处理这个过程中获得了很多乐趣 (我唯一遗憾的是当你找到你的方式时你可以看到提示代码......至少有一个解决方案来比较会很酷)

这就是我完成最后一道拼图的方法

func gemPtrn() {
collectGem()
turnRight()
moveForward()
collectGem()
moveForward()
}
func switchPtrn() {
toggleSwitch()
turnLeft()
moveForward()
toggleSwitch()
moveForward()
}


while !isOnGem && !isOnOpenSwitch {
moveForward()

if isBlocked && isOnGem {
    gemPtrn()

} else if isBlocked && isBlockedRight {
    turnLeft()
    moveForward()
}

if isOnClosedSwitch {
    switchPtrn()
}

if isBlocked && isBlockedLeft {
    turnRight()
}


}