Python实现比较扑克牌大小程序代码示例
是Udacity课程的第一个项目。
先从宏观把握一下思路,目的是做一个比较德州扑克大小的问题
首先,先抽象出一个处理的函数,它根据返回值的大小给出结果。
之后我们在定义如何比较两个或者多个手牌的大小,为方便比较大小,我们先对5张牌进行预处理,将其按照降序排序,如下:
defcard_ranks(hand): ranks=['--23456789TJQKA'.INDEX(r)forr,sinhand] ranks.sort(reverse=True) returnranks
然后我们可以枚举出一共有9种情况,并用数字代表每一种情况的等级,利用Python的比较功能,将等级放在第一位,如果等级相同,那么再比较后面的。
defhand_rank(hand): "Returnavalueindicatingtherankingofahand." ranks=card_ranks(hand) ifstraight(ranks)andflush(hand): return(8,max(ranks)) elifkind(4,ranks): return(7,kind(4,ranks),kind(1,ranks)) elifkind(3,ranks)andkind(2,ranks): return(6,kind(3,ranks),kind(2,ranks)) elifflush(hand): return(5,ranks) elifstraight(ranks): return(4,max(ranks)) elifkind(3,ranks): return(3,kind(3,ranks),ranks) eliftwo_pair(ranks): return(2,two_pair(ranks),ranks) elifkind(2,ranks): return(1,kind(2,ranks),ranks) else: return(0,ranks)
可以看到,如果等级相同,接下来比较的是每套牌中牌的大小了。同时我们需要三个函数,代表同花,顺子,以及kind(n,ranks),代表ranks有n张牌的点数。这里的三个函数实现非常巧妙,利用了set去重的特性。
defstraight(ranks): return(max(ranks)-min(ranks))==4andlen(set(ranks))==5 defflush(hand): suit=[s,forr,sinhand] returnlen(set(suit))==1 defkind(n,ranks): forsinranks: ifranks.count(s)==n:returns returnNone
我们发现,有一种情况是含有两个对,于是需要一个函数来判断是否是这种情况,这个函数中调用了kind()函数,由于kind()函数满足短路特性,只会返回先得到的满足情况的点数,于是将其翻转后,在调用一边kind,若得到的结果相同,那么就只有一个对(或者没有),否则就有两个。
deftwo_pairs(ranks): pair=kind(2,ranks) lowpair=kind(2,list(reverse(ranks))) ifpair!=lowpair: return(pair,lowpair) else: returnNone
好了,整体的骨架算是搭完了,接下来处理会产生bug的情况,首先是A2345,当排序时由于A被算作14,所以针对这个问题需要单独列一个if
处理A是最低: defcard_ranks(hand): ranks=['--23456789TJQKA'.INDEX(r)forr,sinhand] ranks.sort(reverse=True) return[5,4,3,2,1]if(ranks=[14,5,4,3,2]elseranks
之后就是进一步的简化了,思路挺好的
defpoker(hands): returnallmax(hands,key=hand_ranks) defallmax(iterable,key=None): result,maxval=[],None ket=keyorlambda(x):x forxiniterable: xval=key(x) ifnotresultorxval>maxval: result,maxval=[x],xval elif: result.append(x) returnresult """大于就取代,等于就加入,小于不作处理""" importrandom mydeck=[r+sforrin'23456789TJKQA'forsin'SHDC] defdeal(numhands,n=5,deck=[r+sforrin'23456789TJKQA'forsin'SHDC]): random.shuffle(deck) return[deck[n*i:n*(i+1)]foriinrange(numhands)] defhand_ranks(hand): groups=group['--23456789TJQKA'.index(r)forr,sinhand] counts,ranks=unzip(groups) ifrnaks==(14,5,4,3,2,1): ransk=(5,4,3,2,1) straight=len(ranks)==5andmax(ranks)-min(ranks)==4 flush=len(set([sforr,sinhand]))==1 return(9if(5,)==countelse 8ifstraightandflushelse 7if(4,1)==countselse 6if(3,2)==countselse 5ifflushelse 4ifstraightelse 3if(3,1,1)==countselse 2if(5,1,1)==countselse 1if(2,1,1,1)==countselse 0),ranks defgroup(items): groups=[(items.count(x),x)forxinset(items)] returnsorted(groups,reverse=True) defunzips(pairs):returnzip(*pairs) defhand_ranks(hand): groups=group['--23456789TJQKA'.index(r)forr,sinhand] counts,ranks=unzip(groups) ifrnaks==(14,5,4,3,2,1): ransk=(5,4,3,2,1) straight=len(ranks)==5andmax(ranks)-min(ranks)==4 flush=len(set([sforr,sinhand]))==1 returnmax(count_ranks[counts],4*straight+5*flush),ranks count_rankings={(5,):10,(4,1):7,(3,2):6,(3,1,1):3,(2,2,1):2, (2,1,1,1):1,(1,1,1,1,1):0}
总结下,面对一个问题的思维步骤:
started:understandproblemslookatspecificationSeeifitmakesense definethepieceofproblemreusethepieceyouhavetest!>explore 最后是是的程序在各个方面达到均衡 correctnesseleganceefficienctfeatrues
总结
以上就是本文关于Python实现比较扑克牌大小程序代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:
Python3简单实例计算同花的概率代码
Python语言描述最大连续子序列和
Python数据可视化正态分布简单分析及实现代码
如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!