Bingo minigame stops after two loops

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
User avatar
voluorem
Regular
Posts: 29
Joined: Fri Jun 24, 2022 3:32 pm
Projects: Sweet Release
Discord: voluorem
Contact:

Bingo minigame stops after two loops

#1 Post by voluorem »

So I've been trying to make a bingo minigame and it... sort of works? It works perfectly until it calls 2 balls and then it just stops and I have no idea why. I'm assuming it's something to do with how it moves around the code but it might just be something minor and obvious that I'm not seeing (I am not an expert in Python lol). Regardless, I don't know how to fix it.
(And I know you can't actually mark off any of the squares, it was giving me an error code and I didn't feel like figuring that part out so I deleted it lol)

Code: Select all

default bingolist = list(range(1, 76))
default nextnumber = 0
default nextletter = " "
default cardbnumbers = ['0', '0', '0', '0', '0']
default cardinumbers = ['0', '0', '0', '0', '0']
default cardnnumbers = ['0', '0', '0', '0', '0']
default cardgnumbers = ['0', '0', '0', '0', '0']
default cardonumbers = ['0', '0', '0', '0', '0']
label bingocardrandom:
    $ cardbnumbers = renpy.random.sample(range(1, 16), 5)
    $ cardinumbers = renpy.random.sample(range(16, 31), 5)
    $ cardnnumbers = renpy.random.sample(range(31, 46), 5)
    $ cardgnumbers = renpy.random.sample(range(46, 61), 5)
    $ cardonumbers = renpy.random.sample(range(61, 76), 5)
    return
transform ballspin:
    rotate 0
    linear 3.0 rotate 1080
transform ballmove:
    xpos 1000
    ypos -100
    ease 3.0 ypos 600
screen bingoball:
    hbox:
        button:
            add "images/etc/bingoball[nextletter].png" at ballspin, ballmove
            text "[nextnumber]"
            action None


label get_number:
    $ idx = renpy.random.randint(0, len(bingolist)-1)
    $ nextnumber = bingolist.pop(idx)
    return

screen bingo():
    timer 5.0 action Call("bingocall")
    grid 5 6:
        xalign 0.25
        yalign 0.7
        spacing 20
        text "B" xalign 0.5 yalign 0.5 size 80
        text "I" xalign 0.5 yalign 0.5 size 80
        text "N" xalign 0.5 yalign 0.5 size 80
        text "G" xalign 0.5 yalign 0.5 size 80
        text "O" xalign 0.5 yalign 0.5 size 80
        ## 1
        textbutton "[cardbnumbers[0]]" xalign 0.5 yalign 0.5 text_size 60 ## 1
        textbutton "[cardinumbers[0]]" xalign 0.5 yalign 0.5 text_size 60 ## 2
        textbutton "[cardnnumbers[0]]" xalign 0.5 yalign 0.5 text_size 60 ## 3
        textbutton "[cardgnumbers[0]]" xalign 0.5 yalign 0.5 text_size 60 ## 4
        textbutton "[cardonumbers[0]]" xalign 0.5 yalign 0.5 text_size 60 ## 5
        ## 2
        textbutton "[cardbnumbers[1]]" xalign 0.5 yalign 0.5  text_size 60 ## 6
        textbutton "[cardinumbers[1]]" xalign 0.5 yalign 0.5  text_size 60 ## 7
        textbutton "[cardnnumbers[1]]" xalign 0.5 yalign 0.5  text_size 60 ## 8
        textbutton "[cardgnumbers[1]]" xalign 0.5 yalign 0.5  text_size 60 ## 9
        textbutton "[cardonumbers[1]]" xalign 0.5 yalign 0.5  text_size 60 ## 10
        ## 3
        textbutton "[cardbnumbers[2]]" xalign 0.5 yalign 0.5  text_size 60 ## 11
        textbutton "[cardinumbers[2]]" xalign 0.5 yalign 0.5  text_size 60 ## 12
        textbutton "FREE" xalign 0.5 yalign 0.5  text_size 60 ## 13
        textbutton "[cardgnumbers[2]]" xalign 0.5 yalign 0.5  text_size 60 ## 14
        textbutton "[cardonumbers[2]]" xalign 0.5 yalign 0.5  text_size 60 ## 15
        ## 4
        textbutton "[cardbnumbers[3]]" xalign 0.5 yalign 0.5  text_size 60 ## 16
        textbutton "[cardinumbers[3]]" xalign 0.5 yalign 0.5  text_size 60 ## 17
        textbutton "[cardnnumbers[3]]" xalign 0.5 yalign 0.5  text_size 60 ## 18
        textbutton "[cardgnumbers[3]]" xalign 0.5 yalign 0.5  text_size 60 ## 19
        textbutton "[cardonumbers[3]]" xalign 0.5 yalign 0.5  text_size 60 ## 20
        ## 5
        textbutton "[cardbnumbers[4]]" xalign 0.5 yalign 0.5  text_size 60 ## 21
        textbutton "[cardinumbers[4]]" xalign 0.5 yalign 0.5  text_size 60 ## 22
        textbutton "[cardnnumbers[4]]" xalign 0.5 yalign 0.5  text_size 60 ## 23
        textbutton "[cardgnumbers[4]]" xalign 0.5 yalign 0.5  text_size 60 ## 24
        textbutton "[cardonumbers[4]]" xalign 0.5 yalign 0.5  text_size 60 ## 25


