python:面向对象实例:扑克牌发牌程序(非图形化 )

4名牌手打牌,计算机随机将52张牌(不含大/小鬼)发给4名牌手,并在屏幕上显示每位牌手的牌。程序的运行结果如图所示

发牌程序设计出3个类——Card类、Hand类和Poke类。

1.card类

Card类代表一张牌,其中FaceNum字段指的是牌面数字1-13,Suit字段指的是花色,Rank指的是牌的大小

(1)Card构造函数根据参数初始化封装的成员变量,实现盘面大小和花色的初始化,以及是否显示牌面,默认True为显示牌的正面

(2)__str__() 方法用来输出牌面大小和花色

(3)pic_order()方法用来获取牌的序号,牌面按照梅花1-13,方块14-26,红桃27-39,黑桃40-52的顺序编号(未洗牌之前)。这个方法是为图形化显示牌面预留的方法

(4)filp()方法是翻牌方法,改变牌面是否显示的属性值

class Card:
    '''A playing card.card'''
    RANKS=['A','2','3','4','5','6','7','8','9','10','J','Q','K']
    SUITS=['梅花','方片','红桃','黑桃']
    def __init__(self,rank,suit,face_up=True):
        self.rank=rank            #牌面数字1~13
        self.suit=suit            #花色
        self.is_face_up=face_up   #是否显示牌的正面,True为正面,False为反面
    def __str__(self):            #重写print()方法,打印一张牌的信息
        if self.is_face_up:
            rep=self.suit+self.rank
        else:
            rep='XX'
        return rep
    def pic_order(self):          #牌的顺序号
        if self.rank=='A':
            FaceNum=1
        elif self.rank=='J':
            FaceNum=11
        elif self.rank=='Q':
            FaceNum=12
        elif self.rank=='K':
            FaceNum=13
        else :
            FaceNum=int(self.rank)
        if self.suit=='梅花':
            Suit=1
        elif self.suit=='方片':
            Suit=2
        elif self.suit=='红桃':
            Suit=3
        else:
            Suit=4
        return(Suit-1)*13+FaceNum

    def flip(self):                #翻牌方法
        self.is_face_up = not self.is_face_up

2.Hand类

Hand类代表一手牌(一个玩家手里拿的牌),可以认为是一位牌手手里的牌,其中cards列表变量存储牌手手里的牌,玩家可以增加牌、把一张牌给其他牌手。

class Hand():
    '''A hand of playing cards  Hand'''
    def __init__(self):
        self.cards=[]            #cards列表变量存储牌手手里的牌
    def __str__(self):           #重写print()方法,打印出牌手的所有牌
        if self.cards:
            rep=''
            for card in self.cards:
                rep+=str(card)+'\t'
        else :
            rep='无牌'
        return rep
    def clear(self):            #清空手里的牌
        self.cards=[]
    def add(self,card):
        self.cards.append(card)
    def give(self,card,other_hand):  #把一张牌给其他选手
        self.cards.remove(card)
        other_hand.add(card)
        #other_hand.append(card)

3.Poke类

Poke类代表一副牌,可以看作是有52张牌的牌手,所以继承了Hand类。由于其中cards列表变量要存储52张牌,而且要发牌、洗牌,所以增加如下方法:

(1)populate(self)生成存储了52张牌的一手牌,当然这些牌是按照梅花1-13,方块14-26,红桃27-39,黑桃40-52的顺序(未洗牌之前)存储在cards列表变量中。

(2)shuffle(self)洗牌,使用Python的random模块的shuffle()方法打乱牌的存储顺序即可。

(3)deal(self,hands,per_hand=13)是完成发牌动作,发给4个玩家,每人默认13张牌。当然,如果给per_hand传10,则每人发10张牌,只不过牌没发完而已

class Poke(Hand):
    '''Poke类代表一副牌,可以看做是有52张牌的牌手,所以继承Hand类。由于其中cards列表变量要存储52张牌
    而且要发牌,洗牌,所以增加方法如下方法:'''
    def populate(self):                  #生成一副牌
        for suit in Card.SUITS:
            for rank in Card.RANKS:
                self.add(Card(rank,suit))
    def  shuffle(self):                  #洗牌
        import random
        random.shuffle(self.cards)       #打乱牌的顺序
    def deal(self,hands,per_hand=13):    #发牌,发给玩家,没人默认13张牌
        for rounds in range(per_hand):
            for hand in hands:
                if self.cards:
                    top_card=self.cards[0]
                    self.cards.remove(top_card)
                    hand.add(top_card)
                    #self.give(top_card,hand)#上两句可以用此句替换
                else:
                    print('不能继续发牌了,牌已经发完了!')

 4.主程序

主程序比较简单,因为有4个玩家,所以生成players列表存储初始化的4位牌手。生成一副牌对象实例poke1,调用popilate()方法生成有52张牌的一副牌,调用shuffle()方法洗牌打乱顺序,调用deal(players,13)方法发给玩家每人13张牌,最后显示4位牌手所有的牌

if __name__=="__main__":
    print('This is a module with classes for playing cards.')
    players=[Hand(),Hand(),Hand(),Hand()]
    poke1=Poke()
    poke1.populate()          #生成一副牌
    poke1.shuffle()           #洗牌
    poke1.deal(players,13)    #发给没人13张牌
    n=1
    for hand in players:
        print('牌手',n,end=':')
        print(hand)
        n=n+1
    input('\nPress the enter key to exit.')

本项目摘自《Python项目案例开发从入门到实战》郑秋生,夏敏捷版

你可能感兴趣的:(python)