知行编程网知行编程网  2022-03-04 02:00 知行编程网 隐藏边栏 |   抢沙发  326 
文章评分 0 次,平均分 0.0

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

阅读本文大概需要5分钟

 

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

 

德州扑克的玩法

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

 

 

思考:德州扑克比较大小

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

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'],我们的扑克面值是从2-'A',正好利用它的下标对应的数字1-13,这样就可以很巧妙的解决了这个问题.

 

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

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

 

 

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

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

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

 

1).判断顺子

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

  • 先把扑克排序
  • 判断是否是不相同的5张
  • 判断最大值和最小值相差为4

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

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

 

2).判断是否为同花

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

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

 

3).判断炸弹,三带二

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

  • 炸弹是4张一样的
  • 三带二是3张一样的

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

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

 

这样炸弹 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).两对

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

 

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

 

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

 

 

 

5.对九种牌型总的排序 

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

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

 

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

  • 比如同花顺:要判断是同花并且是顺子,然后取5张最大值比较
  • 比如炸弹4带一,先取炸弹的面值然后取单张的值
  • 比如三带二,先去3张的面值,然后再取1对的值
  • 同花:比较排序过的列表
  • 顺子:取排序过的列表中的最大值比较
  • 三条:取3条里面的最大值比较
  • 二对:取2对里面的每对的最大值,组成的列表比较
  • 单张:取5个单张里面的最大值比较

 

6.大功告成 

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

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

 


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

 

历史人气文章

Python语言如何入门

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

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

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

用Python写个弹球的游戏

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

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

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

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

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享