[Code] Jacks Or Better draw poker

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
User avatar
plastiekk
Regular
Posts: 112
Joined: Wed Sep 29, 2021 4:08 am
Contact:

[Code] Jacks Or Better draw poker

#1 Post by plastiekk »

A classic draw poker game as a give back to the community have fun with it.
Image

Customize your Level like this:

Code: Select all

label start:

    # set up a level 
    # in this case we start with 50 points and need 1000 to win,
    # a bad hand cost 10

    $ my_points = 50        # start with 50 points
    $ game_over = False     
    $ game_cost = 10        # bad hand cost must be divisible by 2
    $ maxlvl_points = 1000  # 1000 ends the round
    $ kappa = True          # debug informations on (cheat)
    
    "Level 1: Reach 1000 points, good luck!"
    call start_poker 

    if game_over:
        "You lose."
        
    else:
        "Congratulations!"
        
    
    return

And here is the code.

Code: Select all

# Jacks Or Better poker game
# by plastiekk 
#
# cards images are public domain
# sound fx by SFBGames made with chiptone 
# (https://sfbgames.itch.io/chiptone)

# set up points
default rf_points = 4000            # royal flush
default sf_points = 2000            # straight flush
default fk_points = 1000            # four of a kind
default fh_points = 700             # full house
default fl_points = 500             # flush
default st_points = 300             # straight
default tk_points = 200             # three of a kind
default tp_points = 100             # two pairs
default jb_points = 50              # jacks or better

default my_points = 50              # start with 50 points
default game_cost = 10              # pay 10 points 
default maxlvl_points = 1000        # maximal points per round

init python:
    # function to count stuff
    def countX(lst, x): 
        count = 0
        for ele in lst: 
            if (ele == x): 
                count = count + 1
        return count 
    # function to add points    
    def add_points(n):
        global my_points, maxlvl_points
        
        if my_points >= maxlvl_points:
            my_points = maxlvl_points
            return
        x = 0 
        while x <n:
            my_points += 10
            if my_points >= maxlvl_points:
                my_points = maxlvl_points
            renpy.pause(0.01)
            
            renpy.restart_interaction()
            x +=10
        
        renpy.with_statement(Dissolve(0.5))
        return
    # function to decrement points
    def dec_points():
        global my_points, game_cost
        x = game_cost
        y = game_cost // 2
        while x >0:
            my_points -= y
            renpy.pause(0.01)
            renpy.restart_interaction()
            x -= y

    
    # function to pick card images 
    def assemble_images(n=0):
        global player_image, player_hand
        
        while n < 5:

            if player_hand[n].startswith("♦"):
                player_image[n] ="cards/diamonds_"
            
            if player_hand[n].startswith("♥"):
                player_image[n] ="cards/hearts_"
            
            if player_hand[n].startswith("♠"):
                player_image[n] ="cards/spades_"

            if player_hand[n].startswith("♣"):
                player_image[n] ="cards/clubs_"
            
            if player_hand[n].endswith("A"):
                player_image[n] = player_image[n] + "ace"
            
            if player_hand[n].endswith("K"):
                player_image[n] = player_image[n] + "king"
            
            if player_hand[n].endswith("Q"):
                player_image[n] = player_image[n] + "queen"
            
            if player_hand[n].endswith("J"):
                player_image[n] = player_image[n] + "jack"
            
            if player_hand[n].endswith("10"):
                player_image[n] = player_image[n] + "10"
            
            if player_hand[n].endswith("9"):
                player_image[n] = player_image[n] + "9"
            
            
            if player_hand[n].endswith("8"):
                player_image[n] = player_image[n] + "8"
            
            if player_hand[n].endswith("7"):
                player_image[n] = player_image[n] + "7"
            
            if player_hand[n].endswith("6"):
                player_image[n] = player_image[n] + "6"
            
            if player_hand[n].endswith("5"):
                player_image[n] = player_image[n] + "5"
            
            if player_hand[n].endswith("4"):
                player_image[n] = player_image[n] + "4"
            
            if player_hand[n].endswith("3"):
                player_image[n] = player_image[n] + "3"
            
            if player_hand[n].endswith("2"):
                player_image[n] = player_image[n] + "2"
            
            
            player_image[n] = player_image[n] + ".png"
            n +=1


        return player_image
        
    # function to play a sound
    def button_snd(trans=0,at=0,st=0):
        global snd_file
        renpy.sound.play(snd_file)
        return

 
