How are OR statements evaluated in distanceTo? (python)


#1

Hi everyone

Let’s say I’ve defined points A, B, C , and D. What I want to do is tell my hero to move to point A if the distanceTo(A) is less than the other three points. Here’s the code I wrote

        if self.distanceTo(A) < self.distanceTo((B or C or D)):
            self.move(A)

Now there are two ways I could see this being evaluated: the first is that it checks to see if distanceTo(A) is less than ANY of the other three, the second is if distanceTo(A) is less than all of the three.

After playtesting this a bit, my suspicion is that the prior is true, while my goal is the latter. I thought of using AND, but wouldn’t it then add the distanceTo B, C, D? Then the result would always be that the distanceTo(A) is always less, even if, say, I was right next to B.

FYI, I have a background in formal logic, so I’m very familiar with the logic behind OR and AND statements, but I have no real background in programming.

Thanks!


#2

The expression:

self.distanceTo((B or C or D))

Is evaluated as:

intermediateValue = (B or C or D)
self.distanceTo(intermediateValue)

That is, (B or C or D) will evaluate to B (as all these objects are truthy).
Then the distanceTo method will be called passing only one point object.
That is, this code:

if self.distanceTo(A) < self.distanceTo((B or C or D)):

Is equivalent to:

if self.distanceTo(A) < self.distanceTo(B):

What you want is:

distanceToA = self.distanceTo(A)
if distanceToA < self.distanceTo(B) and distanceToA < self.distanceTo(C) and distanceToA < self.distanceTo(D):
    self.move(A)

You can reduce the repetition using the built-in all function and a list comprehension to map the [B, C, D] points to a list of booleans representing whether A is closer to self than them:

distanceToA = self.distanceTo(A)
if all([distanceToA < self.distanceTo(point) for point in [B, C, D]]):
    this.move(A)