Question regarding If Elif Else And

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Eiliya
Regular
Posts: 148
Joined: Tue Dec 04, 2012 6:21 am
Contact:

Question regarding If Elif Else And

#1 Post by Eiliya »

I am not quite sure how these statements (if that's what they are?) actually work. I know that you set them up so that the engine checks if something is true or not, and then performs certain actions based on the result of that check, but I don't really understand how they work when related to one another. Let me take an example from a simple combat script I am currently trying to create.

Code: Select all

label impact:
    $ rnd = renpy.random.randint(1,100)
    $ potential = rnd + p1_pow - e1_res
    if potential < 1:
        $ damage = 0
    elif potential > 0 and potential < 41:
        $ damage = 25 + (p1_lvl*1)
    elif potential > 40 and potential < 81:
        $ damage = 50 + (p1_lvl*3)
    else:
        $ damage = 75 + (p1_lvl*5)
In my mind, this code generates a random number between 1 and 100, adds the related modifiers to that value to calculate the final potential score and then starts by checking if the final result is less than 1. If it is, the attack does no damage. If it is, however, the script then proceeds to check if the result is above 0 but less than 41. If yes, it inflicts low damage. If no, it checks to see if the result is between 41 and 80, in which case it inflicts mid damage. If this is also false, the result has to be something not specified among these criteria (in other words, higher than 80) which causes the script to inflict high damage.

Code: Select all

label impact:
    $ rnd = renpy.random.randint(1,100)
    $ potential = rnd + p1_pow - e1_res
    if potential < 1:
        $ damage = 0
    elif potential < 41:
        $ damage = 25 + (p1_lvl*1)
    elif potential < 81:
        $ damage = 50 + (p1_lvl*3)
    else:
        $ damage = 75 + (p1_lvl*5)
Now, I'm thinking this code, due to the order in which the if/elif/else is placed, should work identically to the first one I posted. However, if the two elif statements were to swap locations, the first example would still work while the second one would be ruined, right? Also, what is the actual difference between a few separate if statements and a string of if/elif's?

Thanks for your time.

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Question regarding If Elif Else And

#2 Post by xela »

Those are statements. All of your assumptions are corrects, terminology is off at places but that's ok since you're providing code examples.

You don't normally write:

Code: Select all

elif potential > 0 and potential < 41:
because

Code: Select all

elif 0 < potential < 41:
is better readable.

Your second version of the code is even better, so I'd stick with that if it suits your needs. Difference between several if statements and if/elif/else statements is that all if statements will be evaluated one after another and the if/elif/else fork will not continue the evaluation after one of the statements is True or you have else there, which will always be ran if the code makes it that far.
Like what we're doing? Support us at:
Image

Onishion
Veteran
Posts: 295
Joined: Mon Apr 20, 2015 10:36 am
Contact:

Re: Question regarding If Elif Else And

#3 Post by Onishion »

Yeah, the thing to always remember about if-flow is that whenever it finds something is "True," it gives up entirely, (unless there is an "and" in there that makes it False).

So basically you want to line things up in such a way that it will check the most likely thing first, and only move to the next thing if that first thing is false.

As for this bit:
Also, what is the actual difference between a few separate if statements and a string of if/elif's?
I assume you mean:

Code: Select all

#something like this:        
if potential > 0 and potential < 41:
        $ damage = 25 + (p1_lvl*1)

#verses something like this?:
if potential > 0: 
    if potential < 41:
        $ damage = 25 + (p1_lvl*1)
So far as I know, they would function identically, but the second way is a bit messier here. I only use the stcacked method if I will have two or more if statements in there or if the first if statement gets so bloated with ands and ors that I get confused trying to parse it.

One thing you DO need to keep in mind if you use "and" and "or" in those if statements is that you need to pay attention to how they get grouped. if you say:

if A > 0 and B > 10 or C > 5

but you mean that it should only trigger while A is 0 and B >10 or C >5, then you need to use parentheses, otherwise it will trigger every time C is over 5, and will only trigger otherwise if both A is > 0 and B is over 10. So basically:

if A > 0 and B > 10 or C > 5
would fail on A: 0 B: 12 C: 3 but succeed on A: 0 B: 6 C: 6
while
if A > 0 and (B > 10 or C > 5)
would only trigger if A is definitely over 0, and either B>10 or C>5, but doesn't need both of those. Make sense?

And again, line up ands and ors so that the most likely scenarios get knocked out first and it can move on to the next thing, rather than saving the real kicker for last.

Oh, and on rereading, you may have been asking what is the different between
if A:
if B:
if C:

and

if A:
elif B:
elif C:

Well the difference is that in the latter case, if it is A, it NEVER bothers with checking against B or the else statement, it just moves on to after that stack. It only gets to the "if B" part if the "if A" check fails. Which you use depends entirely on how you want it to work. If you do want to never check B if A is true, then you want to use elifs. In most cases this makes things faster since once it finds the true response, it never has to bother checking the other ones.

On the other hand, if the things that happen after "if A" triggers might change B, so that B would trigger after that block has finished, and you want that to happen, then you might just want to use if statements like in the first case. There are plenty of cases where you'd want to use either, but typically if it doesn't matter, elif is the more efficient.

Post Reply

Who is online

Users browsing this forum: Majestic-12 [Bot]