default snd_file ="audio/button.wav"

default pl_hand = []    # just a tmp list used in a label

default shema =""       # used for straight combinations
default shemb =[]       # used for pairs and other combinations
default player_image = ["x","x","x","x","x"]

default kappa = True               # set to True to see debug informations (cheat)
default game_over = False

# slots hold/draw
default c_slot0 = True
default c_slot1 = True
default c_slot2 = True
default c_slot3 = True
default c_slot4 = True

default anim_slot0 = True
default anim_slot1 = True
default anim_slot2 = True
default anim_slot3 = True
default anim_slot4 = True

# create the default deck, 52 cards
default card_deck =[
"♥A","♦A","♠A","♣A",                        # aces
"♥2","♦2","♠2","♣2",                        # 2
"♥3","♦3","♠3","♣3",                        # 3
"♥4","♦4","♠4","♣4",                        # 4
"♥5","♦5","♠5","♣5",                        # 5 
"♥6","♦6","♠6","♣6",                        # 6
"♥7","♦7","♠7","♣7",                        # 7     
"♥8","♦8","♠8","♣8",                        # 8  
"♥9","♦9","♠9","♣9",                        # 9
"♥10","♦10","♠10","♣10",                    # 10 
"♥J","♦J","♠J","♣J",                        # jacks 
"♥Q","♦Q","♠Q","♣Q",                        # queens
"♥K","♦K","♠K","♣K"                         # kings
]

# combinations
default straight_combinations = [
"2345A","23456","34567","45678","56789","6789T","789TJ","89TJQ","9TJQK","TJQKA"
]

# the play_deck
default play_deck = []
default cards_tint = "#f5e0a1ff"    # to make the cards looking smokier :)

# hands
default player_hand = []

#####################
# fancy outlines
define gui.name_text_outlines = [ (2.5, "#000000", 4, 3,) ]
define gui.text_outlines = [ (2.5, "#000000", 0, 0) ]

###################
label new_deck:
    hide screen show_hand
    hide screen hold_draw
    with Dissolve(0.22)
    play sound "audio/shuffle.wav"
    
    $ player_hand.clear()
    $ play_deck.clear()
    $ shema =""
    $ shemb.clear()
    $ c_slot0 = True
    $ c_slot1 = True
    $ c_slot2 = True
    $ c_slot3 = True
    $ c_slot4 = True


    $ anim_slot0 = True
    $ anim_slot1 = True
    $ anim_slot2 = True
    $ anim_slot3 = True
    $ anim_slot4 = True

    $ i = 0
    while i < 30:                       # shuffle ~30 times   
        $ play_deck = card_deck[:]
        $ renpy.random.shuffle(play_deck)
        $ renpy.pause(0.001,hard=True)
        $ renpy.restart_interaction
        $ i+=1
    return


label pop_cards(player="Null", count=0, deck="Null"):
    if player == "Null" or count == 0 or deck == "Null":
        "Error in label call."
        return
    while count >0 :
        $ card_buffer = deck.pop(0)
        
        $ count -=1
        $ player.append(card_buffer)
    return 

#####################################
# game loop

label start_poker:
    if game_over:
        # "Game over."
        return
        
    if my_points >= maxlvl_points:
        # "Congratulations!"
        return

    call new_deck 
    show screen debug_poker_screen
    
    $ player_hand = []
    call pop_cards(player_hand,5,play_deck)     # draw cards
   

    # if you want to "test" your combinations, this is the right place to do it
    # diamonds = ♦ (D)
    # hearts = ♥  (H)
    # spades = ♠ (S)
    # clubs = ♣ (C)
    
    # $ player_hand =["♥2","♥3","♥A","♥5","♥4"]   # straight flush
    # $ player_hand =["♣K","♣J","♣A","♣Q","♣10"]   # royal flush
    # $ player_hand =["♣K","♣J","♣9","♣Q","♣2"]   # flush
    
    # assemble image names
    $ assemble_images()
    call draw_cards 
    call make_sheme(player_hand) 

    jump start_poker
    
