随时提醒自己是否抓住了问题的关键,对解决问题有很大的帮助。1.使用类来定义一副扑克牌。这次扑克牌的定义排除了Kings和Kings,只针对其他52张牌。一共有4套,每套13张牌。如果我们要定义一个新的对象来表示一张牌,它的属性显然应该是rank(大小)和suit(花色)。但是属性值就不那么直观了。我们模仿Unicode以数字编码的形式对字母、汉字等字符进行编码,并使用证书对大小和颜色进行编码。颜色编码:草:0,方块:1,红心:2,黑桃:3数字编码:根据数字一一对应,其中:杰克:11,皇后:12,国王:13类牌(对象):'''代表一张标准扑克牌。'''def__init__(self,suit=0,rank=2):self.suit=suitself.rank=rank#为了将Card对象打印成人们可以看到的形式可以读取,整数需要将代码映射到相应的尺寸和花色。#rank_names的第一个元素是None,因为没有size为0的卡片,让None占据一个位置,让codenumber和卡片size对应的更整齐一点,比如字符串'2的下标2'像这样。suit_names=['Clubs','Diamonds','Hearts','Spades']rank_names=[None,'Ace','2','3','4','5','6','7','8','9','10','Jack','Queen','King']#__str__打印时会把代码和卡片一张一张匹配def__str__(self):return'%sof%s'%(Card.rank_names[self.rank],Card.suit_names[self.suit])比较卡片:比较大小时有内置的比较运算符(<、>、=等),但对我们来说定义类型,不能直接比较,需要使用《Python自学日记13——类与方法》中的重载运算符来实现。介绍的例子是使用__cmp__接收两个形参,self和other。第一个对象大的时候返回正数,第二个对象大的时候返回负数,相等的时候返回0。卡片比较涉及到两个属性大小和颜色,我们决定颜色大于大小,其余按代码大小比较。classCard(object):...#表示省略上面的代码def__str__(self):return'%sof%s'%(Card.rank_names[self.rank],Card.suit_names[self.suit])def__cmp__(self,other):#checksuitifself.suit>other.suit:return1ifself.suitother.rank:return1ifself.rankin---->1deck.sort()2print(deck)insort(self)28#Exercise:写一个Deck方法sort,使用list方法sort对一个Deck29中的卡片进行排序defsort(self):--->30self.cards.sort()TypeError:'<'notsupportedbetweeninstancesof'Card'and'Card'错误信息显示Card对象不支持'<',我只是以为我使用了重载运算符,它不应该出现在这种情况下,我认为默认降序排序不使用重载运算符方法。可不可以将__cmp__作为参数传入sort()方法,然后在sort中查看参数的性质,然后试了一会儿,不行,我怀疑我是不是没有带Card对象。我用Card.__cmp__试了一下,还是不行。然后我想,既然是这样,我就不用排序了。后来用了quicksort算法,结果报错和第一个差不多,'<'doesnotapplytothelisttype,然后想了python3中不使用cmp的替代方法。网上查了一下运算符,__lt__对应小于,由于上面的错误'<'不适用,那就用lt试试classCard(object):...#表示省略上面的代码def__str__(self):return'%sof%s'%(Card.rank_names[self.rank],Card.suit_names[self.suit])def__lt__(self,other):#Replace__cmp__with__lt__#Checkifself.suit>other.suit:return1ifself.suitother.rank:return1ifself.rank=5:returnTruereturnFalse#Exercise:增加判断手牌是否有对子的方法defrank_hist(self):#需要先根据牌的大小来数牌self.ranks={}forcardinself.cards:self.排名[卡。rank]=self.ranks.get(card.rank,0)+1defhas_pair(self):'''如果手牌有一对则返回True,否则返回False'''self.rank_hist()forvalinself.ranks.valuees():ifval>=2:returnTruereturnFalse#增加判断手上是否有两对的方法defhas_twopair(self):self.rank_hist()count=0forvalinself.ranks.values():ifval==2:count+=1ifval==4:count+=2ifcount>=2:returnTruereturnFalse#添加判断手牌是否有葫芦的方法(对于5张牌)defhas_fullhouse(self):self.rank_hist()iflen(self.ranks)!=2:returnFalseforvalinself.ranks.values():ifval==3orval==2:returnTrue返回false#添加判断手上是否有4种的方法defhas_four_of_a_kind(self):self.rank_hist()forvalinself.ranks.values():ifval==4:returnTruereturnFalse#添加判断手中是否有顺子方法defhas_straight(self):self.rank_hist()ranks=self.ranks.copy()ranks[14]=ranks.get(1,0)returnself.in_a_row(ranks,5)defin_a_row(self,ranks,n):count=0foriinrange(1,15):ifranks.get(i,0):count+=1ifcount==5:returnTrue否则:计数=0重新turnFalse#添加判断手牌是否有同花顺方法defhas_straight_flush(self):self.rank_hist()self.suit_hist()ifself.has_flush()andself.has_straight():returnTruereturnFalse#Exercise:写一个函数classify(分类),可以找出最大的Combine并设置label属性defclassify(self):self.rank_hist()self.suit_hist()self.labels=[]forlabelinPokerHand.all_labels:f=getattr(self,'has_'+label)iff():self.labels。append(label)returnself.labels[0]#从列表中识别出的第一个组合将被返回,那么它必须是最大的组合if__name__=='__main__':#makeadeck#deck=Deck()#deck.shuffle()##发牌并对手牌进行分类#foriinrange(7):#hand=PokerHand()#deck.move_cards(hand,7)##hand.sort()##print(hand)##print(hand.has_flush())##print(hand.has_pair())##print(hand.has_twopair())##houseprint(hand.has_f())##print(hand.has_four_of_a_kind())##print(hand.has_straight())##print(hand.has_straight_flush())#print(hand.classify())#print('')t=[]n=1000foriinrange(n):deck=Deck()deck.shuffle()forjinrange(10):hand=PokerHand()deck.move_cards(hand,5)t.append(hand.classify())#returnttimes={}forsint:times[s]=times.get(s,0)+1#key,val在times.items()中的返回时间:val='%.2f%%'%(float(val/(n*10))*100)print(key,val)#print(hand.classify())#打印('')