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

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

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


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


题目:


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


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


解决方案:


首先,我们需要认识到“通用”的扑克牌可以有很多种。通用可能意味着可以用于类似扑克的游戏的标准牌组,或者甚至可以扩展到Uno或棒球卡。


实现特定的扑克牌游戏


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


这里的结构很清晰:一副牌包含四种花色和13张牌。每张牌的数字值从1到13。如果您考虑一下扑克牌游戏,不同的游戏有不同的发牌和回收牌的方式。因此,我们可以在“Deck”类中有一组抽象方法,以允许子类实现其自己的发牌方式。我画的类图在这里:


imgimg

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 HEARTS
true
10

这表明我们成功地创建了一个通用的扑克牌数据结构,并使用继承的方式,实现了特定的扑克游戏和二十一点游戏。


完整代码如下:


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
    }
}

相关文章
|
存储 数据格式 运维
开发与运维C++问题之更改数据模型为通用数据结构如何解决
开发与运维C++问题之更改数据模型为通用数据结构如何解决
162 1
|
存储 NoSQL Java
基于内存的分布式NoSQL数据库Redis(二)数据结构与通用命令
基于内存的分布式NoSQL数据库Redis(二)数据结构与通用命令
299 0
|
存储 架构师 算法
每个程序员都必须知道的8种通用数据结构
数据结构是一种特殊的组织和存储数据的方式,可以使我们可以更高效地对存储的数据执行操作。数据结构在计算机科学和软件工程领域具有广泛而多样的用途。
|
数据库
【自然框架】之通用权限(一):简介、数据结构
      这次要写一整套的权限方面的文章了,无论我的想法好与不好,先写出来请大家来评判。这个系列我要详细的说明我的权限的思路、想法、实现方式、代码和Demo。可能有人会说,通用是达不到的,最多只能无限接近。
1156 0
|
NoSQL PHP Redis
高可用Redis(一):通用命令,数据结构和内部编码,单线程架构
1.通用API 1.1 keys命令和dbsize命令 keys * 遍历所有key keys [pattern] 遍历模式下所有的key dbsize 计算Redis中所有key的总数 例子: 127.
1313 0
|
算法 C++
一步一步写算法(之通用数据结构)
原文: 一步一步写算法(之通用数据结构) 【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】     上一篇博客介绍了通用算法,那么有了这个基础我们可以继续分析通用数据结构了。
776 0
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
399 59

热门文章

最新文章