#####################################
# split hand to a mashine readable sheme 
label make_sheme(pl_hand):


    $ shema = ""
    $ shemb.clear()
    $ c_aces = sum(1 for x in pl_hand if x.endswith("A"))
    $ shemb.append(c_aces)
    if c_aces >0:
        $ x = c_aces
        while x >0:
            $ shema = shema+"A"
            $ x -=1
    $ c_kings = sum(1 for x in pl_hand if x.endswith("K"))
    $ shemb.append(c_kings)
    if c_kings >0:
        $ x = c_kings 
        while x >0:
            $ shema = shema+"K"
            $ x -=1

    $ c_queens = sum(1 for x in pl_hand if x.endswith("Q"))
    $ shemb.append(c_queens)
    if c_queens >0:
        $ x = c_queens
        while x >0:
            $ shema = shema+"Q"
            $ x -=1 
    $ c_jacks = sum(1 for x in pl_hand if x.endswith("J"))
    $ shemb.append(c_jacks)
    if c_jacks >0:
        $ x = c_jacks
        while x >0:
            $ shema = shema+"J"
            $ x -=1 
    
    $ c_tens = sum(1 for x in pl_hand if x.endswith("10"))
    $ shemb.append(c_tens)
    if c_tens > 0:
        $ x = c_tens
        while x >0:
            $ shema = shema+"T"
            $ x -=1 
    $ c_nines = sum(1 for x in pl_hand if x.endswith("9"))
    $ shemb.append(c_nines)
    if c_nines >0:
        $ x = c_nines
        while x >0:
            $ shema = shema+"9"
            $ x -=1
    $ c_eights = sum(1 for x in pl_hand if x.endswith("8")) 
    $ shemb.append(c_eights)
    if c_eights >0:
        $ x = c_eights
        while x >0:
            $ shema = shema+"8"
            $ x -=1
    $ c_seven = sum(1 for x in pl_hand if x.endswith("7"))
    $ shemb.append(c_seven)
    if c_seven >0:
        $ x = c_seven
        while x >0:
            $ shema = shema+"7"
            $ x -=1
    $ c_sixes = sum(1 for x in pl_hand if x.endswith("6"))
    $ shemb.append(c_sixes)
    if c_sixes >0:
        $ x = c_sixes
        while x >0:
            $ shema = shema+"6"
            $ x -=1 
    $ c_fives = sum(1 for x in pl_hand if x.endswith("5"))
    $ shemb.append(c_fives)
    if c_fives >0:
        $ x = c_fives
        while x >0:
            $ shema = shema+"5"
            $ x -=1
    $ c_fours = sum(1 for x in pl_hand if x.endswith("4"))
    $ shemb.append(c_fours)
    if c_fours >0:
        $ x = c_fours
        while x >0:
            $ shema = shema+"4"
            $ x -=1  
    $ c_threes = sum(1 for x in pl_hand if x.endswith("3"))
    $ shemb.append(c_threes)
    if c_threes >0:
        $ x = c_threes
        while x >0:
            $ shema = shema+"3"
            $ x -=1
    $ c_twos = sum(1 for x in pl_hand if x.endswith("2"))
    $ shemb.append(c_twos)
    if c_twos > 0:
        $ x = c_twos
        while x >0:
            $ shema = shema+"2"
            $ x -=1
    $ shema = shema[::-1] # reverse shema to compare with straigt_combinations

    # now compare the hand
    
    window hide # for some reason the window popped up (?) so we close it here again
    $ renpy.pause(0.22, hard=True) # a little pause because Ren'Py is too fast :)
    
    $ c_diamonds =  sum(1 for x in pl_hand if x.startswith("♦"))
    $ c_hearts =  sum(1 for x in pl_hand if x.startswith("♥"))
    $ c_spades =  sum(1 for x in pl_hand if x.startswith("♠"))
    $ c_clubs =  sum(1 for x in pl_hand if x.startswith("♣"))
    

    if c_diamonds == 5 or c_hearts == 5 or c_spades == 5 or c_clubs == 5:
        # "A flush! Check a straight or royal flush here!"
        if shema =="TJQKA" and c_clubs ==5:
            hide screen xnotify
            "ROYAL FLUSH!"
            # add points and stuff here
            $ snd_file = "audio/pickup.wav"
            $ tmp_txt = "+" + str(rf_points)
            show screen xnotify(tmp_txt) with dissolve
            $ snd_file = "audio/button.wav"
            $ add_points(rf_points)
            return

        if shema in straight_combinations:
            hide screen xnotify
            "STRAIGHT FLUSH!"
            # add points and stuff here
            $ snd_file = "audio/pickup.wav"
            $ tmp_txt = "+" + str(sf_points)
            show screen xnotify(tmp_txt) with dissolve
            $ snd_file = "audio/button.wav"
            $ add_points(sf_points)
            return
        
        # it's a flush otherwise
        "FLUSH!"
        
        hide screen xnotify
        $ snd_file = "audio/pickup.wav"
        $ tmp_txt = "+" + str(fl_points)
        show screen xnotify(tmp_txt) with dissolve
        $ snd_file = "audio/button.wav"
        $ add_points(fl_points)
        return

    # check for straight
    if shema in straight_combinations:
        "STRAIGHT!"
        hide screen xnotify
        $ snd_file = "audio/pickup.wav"
        $ tmp_txt = "+" + str(st_points)
        show screen xnotify(tmp_txt) with dissolve
        $ snd_file = "audio/button.wav"
        $ add_points(st_points)
        return
    
    # "No flush or straight possible, let's check 4 of a kind."
    
    if 4 in shemb:
        "FOUR OF A kIND!"
        hide screen xnotify
        
        $ snd_file = "audio/pickup.wav"
        $ tmp_txt = "+" + str(fk_points)
        show screen xnotify(tmp_txt) with dissolve
        $ snd_file = "audio/button.wav"
        # add points here
        $ add_points(fk_points)
        return
    # "No four of a kind, let's check a full house."
    if 3 in shemb:
        if 2 in shemb:
            "FULL HOUSE!"
            hide screen xnotify
            $ snd_file = "audio/pickup.wav"
            $ tmp_txt = "+" + str(fh_points)
            show screen xnotify(tmp_txt) with dissolve
            $ snd_file = "audio/button.wav"
            # add points here
            $ add_points(fh_points)
            return
    # "No full house let's check three of a kind."
    $ x = countX(shemb, 3)
    if x == 1:
        "THREE OF A KIND!"
        hide screen xnotify
        $ snd_file = "audio/pickup.wav"
        $ tmp_txt = "+" + str(tk_points)
        show screen xnotify(tmp_txt) with dissolve
        $ snd_file = "audio/button.wav"
        #add some points here
        $ add_points(tk_points)
        return



    # "Two pairs? Let's check:"
    $ x = countX(shemb, 2)      
    if x == 2:
        "TWO PAIRS!"
        hide screen xnotify
        $ snd_file = "audio/pickup.wav"
        $ tmp_txt = "+" + str(tp_points)
        show screen xnotify(tmp_txt) with dissolve
        $ snd_file = "audio/button.wav"
        # add some points here
        $ add_points(tp_points)
        return
    if x == 1:  # pairs
        #check AKQJ because we need jacks or better 
        #      0123
        if shemb[0]==2 or shemb[1]==2 or shemb[2]==2 or shemb[3]==2:
            "JACKS OR BETTER!"
            hide screen xnotify
            $ tmp_txt = "+" + str(jb_points)
            $ snd_file = "audio/pickup.wav"
            show screen xnotify(tmp_txt) with dissolve
            $ snd_file = "audio/button.wav"
            # add some points here
            $ add_points(jb_points)
            return
    
    # bad hand
    "Better luck next time."
    hide screen xnotify
    window hide
    if my_points >= game_cost:
        $ snd_file = "audio/arp1_down.wav"
        $ tmp_txt = "-" + str(game_cost)
        show screen xnotify(tmp_txt) with dissolve
        $ snd_file = "audio/button.wav"
        $ dec_points()
    else:
        $ game_over = True
    return
    