default count = 0
default currentbingolist = 0
label start:
    label bingostart:
        call bingocardrandom
    label bingoroll:
        show screen bingo
    label bingocall:
        $ count +=1
        call get_number
        if 1 <= nextnumber <= 15:
            $ nextletter = "b"
        elif 16 <= nextnumber <= 30:
            $ nextletter = "i"
        elif 31 <= nextnumber <= 45:
            $ nextletter = "n"
        elif 46 <= nextnumber <= 60:
            $ nextletter = "g"
        elif 61 <= nextnumber <= 75:
            $ nextletter = "o"
        call screen bingoball
        while count <= 75:
            jump bingoroll

    label bingostop:
        return

return

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Bingo minigame stops after two loops

#2 Post by zmook »

The first thing that jumps out at me is that you probably want "repeat True" in your timer statement.

Code: Select all

screen bingo():
    timer 5.0 repeat True action Call("bingocall")
Now it will continue every 5 seconds forever or until something dismisses the screen.
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Bingo minigame stops after two loops

#3 Post by zmook »

Oh, wait. I tried out your code, and see that oh yeah, your control flow is all messed up. 'show screen bingo' is not an interaction and does not pause the game, so immediately after drawing the bingo card your game continues to the next statement, which is 'label bingocall:' and continues from there. This gets a 'nextnumber' and 'nextletter', then calls screen 'bingoball'. 'call screen' *does* start an interaction, so renpy waits for user input, except there's nothing in 'bingoball' that does anything with user input, so it waits indefinitely. Then five seconds later, the timer in screen 'bingo' finishes and it calls label 'bingocall' for your second roll. This also calls screen 'bingoball' and waits. And now there is nothing to wait for.

I've fixed it up to avoid messing around with multiple screens and calling stacks of labels. And also to get rid of a lot of repetitive code. I had to simplify showing the "ball" because I don't have your graphics.

You'll need to add code for the player to actually do something: mark off squares and win the game, etc. If you want help with that, post what you have written so far and I'll show you how to add it.

Code: Select all

default bingocols = ("B", "I", "N", "G", "O")
default bingolist = list(range(1, 76))
default nextnumber = 0
default nextletter = " "
default cardnumbers = {c:[0,]*5 for c in bingocols}

label bingocardrandom:
    python:
        for (i,c) in enumerate(bingocols):
            cardnumbers[c] = renpy.random.sample(range(i*15+1, i*15+16), 5)
    return


transform ballspin:
    rotate 0
    linear 3.0 rotate 1080
transform ballmove:
    xpos 1000
    ypos -100
    ease 3.0 ypos 600



