巧妙的Python数据结构玩法|实战德州扑克

浏览: 4095

Clipboard Image.png

这是菜鸟学Python的第77篇原创文章

阅读本文大概需要5分钟


      前面几篇一直都在写Python的数据分析处理,今天我想写一篇轻松好玩的文章,德州扑克大家应该都玩过吧,今天我们就来写一个程序对德州扑克进行比大小,好像看似简单,但是能学到不少东西,特别是对问题如何抽象建模然后写成程序,快来看看吧~~

Clipboard Image.png

思考:德州扑克比较大小

如何解决这个问题,看起来好像很复杂啊,至少有这些问题是需要考虑的:

1.我们要制定9种牌型的大小顺序

2.对于每一张牌型里面又需要排序,比如同样都是同花顺,也有大小

3.每一种牌型,若是最大的一样,还要比较最小的,比如88899比88877大

4.10,J,Q,K,A这些大牌如何处理,怎么比较 

5.A的问题,可以当最大值,也可以当1

6.多手牌的比较,比如有3手牌

上面这么多问题着急啊,怎么办呢,如何设计一个巧妙的数据结构来解决这个问题,我们下面来一步一步分析

1.设计数据结构

Python中耳熟能详的类型有列表,字典,元组,集合,这些类型内置了强大的相关操作,对于这道题,我们先要抽象出来,然后用程序去描述这个问题,

  • 每张牌2个维度:一个是数字,一个是花


  • 花色我们用黑桃Spade,梅花Club,方块Diamonds,红桃Hearts用首字母表示['S','C','D','H']


  • 牌呢,我们使用数字还是字符表示,如果用数字表示10,J,K,Q就要对应11,12,13

    hands_1=['6C','7C','8C','9C','10C']

    hands_2=[('6','C'),('7','C'),('8','C'),('9','C'),('J','C')]

    hands_3='6C 7C 8C 9C 10C'

  • 如果用数字就会带来一个非常严重的问题:

    比如s1='6C',我们很容易分割,a,b='6C'

    但是s2='10C',我们就无法分析,因为是3个字符,这样在后面统一处理的时候会带来很多麻烦和不方便,所以我们的牌必须用字符表示

上面3种表示方法,其实第一种和第三种都不错,第三种更简洁一下,好数据结构我们定下来了

2.分析德州扑克的排序

既然德州扑克有9种,那么我就按数字大小列为9个等级 9>8>7>6..>1

9.同花大顺

8.同花

7.炸弹

6.三带二

5.顺子

4.三条 

3.两对 

2.一对

1.单张

并且把5张手牌从大到小排个序,然后开始分析


1).如果有2手牌是同类型的:

ths_hands1="6C 7C 8C 9C TC" #同花顺
抽象表示为:(9,10) 
9表明是同花顺最高级为9
10表明这副手牌里面的顺子最大值
这样的话相同的同花顺,我只要比较第二个数字就可以了
ths_hands2="8C 9C TC JC QC" #同花顺"
表示为:(9,12) 
9表明是同花顺最高级为9
12表明这副手牌里面的顺子最大值
max((9,10),(9,12))
>>(9,12)
这样很容易得到(9,12)是最大的手牌
2).如果有2手牌是不同类型的:
ths_hands1="6C 7C 8C 9C TC" #同花顺
表示为:(9,10)
9表明是同花顺级别为9
10表明这副手牌里面的顺子最大值
zd_hand2="6D 6H 6S 6C 7C" #6炸
表示为:(8,6,7)
8表示是炸弹级别为8
6表示炸弹是6炸
7表示是单张
max((9,12),(8,6,7))
>>(9,12)
这样最后我们只需要判断这个hands属于第几种,然后max一下就可以了
max([hands1,hand2],key=rank_hand)
是不是很简单啦

3.单5张扑克排序问题