##########################

label draw_cards:
    call screen hold_draw 
    
    if c_slot0 == False:
        $ player_hand[0] = play_deck.pop(0)
        $ c_slot0 = True

    if c_slot1 == False:
        $ player_hand[1] = play_deck.pop(0)
        $ c_slot1 = True

    if c_slot2 == False:
        $ player_hand[2] = play_deck.pop(0)
        $ c_slot2 = True

    if c_slot3 == False:
        $ player_hand[3] = play_deck.pop(0)
        $ c_slot3 = True

    if c_slot4 == False:
        $ player_hand[4] = play_deck.pop(0)
        $ c_slot4 = True

    $ assemble_images()    
    hide screen hold_draw
    show screen show_hand

    return

#### transforms

transform cheat_glow:
    alpha 1.0
    ease 2.4 alpha 0.1
    ease 3.6 alpha 1.0
    repeat

transform score_glow:
    alpha 1.0
    ease 1.2 alpha 0.7 matrixcolor TintMatrix("#fad15f")
    ease 1.4 alpha 1.0 matrixcolor TintMatrix(cards_tint)
    repeat

transform cheat_move:
    
    xpos 0.5
    ease 2.0 xpos 0.48
    ease 2.0 xpos 0.5
    repeat


transform trans_c1:
    matrixcolor TintMatrix(cards_tint)
    xpos -2.0
    ease 0.6 xpos 0.0

