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项目案例开发从入门到实战》郑秋生,夏敏捷版