制作发牌程序的Python代码遇到问题。

4 投票
5 回答
15299 浏览
提问于 2025-04-17 08:11

我正在尝试制作一个纸牌游戏。现在我遇到的问题是如何发牌。我做了一个字典,把每张牌都列出来,并给它们赋了一个值,因为有些牌比其他牌更值钱。我想的办法是把这个字典分成四部分,或者制作四个字典的副本,然后从每个字典中删除39张牌(这样每个人就剩下13张牌)。这样做可行吗?还是我走错了方向?

from random import randint
deck = {}
def makeDeck(deck):
  suit = ['Club', 'Spade', 'Heart', 'Diamond']
  whichSuit = 0
  whichNum = 2
  count = 1
  while count != 52:
    if whichNum == 11:
      whichNum = 'Jack'
    if whichNum == 12:
      whichNum = 'Queen'
    if whichNum == 13:
      whichNum = 'King'
    if whichNum == 14:
      whichNum = 'Ace'
    deck[str(whichNum)+' '+suit[whichSuit]] = count
    count += 1
    if whichNum == 'Jack':
      whichNum = 11
    if whichNum == 'Queen':
      whichNum = 12
    if whichNum == 'King':
      whichNum = 13
    if whichNum == 'Ace':
      whichNum = 14
    whichNum += 1
    if count == 13 or count == 26 or count == 39:
     whichSuit += 1
     whichNum = 2
def dealCards(deck):
  me = deck
  comp1 = deck
  comp2 = deck
  comp2 = deck

(如果代码有问题我很抱歉,这是我第一次发帖,谢谢)

5 个回答

1

你可以选择使用Python自带的一个功能,叫做random.shuffle。别去搞什么字典了,直接创建一堆牌的列表,然后把它整个打乱就行:

>>> import random
>>> ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'K', 'Q']
>>> suits = ['C', 'D', 'H', 'S']
>>> cards = [[rank, suit] for rank in ranks for suit in suits]
>>> random.shuffle(cards)
>>> cards
[['J', 'S'], ['2', 'S'], ['3', 'S'], ['9', 'S'], ['9', 'D'], ['5', 'S'], 
 ['8', 'H'], ['A', 'C'], ['4', 'D'], ['Q', 'H'], ['2', 'C'], ['Q', 'D'], 
 ['7', 'H'], ['4', 'C'], ['7', 'S'], ['6', 'C'], ['K', 'H'], ['6', 'S'], 
 ['9', 'C'], ['9', 'H'], ['A', 'H'], ['J', 'C'], ['2', 'D'], ['J', 'H'], 
 ['3', 'H'], ['4', 'H'], ['8', 'C'], ['Q', 'S'], ['10', 'S'], ['A', 'S'], 
 ['K', 'S'], ['5', 'D'], ['10', 'D'], ['8', 'D'], ['7', 'C'], ['5', 'C'], 
 ['Q', 'C'], ['3', 'D'], ['8', 'S'], ['6', 'H'], ['A', 'D'], ['2', 'H'], 
 ['6', 'D'], ['K', 'D'], ['10', 'C'], ['5', 'H'], ['4', 'S'], ['K', 'C'], 
 ['7', 'D'], ['10', 'H'], ['3', 'C'], ['J', 'D']]

如果你想自己动手实现,可以考虑一下Fisher-Yates洗牌算法。这个方法非常简单。

说得简单明了一点,一旦你有了一个打乱的列表,你可以像这样把它分发出去:

>>> hand1 = cards[0:13]
>>> hand2 = cards[13:26]
# ...and so on...

或者用其他更复杂的方式来处理。(不过要注意,没必要去循环处理每个人的手牌,因为已经是随机的,简单的切片就足够了。)

6

我对Python中的字典功能不是很熟悉,但我会使用卡片对象和列表来进行洗牌。

from random import shuffle    
class Card:
    def __init__(self,suit,num):
        self.suit = suit
        self.num = num

deck = list()
suits = ['Diamond', 'Heart', 'Spade', 'Club']

nums = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']

for suit in suits: #This is the code that actually makes a deck
    for num in nums:
        deck.append(Card(suit,num))

shuffle(deck)
for number in range(13):
    for player in range(4):
        #deal cards here using deck.pop()
        print(deck.pop().num) #just to prove it works randomly =P        

希望这能回答你的问题(因为这是你的第一个问题,而这是我的第一个回答)

补充:哎呀,集合(set)已经不推荐使用了。改用内置的集合。

补充2:而且set.pop()并不是完全随机的,进一步阅读后发现,它只是随意的。真是让我感到尴尬。

8

听起来这是个很好的机会来使用类!我会这样做:

from random import shuffle

class Cards:
    def __init__(self):
        values = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
        suites = ['H', 'S', 'C', 'D']
        self.deck = [j + i for j in values for i in suites]

    def shuffle(self):
        shuffle(self.deck)

    def deal(self, n_players):
        self.hands = [self.deck[i::n_players] for i in range(0, n_players)]

c = Cards()
print c.deck
c.shuffle()
print c.deck
c.deal(4)
print c.hands

撰写回答