transform trans_c2:
    matrixcolor TintMatrix(cards_tint)
    xpos -3.5
    ease 0.5 xpos 0.0

transform trans_c3:
    matrixcolor TintMatrix(cards_tint)
    xpos -4.0
    ease 0.4 xpos 0.0

transform trans_c4:
    matrixcolor TintMatrix(cards_tint)
    xpos -4.0
    ease 0.3 xpos 0.0

transform trans_c5:
    matrixcolor TintMatrix(cards_tint)
    xpos -5.0
    ease 0.2 xpos 0.0

###################
# screens
screen debug_poker_screen():
    if kappa:
        $ cards = len(play_deck)
        text "{size=-1}deck: [play_deck] - cards: [cards] {/size} "  
        text "{size=-1}next five cards: {/size} {size=+5}[play_deck[0]] - [play_deck[1]] - [play_deck[2]] - [play_deck[3]] - [play_deck[4]] {/size}" at cheat_move :
            yalign 0.18 xalign 0.5
        
    
    text "{size=+15}⚘  {/size}" style "score_style" at score_glow:
        xalign 0.82 yalign 0.85
    text "{size=+15} [my_points]{/size} " style "score_style" at score_glow:
        xalign 0.91 yalign 0.85   
    
  
style score_style is text:
    outlines [(4,"#000000",4 ,3)]
    bold True
    italic True

screen hold_draw():
    
    grid 5 1:
        spacing 30

        align (0.5,0.69)
        $ snd_file ="audio/button.wav"
        for i in range(0, len(player_hand)):
            frame:
                background None
                $ content = player_hand[i]
                $ da_var = "c_slot" + str(i)
                $ da_var2 = "anim_slot" + str(i)
                
                imagebutton:
                    focus_mask None
                    idle "held_idle.png"
                    hover "held_ground.png"
                    action [Function(button_snd),ToggleVariable(da_var,True, False),ToggleVariable(da_var2,True, False)] 

    grid 5 1:
        spacing 30
        align (0.5,0.39)
        
        # card 0
        frame at trans_c1 :
            background None
            if c_slot0:
                $ content = player_image[0]
                add "[content]"
            else:
                add "cards/back.png"

        # card 1
        frame at trans_c2:
            background None
            if c_slot1:
                $ content = player_image[1]
                add "[content]"
            else:
                add "cards/back.png"
        # card 2
        frame at trans_c3:
            background None
            
            if c_slot2:
                $ content = player_image[2]
                add "[content]"
            else:
                add "cards/back.png"

        # card 3
        frame at trans_c4:
            background None
            
            if c_slot3:
                $ content = player_image[3]
                add "[content]"
            else:
                add "cards/back.png"

        # card 4
        frame at trans_c5:
            background None
            
            if c_slot4:
                $ content = player_image[4]
                add "[content]"
            else:
                add "cards/back.png"


    frame:
        background None
        align(0.5,0.87)
        imagebutton:
            focus_mask None
            idle "done_idle"
            hover "done_hover"
            action [Function(button_snd),Return()]


