习题:扑克牌发牌

  • 发52张扑克牌到4个人,要随机,速度足够快
  • 有人写了一个下面的例子,你觉得他的算法对吗?你能否比他写得好?
  • 提示: random.shuffle()
import random,time

class timer:
    def __init__(self):
        self.start= time.time()
    def stop(self):
        self.end= time.time()
        return  "\n 本次运行已用时 %s秒"% (self.end-self.start)

class people:
        #定义四个玩牌的人
    jack = []
    python = []
    java = []
    stephen = []
    def print_jack(self):
        i=0
        tmp = ''
        while i < 13:
            tmp += self.jack[i]+' '
            i += 1
        return tmp
    def print_python(self):
        i=0
        tmp = ''
        while i < 13:
            tmp += self.python[i]+' '
            i += 1
        return tmp
    def print_java(self):
            i=0
            tmp = ''
            while i < 13:
                tmp += self.java[i]+' '
                i += 1
            return tmp
    def print_stephen(self):
        i=0
        tmp = ''
        while i < 13:
            tmp += self.stephen[i]+' '
            i += 1
        return tmp

class agent(people):
    def __init__(self):
        #定义一个空的列表存放牌
        self.card = []
        #定义洗牌的次数,并不是越大牌就越乱
        self.count = 52
        #定义一个基本的牌序
        self.base = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']

    def arrangement(self):
        #重新排列纸牌
        i = 0
        while i < 13:
            self.card.insert(0,'黑桃'+self.base[i])
            i += 1
        i = 0
        while i < 13:
            self.card.insert(0,'红桃'+self.base[i])
            i += 1
        i = 0
        while i < 13:
            self.card.insert(0,'草花'+self.base[i])
            i += 1
        i = 0
        while i < 13:
            self.card.insert(0,'方块'+self.base[i])
            i += 1

    def shuffle(self):
        #洗牌
        i = 1
        while i < self.count:
            #产生一个随机数来确定要交换牌的位置
            position = random.randint(0,51)
            #临时取出一张牌准备用来交换位置
            tmp = self.card[position]
            #交换随机位置的牌和第一张牌
            self.card[position] = self.card[0]
            self.card[0] = tmp
            i += 1

    def outcards(self):
        #发牌
        i = 0
        while i < 52:
            if i <= 12:
                self.jack.insert(0,self.card[i])
            elif i >= 12 and i <= 25 :
                self.python.insert(0,self.card[i])
            elif i >= 25 and i <= 38 :
                self.java.insert(0,self.card[i])
            elif i >= 38 and i <= 52 :
                self.stephen.insert(0,self.card[i])
            i += 1

start=timer()
a=agent()
a.arrangement()
a.shuffle()
a.outcards()
print a.print_jack()
print a.print_python()
print a.print_java()
print a.print_stephen()
print start.stop()

其他方法

  • 关于牌的表示(另一种方法)
  1. suit表花色['Clubs', 'Diamonds', 'Hearts', 'Spades'], suit = 2就是红桃
  2. rank表大小rank = [None, 'Ace', '2','3','4','5','6','7','8','9','10','Jack','Queen','King']加一个None, 是为了让rank[2] = '2'和数字2对应起来
class Card(object):
    '''Represents a standard playing card.'''
    def __init__(self, suit = 0, rank = 2): 
        self.suit = suit
        self.rank = rank    
    suit_names = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
    rank_names = [None, 'Ace', '2','3','4','5','6','7','8','9','10','Jack','Queen','King']
    def __str__(self):
        return "%s of %s" % (Card.rank_names[self.rank], Card.suit_names[self.suit])
card1 = Card(2, 7)
print card1
  • 关于牌组(Deck)的表示
  1. 连续打印牌组
class Deck(object):
    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1, 14):
                card = Card(suit, rank)
                self.cards.append(card)
    def __str__(self):
        res = []
        for card in self.cards:
            res.append(str(card))
        return '\n'.join(res)