我们先把5张扑克排序,每种牌需要从大到小先排序

  • 比如[2,3,4,5,6,7,8,9]我们很容易排序,但是把[9,T,J,Q,K,A]这怎么排序呢,必须要用一个制定一个规矩A>K>Q>J>T>9..>2


  • 有同学说不是每张牌都有花色吗:hands="5S 5D 9H 9C 6S",我们split一下就可以了

  • 关键是如何对单张牌面值排序.我们先制定一个列表 ['0123456789TJQKA'],我们的扑克面值是从'A',正好利用它的下标对应的数字1-13,这样就可以很巧妙的解决了这个问题.


当然有同学说可以用字典键值对,来通过设置对应的key的大小,然后排序,当然可以,但是没有上面这种方法简洁.


4.接着分析如何判断各种牌型

虽然牌型有9种,但是分割起来,无非下面几种问题:

  • 同花顺,同花:考虑5张牌的花色

  • 炸弹,三带二,二对:其实都是考虑5种牌里面哪几张是一样的

  • 顺子:考虑5张牌是不是顺子

1).判断顺子

判断手牌是否是顺子,很简单

  • 先把扑克排序

  • 判断是否是不相同的5张

  • 判断最大值和最小值相差为4

满足上面3点肯定是顺子了


2).判断是否为同花

5张牌同花色,比较好判断用,用set很容易搞定


3).判断炸弹,三带二

这几种类型都有一个共同的特点,就是有几张是一样的,

  • 炸弹是4张一样的

  • 三带二是3张一样的

所以我们要写一个函数来判断5张里面有几种相同的,我们传入2个参数,一个相同的个数,一个是牌


这样炸弹 cards="3S 3S 3S 3C 4D"

就可以描述为(7,3,4)第一个7表示是炸弹型牌为7,3表示是3炸,4是带的单张

同理三带二可以表示为:

cards="8S 8S 8S 3C 3D"
print (6,judge_kind(3,card_ranks(cards)),judge_kind(2,card_ranks(cards)))
>>(6,8,3)

4).两对

二对跟上面跟类似,但是要得到两个对里面的最大值,所以我们利用上面的函数来做二次处理,取出每对里面的最大值


一副对子和5个单张很好理解,这边就不说了 



5.对九种牌型总的排序 

上面几步已经把每一个小的环节打通了,现在我们来写个总的对9种牌型的排序函数吧


对于9种牌型,先判断是哪种类型的,接着对剩余的部分再排序

  • 比如同花顺:要判断是同花并且是顺子,然后取5张最大值比较

  • 比如炸弹4带一,先取炸弹的面值然后取单张的值

  • 比如三带二,先去3张的面值,然后再取1对的值

  • 同花:比较排序过的列表

  • 顺子:取排序过的列表中的最大值比较

  • 三条:取3条里面的最大值比较

  • 二对:取2对里面的每对的最大值,组成的列表比较

  • 单张:取5个单张里面的最大值比较



6.大功告成 

根据不同的牌型转换成对应的元组型数据结构,然后利用max轻松搞定


Python处理德州扑克比大小就讲到这里,是不是觉得蛮好玩的,今天就讲到这里,大家可以动手去写一下,不是很难,另外这个程序有一个小bug,若有发现的同学可以跟我说,我会公布答案

历史人气文章

Python语言如何入门

分析10000个美国人名字|探寻数据背后的故事

关于Excel表格如何处理|这篇最用心

同学,学Python真的不能这样学

用Python写个弹球的游戏

Python写个迷你聊天机器人|生成器的高级用法

用Python破解微软面试题|24点游戏

2道极好的Python算法题|带你透彻理解装饰器的妙用

一道Google的算法题 |Python巧妙破解

 长按二维码,关注【菜鸟学python】

来源 | 菜鸟学Python

作者 | xinxin

本文章为菜鸟学Python独家原创稿件,未经授权不得转载

推荐 1
本文由 菜鸟学Python 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

1 个评论

你好 我运行了这个 但是出问题了 请问bug出现在哪里 list木有split

要回复文章请先登录注册