transform swirl1:
    matrixcolor TintMatrix(cards_tint)
    choice:
        ypos -2.0 xpos -1.0
        ease 0.15 ypos 0.0 xpos 0.0
    choice:
        ypos -2.0 xpos 1.0
        ease 0.2 ypos 0.0 xpos 0.0
    choice:
        ypos -2.0 xpos -1.0
        ease 0.18 ypos 0.0 xpos 0.0
    choice:
        ypos -2.0 xpos 1.0
        ease 0.25 ypos 0.0 xpos 0.0


transform nonull:
    matrixcolor TintMatrix(cards_tint)

screen show_hand():
    zorder 2
    # fancy animation or stand still?
    if anim_slot0:
        $ gurk = nonull
    else:
        $ gurk = swirl1 
    if anim_slot1:
        $ gurk1 = nonull
    else:
        $ gurk1 = swirl1 
    if anim_slot2:
        $ gurk2 = nonull
    else:
        $ gurk2 = swirl1
    if anim_slot3:
        $ gurk3 = nonull
    else:
        $ gurk3 = swirl1 
    if anim_slot4:
        $ gurk4 = nonull
    else:
        $ gurk4 = swirl1  

    
    grid 5 1:
        spacing 30
        align (0.5,0.39)
        
        frame:
            background None
            
            if c_slot0:
                $ content = player_image[0]
                add "[content]" at gurk

        # card 1
        frame:
            background None
            
            if c_slot1:
                $ content = player_image[1]
                add "[content]" at gurk1

        # card 2
        frame:
            background None
            
            if c_slot2:
                $ content = player_image[2]
                add "[content]" at gurk2

        # card 3
        frame:
            background None
            
            if c_slot3:
                $ content = player_image[3]
                add "[content]" at gurk3

        # card 4
        frame:
            background None
            
            if c_slot4:
                $ content = player_image[4]
                add "[content]" at gurk4



screen xnotify(message):
    
    text message style "score_style" at fancy_transform

    timer 3.25 action Hide('xnotify')


transform fancy_transform:
    
    alpha 0.0
    size (95,50)
    function button_snd
    xalign 0.93
    yalign 0.87
    ease 1.0 alpha 1.0 
    ease 0.5 yalign 0.87 xalign 0.93
    parallel:
        ease 0.9 yalign 1.1 
    parallel:    
        ease 0.35 alpha 0.0
Or just try it by creating a new project and copying these files into it.
Attachments
game.zip
(1.45 MiB) Downloaded 78 times
Last edited by plastiekk on Thu Dec 22, 2022 12:06 am, edited 1 time in total.
Why on earth did I put the bread in the fridge?

User avatar
Alex
Lemma-Class Veteran
Posts: 3094
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: [Code] Jacks Or Better draw poker

#2 Post by Alex »

Uh, looks like audio files are missing - could you reupload archive?..

User avatar
plastiekk
Regular
Posts: 112
Joined: Wed Sep 29, 2021 4:08 am
Contact:

Re: [Code] Jacks Or Better draw poker

#3 Post by plastiekk »

Alex wrote: Wed Dec 21, 2022 4:45 pm Uh, looks like audio files are missing - could you reupload archive?..
Of course, I had to forget something. ^.^
archive updated.
Why on earth did I put the bread in the fridge?


Post Reply

Who is online

Users browsing this forum: No registered users