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

• Difficulty Level : Hard
• Last Updated : 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.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 card``3. Player manage multiple cards */`` ` `#include ``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 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);``        ``addPoint(points, bjcs);``    ``};`` ` `    ``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 code``int` `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 {`` ` `    ``/* 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 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 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 class``of type Ace that extends BlackJackCard. */`

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.