signed

QiShunwang

“诚信为本、客户至上”

(Leeds1721纸牌游戏——百家乐(java实现)

2021/6/3 17:29:10   来源:

百家乐

    • 百家乐规则
    • 如何实现
    • Card类
    • BaccaratCard类
    • BaccaratHand
    • Shoe
    • 小结
    • Full Solution

百家乐规则

使用3~8副,每副52张纸牌,洗在一起,置於发牌盒中,由荷官从其中分发。各家力争手中有两三张牌总点数为9或接近9,K、Q、J和10都计为0,其他牌按牌面计点。计算时,将各家手中的牌值相加,但仅论最後一位数字。当场付赌金最多者为庄家。

百家乐游戏分为庄(Bank)、闲(Play)、和(Tie)与对子(Pair)四门,另外部分赌场有其独特的押注方式,比如大小、庄双、庄单、闲双、闲单。这里的庄、闲,并没有具体的含义,只是代表游戏的双方,和与对子则是为了增加娱乐性而设立的一个彩头。客人根据自己的想法可任意选择庄、闲、和与对子或其他任意一门下注。

如何实现

这个游戏听起来很复杂,所以我们要先理解这个游戏然后再把它转化为计算机看得懂的语言。我们都知道扑克牌含有52张卡牌,而52张卡牌里有4种花色,分别为 黑桃(spade)、红桃(heart)、梅花(club)、方块(diamond),花色大小为:黑桃>红心>方块>梅花。然而每张花色拥有13张牌对应的值为A到K,相信大家应该都熟悉。一套卡牌的定义就解析完毕了,那么我们就可以先写个Card类来定义这些基础内容。毕竟我们的游戏是要建立在有牌的情况下。我们这次实现就只考虑庄家,闲家和和局(其他的玩法不考虑),那么开始实现吧。

Card类

老师已经帮我们写好了这个枚举类,Suit代表花色,Rank代表值,所以我们就不用写了,直接调用即可。

public enum Suit {
    CLUBS('C', '\u2663'), DIAMONDS('D', '\u2666'),
    HEARTS('H', '\u2665'), SPADES('S', '\u2660');
 


public enum Rank {
    ACE('A'), TWO('2'), THREE('3'), FOUR('4'), FIVE('5'),
    SIX('6'), SEVEN('7'), EIGHT('8'), NINE('9'), TEN('T'),
    JACK('J'), QUEEN('Q'), KING('K');

BaccaratCard类

开头我们要解决的是这个类。顾名思义,这个类的作用是确定单张牌的具体值以及对其的操作。开头我们先把老师给的图片里面的框架搭建好,这我就不讲了,不会吧不会吧,不会有人不会搭建框架吧哈哈哈哈哈。搭建完之后呢,就可以开始写老师要求的方法了。但在做之前,我们必须要用到一个东西,这个东西贯穿整个项目也就是java牛逼之处——继承!

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
兔子和羊属于食草动物类,狮子和豹属于食肉动物类。食草动物和食肉动物又是属于动物类。虽然食草动物和食肉动物都是属于动物,但是两者的属性和行为上有差别,所以子类会具有父类的一般特性也会具有自身的特性。

使用了继承我们就可以直接调用父亲大人Card里面的Rank和Suit了,把想加的类用extends连接。getRank和getSuit这种弱智题就不讲了,一个return完事有手就行。我们直接看toString(),这个方法也特别特别特别简单,就是把卡牌转换为字符串类型呗。那么我们直接用String.format方法一句话就搞定了(要import lang库)。

 return String.format("%c%c", rank.getSymbol(),suit.getSymbol());

getSymbol()是在Card里面的方法,作用是获取符号的值。

Equals()就是判断两张牌的花色和值是否一样。给了一个参数other,我们就写一个if else就解决了,值得注意的点,equal是返回true和false。一样就返回true,不一样就返回false。

compareTo()怎么做呢,先来分析一下里面的参数other的类是Card,那么我们在获取other的suit和rank时就不能直接.rank,因为Card里面suit和rank是私有变量。所以我们要用到getSuit(),和getRank()了。这个方法是先比较花色再比较rank,花色就按照直接的排名进行比较,如果花色一样再比较值。**compareTo的方法是如果大于则返回1,相同则返回0,小于则返回-1。**所以我们就可以这样写:定义一个int类型的变量,这个变量等于other的花色比较这this的花色返回的值,然后return这个变量。在这中间加个if判断:如果这两个花色的大小一样,则变量等于other的rank和this的rank比较返回的值。

value()——写这个方法前,我们要知道百家乐值的规则是10及以上大小都是10。所以我们就定义一个char类,然后获取rank的值,根据值返回对应的大小,大于等于10就都返回10。(返回0也可以,因为手牌的值加减的规则是超过10减10。)

BaccaratHand

这个类的是用来储存刚刚写的BaccaratCard对象的。通俗易懂就是手牌。这个继承的对象是老师写的另外一个类CardCollection.里面老师写好了一个Card类型的cards list,用来存手牌。size()和add()太简单了就不讲了,一句话的事情。我们直接看value()。

value()这个方法要求就是计算手牌中卡牌的大小。所以我们肯定要循环遍历,那么就写一个for循环。定义一个int类型变量初始化为0。然后遍历一张牌就把那张牌的值加上去。循环完return这个变量就搞定了。(特别注意一点,老师写的是Linklist类型,这个方法不能用[]这玩意,要用它专门的获取方法get(),我当时写也栽了个跟头笑死)

isNatural()——这个方法就是判断手牌的值是否为所谓的Natural我也不知道这他妈是啥,反正很牛逼就对了,其百家乐规则为手牌的值加起来为8或者9就称为natural,那么很简单了,一个if else搞定(注意return的是true和false)。

toString()——这个方法就是把手牌的值转换为字符串类型。对字符串进行操作我们可以选择用StringBulider或者StringBuffer类,但因为StringBuilder的速度比StringBuffer快所以我们普遍选择前者。那么久循环遍历原来list的每个值然后用append()加进自己new的StringBuilder里面。最后把StringBuilder类转换成String类就搞定了。

Shoe

这个类就是牌库的意思,主要对构造器进行操作,方法都很简单。size()就不说了,Shuffle()方法直接用collection库里自带的shuffle方法就搞定了。deal()方法也很简单,remove牌库第一张牌就搞定了,如果牌库是空的就抛错。

构造器操作
PDF定义了两个情况一个是decks为6,另一个是decks为8的情况。decks就是套牌的意思,6就是6套牌,8就是8套牌。所以我们就要在构造器里去把52X6的牌或者52X8的牌add到Cardcollection里面定义好的list里面。先两个if判断decks为6还是为8,然后在if里面写一个3重循环把这些牌都加进list里面就搞定了。

小结

这个游戏项目考验了对题目的逻辑分析,类与类之前的概念要清晰,继承的概念,字符串的熟练运用操作,方法的掌握及其返回类型,最重要的是改bug能力!!笑死在这里插入图片描述

Full Solution

最后给大家看一下完成结果,虽然还有点功能没写完,不过不着急,诶,就是玩~(别忘了随手点个赞Thanks♪(・ω・)ノ)

Round5
--------------------------------
|Player: 5S 3D = 8              |
|Banker: 4H 5D = 9              |
|Dealing third card to player...|
|Dealing third card to banker...|
|Player: 5S 3D 2D = 0           |
|Banker: 4H 5D 2D = 1           |
|Banker Win!                    |
--------------------------------

Round6
--------------------------------
|Player: 8D 9S = 7              |
|Banker: KS QC = 0              |
|Dealing third card to player...|
|Dealing third card to banker...|
|Player: 8D 9S 6C = 3           |
|Banker: KS QC 3S = 3           |
|Tie!                           |
--------------------------------

Round7
--------------------------------
|Player: 3H QD = 3              |
|Banker: JS AS = 1              |
|Dealing third card to player...|
|Dealing third card to banker...|
|Player: 3H QD TC = 3           |
|Banker: JS AS JS = 1           |
|Player Win!                    |
--------------------------------

Round8
--------------------------------
|Player: KD 2S = 2              |
|Banker: 2C JS = 2              |
|Dealing third card to player...|
|Dealing third card to banker...|
|Player: KD 2S QC = 2           |
|Banker: 2C JS 5H = 7           |
|Banker Win!                    |
--------------------------------

Round9
--------------------------------
|Player: KC 5D = 5              |
|Banker: KS 5D = 5              |
|Dealing third card to player...|
|Dealing third card to banker...|
|Player: KC 5D 2D = 7           |
|Banker: KS 5D 9S = 4           |
|Player Win!                    |
--------------------------------

9rounds played
3player wins
4banker wins
2ties