Design the Data Structures(classes and objects)for a generic deck of cards - GeeksforGeeks

01 Apr, 2019
Design the data structures for a generic deck of cards Explain how you would sub-class it to implement particular card games and how you would subclass the data structures to implement blackjack.
Solution:
First, we need to recognize that a “generic” deck of cards can mean many things. Generic could mean a standard deck of cards that can play a poker-like game, or it could even stretch to Uno or Baseball cards.
To implement particular card games
Let’s assume that the deck is a standard 52-card set like you might see used in a blackjack or poker game. If so, the design might look like this:
The structure is clear here: a deck contains four suits and a suit contains 13 card. Each card has a numerical value from 1 to 13. If you think about a card game, different games differ from ways of dealing cards and putting cards back in. So we can have a set of abstract methods inside the class ‘Deck’ to allow sub-class implements its own way of dealing. The class diagram I draw is here:


Below is C++ implementation of the idea.
/*1. Investigation on an individual card instead of    a collection of cards, focus on a card's state    and interface.2. A card game has its own specific constrain and    requirement on cards, such that a generic card    cannot satisfy a blackjack card3. Player manage multiple cards */  #include <bits/stdc++.h>using namespace std;  namespace SUIT {enum Enum {    SPADE,    HEART,    CLUB,    DIAMOND};};  class Card {private:    SUIT::Enum s;    int v;  public:    virtual SUIT::Enum suit() const    {        return s;    };      virtual int val() const    {        return v;    };      Card(int val, SUIT::Enum suit)        : s(suit), v(val){};};  class BlackJackCard : public Card {public:    virtual int val()    {        int v = Card::val();        if (v < 10)            return v;        return 10;    }      BlackJackCard(int val, SUIT::Enum suit)        : Card(val, suit){};};  class player {private:    int id;    int bet;    set<int> points;    vector<BlackJackCard*> bjcs;    bool addPoint(set<int>& amp; points, BlackJackCard * card)    {        if (points.empty()) {            points.insert(card->val());            if (card->val() == 1)                points.insert(11);        } else {              /* Set elements are ALWAYS CONST, they can't               be modified once inserted. */            set<int> tmp;            for (auto it = points.begin(); it != points.end(); ++it) {                tmp.insert(*it + card->val());                if (card->val() == 1)                    tmp.insert(*it + 11);            }            points = tmp;        }    }      void getPoints()    {        cout << "You All Possible Points : " << endl;        for (auto it = points.begin(); it != points.end(); ++it) {            cout << *it << endl;        }    };      int getMinPoints()    {        /* set is implemented by commonly BST, so else           are in order!!!          learn to use lower_bound() and upper_bound()          "they allow the direct iteration on subsets            based on their order."          which gives us another option to find min. preferable */          // return *(points.lower_bound(0));        return *(points.begin());    };      void printCards()    {        cout << "You Cards : " << endl;        for (auto it = bjcs.begin(); it != bjcs.end(); ++it) {            cout << (*it)->val() << endl;        }    }  public:    player(int i, int j)        : id(i), bet(j)    {        bjcs.push_back(new BlackJackCard(rand() % 13 + 1, SUIT::SPADE));        bjcs.push_back(new BlackJackCard(rand() % 13 + 1, SUIT::SPADE));        addPoint(points, bjcs[0]);        addPoint(points, bjcs[1]);    };      void getAnotherCard()    {        for (set<int>::iterator it = points.begin(); it != points.end(); ++it) {                       /* predefined strategy for the player    */            if (*it <= 21 && 21 - *it <= 4) {                printCards();                getPoints();                cout << "Stand" << endl;                exit(1);            }        }        bjcs.push_back(new BlackJackCard(rand() % 13 + 1, SUIT::SPADE));        addPoint(points, bjcs.back());        if (getMinPoints() > 21) {            printCards();            getPoints();            cout << "Busted" << endl;            exit(2);        }    };      virtual ~player()    {        for (auto it = bjcs.begin(); it != bjcs.end(); ++it) {            delete *it;        }    };};// Driver codeint main(){    srand(time(NULL));    player p(1, 1000);    p.getAnotherCard();    p.getAnotherCard();    p.getAnotherCard();      return 0;}
Output:
You Cards : 
10
10
You All Possible Points : 
20
Stand

To implement Blackjack.
Note: Now, let’s say we’re building a blackjack game, so we need to know the value of the cards. Face cards are 10 and an ace is 11 (most of the time, but that’s the job of the Hand class, not the following class).
At the start of a blackjack game, the players and the dealer receive two cards each. The players’ cards are normally dealt face up, while the dealer has one face down (called the hole card) and one face up.
The best possible blackjack hand is an opening deal of an ace with any ten-point card. This is called a “blackjack”, or a natural 21, and the player holding this automatically wins unless the dealer also has a blackjack. If a player and the dealer each have a blackjack, the result is a push for that player. If the dealer has a blackjack, all players not holding a blackjack lose.


Main logic of Blackjack in Java
public class BlackJackHand extends Hand<BlackJackCard> {      /* There are multiple possible scores for a blackjack    hand, since aces have 3 * multiple values. Return    the highest possible score that's under 21, or the   4 * lowest score that's over. */      public int score()    {        Arraylist<Integer> scores = possibleScores();        int maxUnder = Integer.MIN_VALUE;        int minOver = Integer.MAX_VALUE;        for (int score : scores) {            if (score > 21 & amp; &score < minOver) {                minOver = score;            } else if (score <= 21 & amp; &score > maxUnder) {                maxUnder = score;            }        }        return maxUnder Integer.MIN_VALUE ? minOver maxUnder;    }      /* return a list of all possible scores this hand could have      (evaluating each * ace as both 1 and 11 */    private Arraylist<Integer> possibleScores() { ... }      public boolean busted() { return score() > 21; }    public boolean is21() { return score() == 21; }    public boolean isBlackJack() { ... }}  public class BlackJackCard extends Card {    public BlackJackCard(int c, Suit s) { super(c, s); }    public int value()    {        if (isAce())            return 1;        else if (faceValue >= 11 & amp; &faceValue <= 13)            return 10;        else            return faceValue;    }      public int minValue()    {        if (isAce())            return 1;        else            return value();    }      public int maxValue()    {        if (isAce())            return 11;        else            return value();    }      public boolean isAce()    {        return faceValue == 1;    }      public boolean isFaceCard()    {        return faceValue >= 11 & amp;        &faceValue <= 13;    }}  /* This is just one way of handling aces. We could, alternatively, create a classof type Ace that extends BlackJackCard. */
References :https://www.careercup.com/question?id=2983http://stackoverflow.com/questions/37363008/a-singleton-class-to-design-a-generic-deck-of-card
This article is contributed by Mr. Somesh Awasthi. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
AnamikaPandey2
Amazon
Microsoft
Design Pattern
Amazon
Microsoft
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Command Pattern
Strategy Pattern | Set 1 (Introduction)
Template Method Design Pattern
State Design Pattern
Conceptual Model of the Unified Modeling Language (UML)
Visitor design pattern
Flyweight Design Pattern
Difference between Sequence Diagram and Activity Diagram
Difference Between Architectural Style, Architectural Patterns and Design Patterns