init python:
    def bingocall():
        global count, nextnumber, nextletter
        count +=1
        if not bingolist:
            return "done"   # returning any value other than None causes the screen to return
        idx = renpy.random.randint(0, len(bingolist)-1)
        nextnumber = bingolist.pop(idx)
        nextletter = bingocols[(nextnumber-1)//15]
        

screen bingo():

    timer 5.0 repeat True action Function(bingocall)
    text "remaining:" + " ".join([str(i) for i in bingolist]) align(0.05,0.95)

    grid 5 6:
        xalign 0.25
        yalign 0.7
        spacing 20
        for c in bingocols:
            text c xalign 0.5 yalign 0.5 size 80
        
        for i in range(5):
            for c in bingocols:
                textbutton str(cardnumbers[c][i]) align (0.5,0.5) text_size 60

    hbox:
        if nextnumber > 0:
            textbutton "[nextnumber]":
                text_size 100
                text_color "#fdb"
                action None


default count = 0
default currentbingolist = 0


label start:

    "ready to get a card"
    call bingocardrandom

    "ready to roll"
    call screen bingo

    "done"

return
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

User avatar
voluorem
Regular
Posts: 29
Joined: Fri Jun 24, 2022 3:32 pm
Projects: Sweet Release
Discord: voluorem
Contact:

Re: Bingo minigame stops after two loops

#4 Post by voluorem »

That's so much better, thank you so much!

So what I had for marking off squares/getting bingo wouldn't work anymore because it depended on each number on the card being linked to a variable, but now that all of the numbers are linked to one variable I have no idea how to mark off specific squares (I mean, granted, it didn't work in the first place. But now it works even less, lol). Where should I start with that?

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Bingo minigame stops after two loops

#5 Post by zmook »

Each number on the card is determined by a pair of variables, a column letter (B/I/N/G/O) and a row number (0-4). You have both of these ('c' and 'i') available at the time when you declare the card number textbutton. So you want to add an action to that button that looks something like:

Code: Select all

                $ cardnumber_style = "cardnumber_marked" if is_marked[c][i] else "cardnumber_unmarked"
                textbutton str(cardnumbers[c][i]):
                    align (0.5,0.5) 
                    style cardnumber_style
                    action Function(mark_card, c, i)
where you have to write a python function 'mark_card'. You also need to initialize an array 'is_marked' to all False at the same time the 'cardnumbers' array is randomized, and then the 'mark_card' function sets the appropriate entry to True when it's clicked. (I don't know if you want to write the logic to determine if the marking is correct at the time when the player tries to do it, or at the end when they have their card "inspected". You could do it either way depending how you want the game to work.)

You also need to create a pair of textbutton styles "cardnumber_marked" and "cardnumber_unmarked".
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Bingo minigame stops after two loops

#6 Post by zmook »

Oh, I just noticed, when I was cleaning your code up I lost the special case of the middle square being 'FREE'.

Code: Select all

        for i in range(5):
            for c in bingocols:
                if c=="N" and i==2:
                   $ square_txt = "FREE"
                else:
                   $ square_txt = str(cardnumbers[c][i]) 
                textbutton square_txt align (0.5,0.5) text_size 60 action Function(mark_card, c, i)
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

User avatar
voluorem
Regular
Posts: 29
Joined: Fri Jun 24, 2022 3:32 pm
Projects: Sweet Release
Discord: voluorem
Contact:

Re: Bingo minigame stops after two loops

#7 Post by voluorem »

I got everything down except for the mark_card function. I'm not quite sure about the syntax for checking if the marking is correct when the player tries to mark it.

User avatar
zmook
Veteran
Posts: 421
Joined: Wed Aug 26, 2020 6:44 pm
Contact:

Re: Bingo minigame stops after two loops

#8 Post by zmook »

voluorem wrote: Sat Jun 25, 2022 7:03 pm I got everything down except for the mark_card function. I'm not quite sure about the syntax for checking if the marking is correct when the player tries to mark it.

Code: Select all

    def mark_card(c,i):
        if (c=="N" and i==2):
            return      # clicked the FREE square, do nothing
        clicked_number = cardnumbers[c][i]
        if clicked_number == nextnumber:
           is_marked[c][i] = True 
colin r
➔ if you're an artist and need a bit of help coding your game, feel free to send me a PM

Post Reply

Who is online

Users browsing this forum: Google [Bot]