How to randomly shuffle a deck of cards among play

2019-03-06 00:53发布

I am having trouble using one function in another to deal cards. Here is what I have so far.

import random as rand 

def create(): 
     ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']   
     suites = ['H', 'C', 'D', 'S'] 
     deck = [[r + s] for s in suites for r in ranks]    
     return deck   

def cards_dealt (num_cards, num_players, deck): 
     rand.shuffle(deck) 


print(cards_dealt(5, 3, deck)) 

I understand that the function is incomplete. I need num_cards to be the number of cards that each player receives, num_players to be the number of players, and deck to be the list of card strings from the function create(). For example, the print statement would reveal the 5 cards each of the three players gets from the list deck that has been shuffled. My problem is that whenever I write something, it says that deck is not defined.

3条回答
倾城 Initia
2楼-- · 2019-03-06 00:55

Forget about your two functions, since they're both correct, and look at your top-level code:

import random as rand
def ...
def ...
print(cards_dealt(5, 3, deck)) 

Where does deck come from? Nowhere. Hence the exception.

It's pretty obvious where you intended it to come from—you have a create function that ends with a return deck. You just aren't calling it anywhere.

So you want:

import random as rand
def ...
def ...
deck = create()
print(cards_dealt(5, 3, deck)) 

… or, if you want to make it clearer that the global variable is unrelated to the two locals:

import random as rand
def ...
def ...
mydeck = create()
print(cards_dealt(5, 3, mydeck)) 

… or, if you want to make things more concise:

import random as rand
def ...
def ...
print(cards_dealt(5, 3, create())) 

Beyond this problem, cards_dealt doesn't have a return, so it just returns None. When your function is complete, there might be something worth printing out, but for now, while you're debugging what you have so far, it's not very useful.

Meanwhile, if you want to print the shuffled deck, which could be useful, you'd do something like this:

import random as rand
def ...
def ...
mydeck = create()
cards_dealt(5, 3, mydeck)
print(mydeck)

When you later finish the function so it returns, say, a tuple of 3 lists of 5 cards, you'll probably want to store those return values for later as well as printing them, so it might go something like this:

import random as rand
def ...
def ...
mydeck = create()
hands = cards_dealt(5, 3, mydeck)
for hand in hands:
    print(hand)
查看更多
混吃等死
3楼-- · 2019-03-06 00:55

There are certainly other ways to do it, but you could complete your function as so, in order to return a dictionary of your players and their hands:

def cards_dealt(num_cards, num_players, deck):
    rand.shuffle(deck)
    return {player:[deck.pop() for _ in range(num_cards)] for player in range(num_players)}

Then, create your deck (that is where your "deck is not defined" problem comes in) and call your function:

my_deck = create()

print(cards_dealt(5, 3, my_deck))

Which returns:

{0: [['10S'], ['8S'], ['7D'], ['6S'], ['4C']], 
 1: [['JD'], ['AC'], ['QD'], ['2D'], ['JS']], 
 2: [['6D'], ['4H'], ['AS'], ['4S'], ['9S']]}

The equivalent cards_dealt function, but with loops instead of the dict and list comprehensions is:

def cards_dealt (num_cards, num_players, deck): 
     rand.shuffle(deck)
     player_hands = {i:[] for i in range(num_players)}
     for player in range(num_players):
         for num in range(num_cards):
             player_hands[player].append(deck.pop())
     return player_hands
查看更多
贪生不怕死
4楼-- · 2019-03-06 01:04

Let me suggest an object-oriented approach where we will define the classes Card, Deck and Player.

Using objects instead of lists of cards will provide a neat API to implement games. As you implement game logic, it will also make it easier to keep a single source of truth as to where each card is and which player has each card.

Deck API

import random


class Card:
    def __init__(self, kind, rank, deck):
        self._kind = kind
        self._rank = rank
        self.deck = deck
        self.where = None

    def __repr__(self):
        return 'Card(kind={}, rank={}'.format(self.kind, self.rank)

    @property
    def kind(self):
        return self._kind

    @property
    def rank(self):
        return self._rank


class Deck:
    def __init__(self):
        ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
        kinds = ['H', 'C', 'D', 'S']
        self.cards = [Card(kind, rank, self) for kind in kinds for rank in ranks]

    def deal(self, players, n=None):
        if any(p.deck is not self for p in players):
            raise RuntimeError('Player {} is not playing the deck'.format(p.id))

        n = n if n is not None else len(self.cards)
        random.shuffle(self.cards)

        for i, card in enumerate(self.cards[:n * len(players)]):
            card.where = players[i % len(players)]


class Player:
    def __init__(self, id, deck):
        self.id = id
        self.deck = deck

    @property
    def hand(self):
        return [card for card in deck.cards if card.where is self]

Dealing cards

deck = Deck()
players = [Player(id, deck) for id in range(3)]

deck.deal(players, n=4)

for p in players:
    print(p.hand)

Output

[Card(kind=D, rank=A), Card(kind=D, rank=2), Card(kind=S, rank=5), Card(kind=S, rank=K)]
[Card(kind=S, rank=9), Card(kind=D, rank=5), Card(kind=C, rank=A), Card(kind=C, rank=Q)]
[Card(kind=C, rank=9), Card(kind=S, rank=J), Card(kind=D, rank=3), Card(kind=H, rank=9)]

Playing a card

The card.where attribute can be updated to indicate the position of a card. Since it is the single source of truth for card position, this updates the player.hand property.

deck = Deck()
players = [Player(id, deck) for id in range(2)]

deck.deal(players, n=1)

players[0].hand[0].where = players[1]

for p in players:
    print(p.hand)

Output

[]
[Card(kind=H, rank=K), Card(kind=D, rank=2)]

More features

The above API provides the basics to deal cards and move cards from hand to hand, but can be extended to implement new features.

查看更多
登录 后发表回答