deck = Deck()
print deck
  • 洗牌, 对列表deck.cards用random.shuffel
import random
random.shuffel(deck.cards)
  • 写进deck class, 再看一下前五张牌
import random
class Deck(object):
    def __init__(self):
        self.cards = []
        for suit in range(4):
            for rank in range(1, 14):
                card = Card(suit, rank)
                self.cards.append(card)
    def __str__(self):
        res = []
        for card in self.cards:
            res.append(str(card))
        return '\n'.join(res)
    def pop_card(self):
        return seld.cards.pop()
    def add_card(self, card):
        self.cards.append(card)
    def shuffle(self):
        random.shuffle(self.cards)
>>> deck.shuffle()
>>> print deck
    Ace of Clubs          2 of Hearts
    2 of Clubs            Jack of Hearts
    3 of Clubs            Jack of Spades
    4 of Clubs            2 of Diamonds
    5 of Clubs            Ace of Clubs
  • 发牌, 对洗牌后的deck.cards列表用已有的方法pop_card, 也就是抽最后一张牌, 在deck class里面加上新方法remove cards
def remove_cards(self, hand, num):
    for i in range(num):
        hand.cards.append(self.pop_card())

比如发给'Python'13张牌

class Hand(Deck):
    '''Represents a hand of playing cards.'''
    def __init__(self, label = ''):
        self.cards = []
        self.label = label
hand = Hand('Python')
deck = Deck()
deck.shuffle()
deck.remove_cards(hand, 13)

看一下python的手牌
>>> print hand
7 of Diamonds
Queen of Clubs
Jack of Clubs
6 of Hearts
7 of Spades
King of Diamonds
3 of Spades
2 of Diamonds
5 of Clubs
10 of Diamonds
Ace of Spades
9 of Spades
10 of Spades

现在deck牌组就只剩下39张牌了:
>>> len(deck.cards)
39
  • 稍微修改一下就是给四个人发牌
deck = Deck()
deck.shuffle()
player_names = ['jack', 'python', 'java', 'steven']
hands = {}
for i in range(4):
    hand = Hand(player_names[i])
    deck.move_cards(hand, 13)
    hands[player_names[i]]=hand
    print "%s 's hand cards are: " % player_names[i]
    print hand 
jack 's hand cards are
Jack of Diamonds
3 of Hearts
7 of Hearts
Jack of Clubs
10 of Diamonds
7 of Diamonds
9 of Spades
9 of Diamonds
King of Diamonds
10 of Hearts
King of Clubs
9 of Clubs
6 of Clubs


python 's hand cards are
2 of Spades
4 of Clubs
King of Hearts
Ace of Clubs
Ace of Diamonds
8 of Clubs
Queen of Hearts
3 of Clubs
Ace of Hearts
3 of Spades
7 of Spades
4 of Diamonds
8 of Hearts


java 's hand cards are
6 of Hearts
Queen of Spades
7 of Clubs
Queen of Diamonds
King of Spades
5 of Hearts
8 of Spades
4 of Spades
5 of Clubs
2 of Diamonds
2 of Hearts
4 of Hearts
10 of Clubs


steven 's hand cards are
5 of Diamonds
Jack of Spades
Queen of Clubs
3 of Diamonds
10 of Spades
2 of Clubs
8 of Diamonds
Jack of Hearts
6 of Diamonds
5 of Spades
6 of Spades
Ace of Spades
9 of Hearts
  • 看一下时间, 总共不到0.2s
start = datetime.now()
end = datetime.now()
print "the time lasped is :", end - start
the time lasped is : 0:00:00.152000
做的不错啊 =)俞熹 2014/11/17 13:29
其实这是我看<像计算机学家一样思考Python>书时候, 从书上抄下来的 — 付聿炜 2015/01/25 11:08
  • course/python/poke2.txt
  • 最后更改: 2015/01/25 11:15
  • (外部编辑)