Reputation: 15
I've been using the Swift Playgrounds app to start learning how to program, so it goes without saying I'm a beginner (and go easy on me!).
I'm on the last stage on Learn to Code 1 - Roll Right, Roll Left. None of the solutions I can find online look like mine, but mine works.
What I'm confused about is why it works - in particular, how it escapes the while loop.
The solution I found:
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()
}
}
The part that confuses me is escaping the while
loop. What I have there at the bottom is seems to read in pseudo code as "While Byte is not blocked forward or not blocked left or not blocked right, solve the puzzle."
But what I'm really trying to say is when Byte gets to the end of the maze and he is blocked on the right AND (&&) on the left AND (&&) in front, then stop.
But if I use
while !isBlocked && !isBlockedLeft && !isBlockedRight {
...Byte doesn't move at all at the start - ostensibly because he's blocked on the left.
Here's a video of someone solving the puzzle but using more hacky code instead of a real algorithm (i.e., it wouldn't work if the maze reset into a new configuration each time you ran it, like some of the levels do).
https://www.youtube.com/watch?v=8xpEaCVSaTg
Upvotes: 0
Views: 1315
Reputation: 1
Having quite some fun with learning how code works with this (Only thing i regret is when u found ur way u can see the hint code...it will be cool to at least have a solution to compare)
This is how I did this last puzzle
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()
}
}
Upvotes: 0
Reputation: 318854
The line:
while !isBlocked || !isBlockedLeft || !isBlockedRight {
should be read as:
Keep going if either value is false. Don't stop until all are true
Using the magic of De Morgan's laws, that can be written as:
while !(isBlocked && isBlockedLeft && isBlockedRight) {
which can be read as:
Keep going until all are true
These are both the same condition but one is clearer than the other. So your original code works but it's less obvious.
You incorrect code of:
while !isBlocked && !isBlockedLeft && !isBlockedRight {
means:
Keep going as long as none are blocked.
Of course this means that as soon as one of those becomes true, the condition equates to true. Not what you want.
Upvotes: 2