如何在玩家之间随机洗牌?

时间:2018-06-08 23:56:44

标签: python list loops random list-comprehension

我在另一个功能中使用一个功能来处理卡片时遇到问题。这是我到目前为止所拥有的。

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)) 

我知道这个功能不完整。我需要num_cards是每个玩家接收的牌数,num_players是玩家的数量,deck需要来自函数create()的牌组列表。 例如,print语句将显示三个玩家中的每一个从已经洗牌的列表牌中获得的5张牌。我的问题是,无论什么时候我写东西,都说甲板没有定义。

3 个答案:

答案 0 :(得分:2)

忘记你的两个功能,因为它们都是正确的,并查看你的顶级代码:

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

deck来自哪里?无处。因此例外。

很明显,意图来自哪里 - 你有一个以create结尾的return deck函数。你根本就没有在任何地方打电话。

所以你想要:

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

......或者,如果你想让全局变量与两个本地变量无关,那就更清楚了:

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

......或者,如果你想让事情更简洁:

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

除此问题外,cards_dealt没有return,因此只返回None。当你的功能完成后,可能会有一些值得打印出来的东西,但就目前而言,当你正在调试你目前所拥有的东西时,它并不是很有用。

同时,如果你想要打印洗牌的牌组,可以有用,你可以这样做:

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

当你以后完成这个功能所以它返回一个由5个卡片组成的3个列表的元组时,你可能想要存储这些返回值以供以后使用,所以它可能会是这样的:

import random as rand
def ...
def ...
mydeck = create()
hands = cards_dealt(5, 3, mydeck)
for hand in hands:
    print(hand)

答案 1 :(得分:2)

让我建议一种面向对象的方法,我们将定义类CardDeckPlayer

使用对象而不是卡片列表将提供一个简洁的API来实现游戏。当您实施游戏逻辑时,它还可以更容易地保留单一事实来源,以确定每张卡的位置以及每张卡的哪个玩家。

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]

交易卡

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

deck.deal(players, n=4)

for p in players:
    print(p.hand)

输出

[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)]

打牌

可以更新card.where属性以指示卡的位置。由于它是卡位置的单一事实来源,因此会更新player.hand属性。

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)

输出

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

更多功能

上述API提供了处理卡片和移动卡片的基础知识,但可以扩展以实现新功能。

答案 2 :(得分:1)

当然还有其他方法,但你可以完成你的功能,以便返回你的球员和他们的手的字典:

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)}

然后,创建你的套牌(这是你的“套牌未定义”问题进来的地方)并调用你的函数:

my_deck = create()

print(cards_dealt(5, 3, my_deck))

返回:

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

等效的cards_dealt函数,但是使用循环代替dict和list comprehensions:

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