- 给定任意两组牌, 每组5张, 能够输出两组牌的牌面及比较的结果.
- 使用52张扑克, 分为四个花色(将红桃, 方块, 黑桃, 梅花简化为A, B, C, D), 每个花色13张牌, 数字从2到14(将J, Q, K, A简化为11, 12, 13, 14).
-
都是散牌的话, 比较各自五张牌中数字最大的
- 例1: "B11, A2, A9, D10, A8" < "D4, A8, C5, C6, B12"
-
对子(两张牌数字相同)大于散牌
- 例2: "B14, A3, A9, D10, A8" < "D4, A2, C2, C6, B11"
-
都有对子则比较对子之间大小
- 例3: "B11, A9, D9, D5, A8" < "D4, B10, C10, C6, B12"
-
顺子(五张牌数字连续)大于对子
- 例4: "D2, B2, C10, A10, B12" < "D5, A6, C7, C8, B9"
- 规则和术语(下列牌型按照从大到小排列, 下面的设计思路将采用这些术语命名)
- 皇家同花顺(royal flush): 由AKQJ10五张组成, 并且这5张牌花色相同
- 同花顺(straight flush): 由五张连张同花色的牌组成
- 4条(four of the kind): 4张同点值的牌加上一张其他任何牌
- 葫芦(full house): 3张同点值加上另外一对
- 同花(flush): 5张牌花色相同, 但是不成顺子
- 顺子(straight): 五张牌连张, 至少一张花色不同
- 3条(three of the kind): 三张牌点值相同, 其他两张各异
- 两对(two pairs): 两对加上一个杂牌
- 一对(one pair): 一对加上3张杂牌
- 高牌(high card): 不符合上面任何一种牌型的牌型,由单牌且不连续不同花的组成
- 总则: 拿到5张牌, 先比较牌型, 如果牌型相同, 再根据牌型比较大小即可
- 由于上述要求只有四个, 但是实际上德州扑克的牌型包含了10种, 因此我扩展了全部的规则, 避免在出现类似葫芦这种牌型的时候被当做高牌处理
- 为了使整个系统更加完善, 避免直接数据运行, 抽象出如下几个角色:
- Poker: 代表一副扑克, 包含
发牌
动作 - Dealer: 荷官, 系统的主导者, 负责
发牌
,计算玩家牌型比较
等 - Player: 玩家, 持有
5张牌
及其牌型结果
对象等, 该类实现Comparable
作为内部排序, 调用comparing逻辑实现玩家的输赢
- Poker: 代表一副扑克, 包含
- 系统其他设计:
- Card: 包括
牌色
和牌数字
, 很明显, 这2个对象都用枚举来存储, 该类实现Comparable
接口作为集合的内部排序 - CardSuitEnum:
牌色
, 包括红心, 黑桃, 草花, 方块 - CardRankEnum:
牌数字
, 2-A, 其中A最大, 抽象成数字14表示 - RankingEnum:
牌型
, 如high card
,one pair
等10种牌型
- Card: 包括
- 关键设计: 根据总则, 抽象出如下2个过程
- ranking: 5张牌牌型的解析
- comparing: 相同牌型的比较, 比如都是
高牌
, 依次比较最大牌即可
- ranking的设计
- 使用模板设计模式, 每个
牌型解析器
作为一个单独的类自己实现其解析逻辑, 如FourOfTheKindRankingImpl
用于检验5张牌是不是四条
- 每个
解析类
都具有可插拔的性质, 全部注册在门面类RankingFacade中, 如题目要求只要四个规则, 即注册对应的4个解析类即可 - 继承结构:
XXXRankingImpl
<AbstractRanking
<IRanking
- 使用模板设计模式, 每个
- comparing的设计
- 依赖
ranking
的解析结果, 使用策略模式
取得对应的比较器
, 比较相同的牌型结果 - 继承结构:
XXXComparingImpl
<AbstractComparing
<IComparing
<Comparator<Player>
- 依赖
- com.alibaba.game.*: 主函数入口
- com.alibaba.game.texasholdem.*: 基本对象
- com.alibaba.game.texasholdem.ranking.*:
ranking
的逻辑, 每个实现类具有可插拔的性质, 如要扩展牌型规则
, 在这里实现具体的解析类
即可 - com.alibaba.game.texasholdem.comparing.*:
comparing
的逻辑, 每个实现类具有可插拔的性质, 如要扩展牌型比较规则
, 在这里实现具体的比较类
即可 - TEST: 包含对应类的单元测试
- 支持1副牌(52张)的多个玩家(每个玩家5张牌)
- TDD
- 开发的时候系统环境为
jdk7
, 未在7以下的版本运行过 - 代码风格参考了
阿里巴巴java开发手册
, 但还未读完, 因此不完全体现
- 之前从来没玩过德州扑克, 所以简单查了下规则才开始写代码. 所以写代码的本质应该是对业务的理解和抽象, 然后在这基础上的扩展