[Solved]Jump to Random Label

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
kaleidx
Newbie
Posts: 12
Joined: Sun Jul 31, 2011 11:45 pm
Contact:

[Solved]Jump to Random Label

#1 Post by kaleidx »

Maybe there's an easier way to do this, I'm not sure, but here's what I'm doing:

Code: Select all

#define a bunch of variables
    $mj1 = 0
    $ dj1 = 0
    $ dj2 = 1
    $ dj3 = 1
    $ etc ...

label questions_start:
    if dj1 == 10:
        jump after_questions
    mu "Next question!"

label start_random:
    $ mj1 = renpy.random.randint(2,16)

    if mj1 == 2:
        if dj2 == 2:
            jump start_random
        else:
            $ dj2 = 2
            jump question1
    if mj1 == 3:
        if dj3 == 2:
            jump start_random
        else:
            $ dj3 = 2
            jump question3
label question1: 
    $ dj2 = 2
    "Blah blah"
    $ dj1 += 1
    jump questions_start

label after_questions:
    "Blah"
So if you couldn't tell, I want a pool of random questions to ask the player but I don't want the same one asked twice. So that's why I added a separate variable for each possible jump to label. Once it jumps to it, it shouldn't jump to it again because it's asking for djx to == 2, right?
Still in testing, I sometimes still get repeat questions and I have no idea why.

Any one have any idea why?
Or I'm open to simpler alternatives as well.

Thanks for reading!
Last edited by kaleidx on Thu Apr 14, 2016 7:07 pm, edited 1 time in total.

Megaman Z
Miko-Class Veteran
Posts: 829
Joined: Sun Feb 20, 2005 8:45 pm
Projects: NaNoRenO 2016, Ren'Py tutorial series
Location: USA
Contact:

Re: Jump to Random Label

#2 Post by Megaman Z »

I'm pretty sure there's a more elegant way of doing this than what I'm about to describe here, but it should work. You will have to get dirty with some python, though:

What you have is a set of labels that you only want to be called once and in a random order, correct? In this case, why not make a list of the labels (as strings) and then shuffle the list at the start of the quiz section (in your example, immediately before the label "questions_start"). random.shuffle(list) (or renpy.random.shuffle(list)) will do an in-place shuffle of the list, randomizing the order of the contents.

After doing this, you'll need to change how you pick the question. Since your list should be randomized at this point, you should do two things:

First, check that the list actually has contents (or that you haven't given as many questions as you want to, in case you don't want to actually give all of the questions). This is actually trivial in Python, just do "if yourlisthere:" as a conditional statement - an empty list will return false, a non-empty list will count as true for that conditional statement. If you have a limit of questions to present, you can add that to the conditional (so, using variables you gave us, the resulting expression would be "if yourlisthere and dj1 < 10")

Second, assuming the previous check was successful (returned True), you simply pop off either the first element or the last element of the list and feed it to either renpy.jump(label) or renpy.call(label, *args, **kwargs), depending on exact implementation. You can also increment the question counter here instead of in the labels themselves. It is the popping that requires us to check if the list is empty or not previously, as without a question limit, it is inevitable that we will pop all items in the list, eventually having an empty list.

hurriedly-written-not-fully-tested code follows:

Code: Select all

#define only two variables since we only need those two...
    $ dj1 = 0
    $ questionlist = ["question1", "question2", "question3"] # this would be your list of questions.

# ... ... ...


# assume we arrive at questions_start by falling into it, not by jump/call
    $ renpy.random.shuffle(questionlist) # shuffle the questionlist

label questions_start:
    python:
        if questionlist and dj1 < 10:
            dj1 += 1 #increment dj1
            renpy.jump(questionlist.pop(0)) #takes first item in the list, removes it from the list, and jumps to it
            # renpy.jump(questionlist.pop()) #this would take the last item in the list instead of the first.
        else: # either we had 10 questions asked already or we have no questions left
            renpy.jump("after_questions")

label question1:
    "This is question 1"
    jump questions_start

label question2:
    "This is question 2"
    jump questions_start

label question3:
    "This is question 2"
    jump questions_start

label after_questions:
    "Blah"
Another potential advantage of this is you can also add to that list in the middle of the game by utilizing the standard list append method (questionlist.append(x)), insert method (questionlist.insert(i, x)), or extend method (questionlist.extend(L)). x would be a new item to add (in our case, a label as string), i is the index of the location in the list to insert an item (0 is the front), and L would be a list of items to add to the end (in our case, a second list of labels as strings).
~Kitsune Zeta

kaleidx
Newbie
Posts: 12
Joined: Sun Jul 31, 2011 11:45 pm
Contact:

Re: Jump to Random Label

#3 Post by kaleidx »

That is definitely much neater and compact then what I had and it seems to be working really well.
I later realized that my original script seemed to only repeat the first question more than once which I'm guessing meant there was something wrong with my if statements because it ignored both of them and just fell to my first question at the bottom of my list.

Anyways, I appreciate the help, it seems to be working much more randomly.

Megaman Z
Miko-Class Veteran
Posts: 829
Joined: Sun Feb 20, 2005 8:45 pm
Projects: NaNoRenO 2016, Ren'Py tutorial series
Location: USA
Contact:

Re: Jump to Random Label

#4 Post by Megaman Z »

kaleidx wrote:That is definitely much neater and compact then what I had and it seems to be working really well.
I later realized that my original script seemed to only repeat the first question more than once which I'm guessing meant there was something wrong with my if statements because it ignored both of them and just fell to my first question at the bottom of my list.

Anyways, I appreciate the help, it seems to be working much more randomly.
...you know what I just realized looking at your script again? Probably what you noticed and [hopefully] fixed: there's no else clause in your if-then tree and no catch-all after the tree. which means if NONE of the items are true, it just passes through... and falls straight through to the next label. This can probably be trivially fixed by sticking a jump start_random right before the question1 label. (I blame me not noticing this on being too used to doing call labels and returns, which would probably be more appropriate here)

That said, in terms of efficiency, it would probably be better to adopt an approach similar to what I had outlined in my post. In your script, there is the potential for a lot of lag time if the Random function keeps picking the same numbers over and over again (it shouldn't be an infinite loop because, in theory, it should eventually pick every number it can in the range given). Contrast this against my script, where once a label is picked from the list, it is immediately removed from that list so that it cannot be picked again (barring the case where the label was added multiple times to the list, in which case only one occurrence of the label would be removed). The only thing you have to keep in mind is the labels have to actually exist. Otherwise... Well, Ren'Py doesn't like trying to jump to labels that don't exist.
~Kitsune Zeta

Post Reply

Who is online

Users browsing this forum: No registered users