简体   繁体   中英

calling function multiple times with new results

I wanted to create a poker simulation that creates a certain number of 5-card poker hands, to see how many times hands I need to play till I get the royal flush...

I wrote a function that generates 5 cards but when i run the function multiple times it won't work --> i get 5*x cards instead of multiple hands with each 5 cards

import random

d = []
h = []

def cards():

    l1 = ["Herz", "Karo", "Pik", "Kreuz"]
    l2 = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
    for i in range(10):
        d.append([])
    for k in range(10):
        d[k].append(l1[random.randint(0, (len(l1) - 1))])
        d[k].append(l2[random.randint(0, (len(l2) - 1))])
    for a in d:
        if a not in h:
            h.append(a)
            if len(h) == 5:
                break
        else:
            continue
    return h

for i in range(2):
    print(cards())

When I run the code, I get the following:

[['Karo', 8], ['Herz', 5], ['Pik', 13], ['Herz', 12], ['Karo', 3]]

[['Karo', 8, 'Karo', 5], ['Herz', 5, 'Karo', 6], ['Pik', 13, 'Herz', 4], ['Herz', 12, 'Herz', 5], ['Karo', 3, 'Pik', 3], ['Karo', 8, 'Kreuz', 3], ['Karo', 9, 'Kreuz', 3], ['Pik', 13, 'Herz', 10], ['Pik', 6, 'Karo', 11], ['Karo', 2, 'Pik', 13], []]

Your code currently has global lists that it keeps appending to. This is almost certainly not what you want.

I would suggest creating a deck of cards, and sampling them without replacement to get a hand of five. You can get up to 10 such hands from a deck of 52 cards. A better way might be to create the deck and shuffle it, picking off 5 cards at a time until it contains fewer than 5 cards.

In either case, you could then pass each hand through a function that tests if it is a flush or whatever else you want.

All the tools you will need for this (until you use numpy), are in the itertools and random modules.

First create a global deck. There is no need to do this multiple times because it will slow you down to no purpose. The deck of cards won't change, only their order will:

rank = [str(x) for x in range(2, 11)] + list('JQKA')
suit = list('♠♥♦♣')
deck = list(''.join(card) for card in itertools.product(rank, suit))

Now you can use this deck to generate from 1 to 10 hands at a time with no repeating cards between them. The key is that shuffling the deck is done in place. You don't have to regenerate the deck every time:

def make_hands(cards=5, hands=None):
    if hands is None:
        hands = len(deck) // cards
    if cards * hands > len(deck):
        raise ValueError('you ask for too much')
    if cards < 1 or hands < 1:
        raise ValueError('you ask for too little')
    random.shuffle(deck)
    result = [deck[cards * i:cards * i + cards] for i in range(hands)]

You can change the desired number of cards per hand and hands per deck with this function. Let's say that you also have a function to check if a hand is a flush or not called isflush . You could apply it like this:

def how_many():
    shuffles = 0
    hands = 0
    while True:
        shuffles += 1
        cards = make_hands()
        for hand in cards:
            hands += 1
            if isflush(hand):
                return shuttles, hands

shuffles, hands = how_many()
print(f'It took {hands} hands with {shuffles} reshuffles to find a flush')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM