为一副通用纸牌设计数据结构

大家好,我是易安,明天咱们来聊一道口试题,这也是我已经面试华为时做过的题,明天分享给大家。

题目:

如何设计一个通用的扑克牌数据结构?请解释如何继承它来实现特定的扑克游戏,以及如何继承这些数据结构来实现二十一点游戏。

倡议:请先在IDE上尝试解法,而后再去看解决方案

解决方案:

首先,咱们须要意识到“通用”的扑克牌能够有很多种。通用可能意味着能够用于相似扑克的游戏的规范牌组,或者甚至能够扩大到Uno或棒球卡。

实现特定的扑克牌游戏

假如这个牌组是一个规范的52张牌组,就像你在二十一点或扑克游戏中看到的那样。如果是这样,设计可能看起来像这样:

这里的构造很清晰:一副牌蕴含四种花色和13张牌。每张牌的数字值从1到13。如果您考虑一下扑克牌游戏,不同的游戏有不同的发牌和回收牌的形式。因而,咱们能够在“Deck”类中有一组形象办法,以容许子类实现其本人的发牌形式。我画的类图在这里:

Java版本:

这里只是写了大略的流程节点,要害须要你本人补充

要设计一个通用的扑克牌数据结构,能够思考应用以下类来示意扑克牌:

public class Card {    private final Suit suit; // 花色    private final Rank rank; // 点数    public Card(Suit suit, Rank rank) {        this.suit = suit;        this.rank = rank;    }    // Getter and Setter methods    @Override    public String toString() {        return rank + " of " + suit;    }}public enum Suit {    CLUBS, DIAMONDS, HEARTS, SPADES;}public enum Rank {    ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING;}

Card类有两个实例变量:suitrank,别离示意花色和点数。SuitRank别离是枚举类型,用于限定花色和点数的范畴。通过这个类,咱们能够轻松地创立一副扑克牌。

为了实现特定的扑克游戏,能够创立一个继承自Card的类,来示意具备非凡规定的游戏中的牌。例如,在五十二张牌的德州扑克中,有四种花色和十三种点数,然而在游戏中,有一张叫做“大王”的牌,它并不属于上述任何一种花色或点数。能够创立一个TexasHoldemCard类,继承自Card类,并增加一个名为isJoker()的办法,用于判断该牌是否为“大王”。

public class TexasHoldemCard extends Card {    private boolean isJoker;    public TexasHoldemCard(Suit suit, Rank rank) {        super(suit, rank);        this.isJoker = false;    }    public boolean isJoker() {        return isJoker;    }    public void setJoker(boolean joker) {        isJoker = joker;    }}

TexasHoldemCard类中,增加了一个名为isJoker()的办法,用于判断该牌是否为“大王”。如果是“大王”,则返回true;否则返回false

为了实现二十一点游戏,能够创立一个名为Blackjack的类,继承自Card类,用于示意二十一点游戏中的牌。在二十一点游戏中,每张牌都有一个点数,其中A牌能够示意1或11点,而J、Q、K牌都示意10点。因而,在Blackjack类中,须要增加一个名为getValue()的办法,用于返回该牌的点数。

public class BlackjackCard extends Card {    public BlackjackCard(Suit suit, Rank rank) {        super(suit, rank);    }    public int getValue() {        switch (rank) {            case TWO:                return 2;            case THREE:                return 3;            case FOUR:             return 4;        case FIVE:            return 5;        case SIX:            return 6;        case SEVEN:            return 7;        case EIGHT:            return 8;        case NINE:            return 9;        case TEN:        case JACK:        case QUEEN:        case KING:            return 10;        case ACE:            return 1; // A牌默认为1点        default:            throw new IllegalStateException("Unexpected value: " + rank);    } }}

BlackjackCard类中,增加了一个名为getValue()的办法,用于返回该牌的点数。在此办法中,应用了一个switch语句,依据不同的点数返回不同的点数值。须要留神的是,A牌的点数能够为1或11,然而在此办法中默认为1。

当初,咱们曾经设计了通用的扑克牌数据结构,并且应用继承的形式,实现了特定的扑克游戏和二十一点游戏。上面是一个简略的例子,展现如何应用上述代码:

public class Main {    public static void main(String[] args) {        Card card = new Card(Suit.HEARTS, Rank.ACE);        System.out.println(card); // Output: ACE of HEARTS        TexasHoldemCard joker = new TexasHoldemCard(Suit.CLUBS, Rank.ACE);        joker.setJoker(true);        System.out.println(joker.isJoker()); // Output: true        BlackjackCard king = new BlackjackCard(Suit.SPADES, Rank.KING);        System.out.println(king.getValue()); // Output: 10    }}

在上述代码中,首先创立了一个一般的扑克牌对象,而后创立了一个继承自CardTexasHoldemCard对象,该对象被标记为“大王”,最初创立了一个继承自CardBlackjackCard对象,示意一张K牌,其点数为10。

运行该程序,输入后果为:

ACE of HEARTStrue10

这表明咱们胜利地创立了一个通用的扑克牌数据结构,并应用继承的形式,实现了特定的扑克游戏和二十一点游戏。

残缺代码如下:

public class Card {    private final Suit suit; // 花色    private final Rank rank; // 点数    public Card(Suit suit, Rank rank) {        this.suit = suit;        this.rank = rank;    }    public Suit getSuit() {        return suit;    }    public Rank getRank() {        return rank;    }    @Override    public String toString() {        return rank + " of " + suit;    }}enum Suit {    CLUBS, DIAMONDS, HEARTS, SPADES;}enum Rank {    ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING;}public class TexasHoldemCard extends Card {    private boolean isJoker;    public TexasHoldemCard(Suit suit, Rank rank) {        super(suit, rank);        this.isJoker = false;    }    public boolean isJoker() {        return isJoker;    }    public void setJoker(boolean joker) {        isJoker = joker;    }}public class BlackjackCard extends Card {    public BlackjackCard(Suit suit, Rank rank) {        super(suit, rank);    }    public int getValue() {        switch (rank) {            case TWO:                return 2;            case THREE:                return 3;            case FOUR:                return 4;            case FIVE:                return 5;            case SIX:                return 6;            case SEVEN:                return 7;            case EIGHT:                return 8;            case NINE:                return 9;            case TEN:            case JACK:            case QUEEN:            case KING:                return 10;            case ACE:                return 1; // A牌默认为1点            default:                throw new IllegalStateException("Unexpected value: " + rank);        }    }}public class Main {    public static void main(String[] args) {        Card card = new Card(Suit.HEARTS, Rank.ACE);        System.out.println(card); // Output: ACE of HEARTS        TexasHoldemCard joker = new TexasHoldemCard(Suit.CLUBS, Rank.ACE);        joker.setJoker(true);        System.out.println(joker.isJoker()); // Output: true        BlackjackCard king = new BlackjackCard(Suit.SPADES, Rank.KING);        System.out.println(king.getValue()); // Output: 10    }}

本文由mdnice多平台公布