Olivier Pons
Olivier Pons

Reputation: 15778

How to force all "or"

Because of "short-circuit operator", Python only evaluates the second argument if the first one is False.

I have a function like this:

def calcule_deplacements_possibles(self, y, x, idx, pp):
    idp = pp['id']
    if pp['piece'] == 'abeille':
        o = False
        o = self.glissement_test(y, x, -2, 0, -1, -1, -1, +1, idp) or o
        o = self.glissement_test(y, x, -1, +1, -2, 0, +1, +1, idp) or o
        o = self.glissement_test(y, x, +1, +1, -1, +1, +2, 0, idp) or o
        o = self.glissement_test(y, x, +2, 0, +1, +1, +1, -1, idp) or o
        o = self.glissement_test(y, x, +1, -1, +2, 0, -1, -1, idp) or o
        o = self.glissement_test(y, x, -1, -1, +1, -1, -2, 0, idp) or o
        if o:
            self.board[y][x]['b'][idx]['m'] = True

This is hexagonal type of cells so I need to try all of them, because glissement_test() adds some markers, so it has always to be called (here 6 times).

How to "force" those calls and use the results like in my code?

Upvotes: 0

Views: 68

Answers (3)

TigerhawkT3
TigerhawkT3

Reputation: 49310

Loop through each set of values you'd like to use, and then see whether they all occurred:

tests = [self.glissement_test(y, x, *vals, idp) for vals in ((-2, 0, -1, -1, -1, 1),
                                                             (-1, 1, -2, 0, 1, 1),
                                                             (1, 1, -1, 1, 2, 0),
                                                             (2, 0, 1, 1, 1, -1),
                                                             (1, -1, 2, 0, -1, -1),
                                                             (-1, -1, 1, -1, -2, 0))]

if any(tests):
    self.board[y][x]['b'][idx]['m'] = True

Note that integer literals are positive by default, so you don't need to specify e.g. +1 to get positive 1.

Upvotes: 3

Łukasz Rogalski
Łukasz Rogalski

Reputation: 23223

If glissement_test() somehow mutates state of self do not use it in conditional. It confuses person reading a code and makes your intent unclear.

Explicitly call all values, and then run a check:

t1 = self.glissement_test(y, x, -2, 0, -1, -1, -1, +1, idp)
t2 = self.glissement_test(y, x, -1, +1, -2, 0, +1, +1, idp)
t3 = self.glissement_test(y, x, +1, +1, -1, +1, +2, 0, idp)
t4 = self.glissement_test(y, x, +2, 0, +1, +1, +1, -1, idp)
t5 = self.glissement_test(y, x, +1, -1, +2, 0, -1, -1, idp)
t6 = self.glissement_test(y, x, -1, -1, +1, -1, -2, 0, idp)

# Now do the check
if t1 or t2 or t3 or t4 or t5 or t6:
    self.board[y][x]['b'][idx]['m'] = True

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385194

There's no way to turn off short-circuiting in Python (nor is there a short-circuit-free "or" operator) as far as I'm aware.

Code in a conditional shouldn't "do" things anyway, hence the convention of short-circuiting in most languages.

Compute the result of self.glissement_test first, assigning it to a variable, then check <that variable> or o.

Upvotes: 0

Related Questions