Skip to content

Cards

7 of DiamondsCard Back

A fun demo that’s also good for learning JavaScript is to model the concepts around card games. Not only do we get to design JavaScript objects with interesting properties, we also get to create interesting logic for manipulating playing cards within a deck.

How would you design the idea of a playing card in a standard deck of 52 cards? Begin with pondering the information that makes up the concept of a playing card.

A playing card can be one of four suits.

  • ♠️ Spades
  • ♥️ Hearts
  • ♦️ Diamonds
  • ♣️ Clubs

Next, a playing card has a value which can range from 2 to 10 and the named values of “Jack”, “Queen”, “King”, and “Ace”.

Together, the suit and value make up the essense of a standard playing card. In JavaScript, we could represent it as an object.

let card = { suit: 'Diamonds', value: '7' };

While the idea of a playing card is pretty simple, we can quickly run into a number of design implications when we want to apply the concept to any given program.

First of all is the question of the range of possible values for any given playing card. Next might be how we want to conceptualize those values. After that, we will probably want to investigate the idea of collections of cards and the most common collection: the Deck. Once we start working with collections, we might want some way to identify specific cards in the deck.

All of these core questions and concerns will, themselves, have implications for how a particular card game might be designed, such as War, Go Fish or Solitaire.

In this demo, I will walk you through some possible ways to address those core concerns. You will find JavaScript to be an excellent language for modeling playing cards!

Having a couple of sources that represent all the possible suits and values in a standard deck can be useful. Your first thought might be to represent these as simple arrays.

const cardSuits = [ 'Spades', 'Hearts', 'Diamonds', 'Clubs' ];
const cardValues = [ 'Ace', '2', '3', '4', '5', '6', '7',
'8', '9', '10', 'Jack', 'Queen', 'King' ];

Notice how we treat all the values as strings. We’re doing that to have a sense of type consistency between the idea of a “Two” and an “Ace”.

A problem with using arrays, however, is that arrays are mutable by default. That means we could potentially add or remove items from the array.

// Bad idea
suits.push('Feet'); // ??
// [ 'Spades', 'Hearts', 'Diamonds', 'Clubs', 'Feet' ]

Is there a way to prevent that? Yes, there is! We can use Object.freeze(). With it, we can make our suits and values immutable (or unchangeable).

“Freezing an object is the highest integrity level that JavaScript provides.”MDN

Here’s how we can do this. (For the sake of completeness, I’ve also included the ‘Joker’ as a possible value, even though it’s “special” in the sense that a standard deck comes with only two Jokers and they are never associated with a card suit.)

const CARD_SUITS = [ 'Spades', 'Hearts', 'Diamonds', 'Clubs' ];
Object.freeze(CARD_SUITS); // Make suits immutable
const CARD_VALUES = [ 'Ace', '2', '3', '4', '5', '6', '7', '8',
'9', '10', 'Jack', 'Queen', 'King', 'Joker' ];
Object.freeze(CARD_VALUES); // Make values immutable

Notice the little adjustment to the names we’re using for these fixed arrays. We’re putting the variable names in all upper-case as a visual ‘cue’ that these cannot be physically modified. That cue will remind us that these are immutable/unchanging.

Queen of HeartsCard Back

With the frozen CARD_SUITS and CARD_VALUES, we already have a pretty healthy start to our game pieces. If we wanted to, we could start writing the code for a simple game using just these two variables.

But what if we wanted some variety in how we communicate the ideas of suits and values? For example, we might want to talk about the “2 of Hearts” or the “Two of Hearts”. One way uses the digit 2 while the other uses the word "Two". Furthermore, we might be interested in using emoji symbols for the suits.

Let’s expand on our two arrays with two more arrays: CARD_VALUE_NAMES and CARD_SUIT_SYMBOLS.

const CARD_SUITS = [ 'Spades', 'Hearts', 'Diamonds', 'Clubs' ];
const CARD_SUIT_SYMBOLS = [ '♠️', '♥️', '♦️', '♣️' ];
const CARD_VALUES = [ 'Ace', '2', '3', '4', '5', '6', '7', '8',
'9', '10', 'Jack', 'Queen', 'King', 'Joker' ];
const CARD_VALUE_NAMES = [ 'Ace', 'Two', 'Three', 'Four', 'Five',
'Six', 'Seven', 'Eight', 'Nine', 'Ten',
'Jack', 'Queen', 'King', 'Joker' ];
// Make these immutable
Object.freeze(CARD_SUITS);
Object.freeze(CARD_SUIT_SYMBOLS);
Object.freeze(CARD_VALUES);
Object.freeze(CARD_VALUE_NAMES);

Notice the great care I took in building these arrays. Each pair of arrays are set up as parallel arrays. A Parallel Array (or corresponding array) is one where the items in the arrays correspond to each other based on their position in the array.

Thus, CARD_VALUES[1] maps to CARD_VALUE_NAMES[1], allowing me to treat '2' and 'Two' as being conceptually equivalent. Likewise, CARD_SUITS[2] and CARD_SUIT_SYMBOLS[2] are also talking about the same suit: ♦️ is the symbol for ‘Diamonds’.

With these, we can create nice utility functions to generate content for the end-user.

function nameCard(valueIndex, suitIndex) {
return `${CARD_VALUE_NAMES[valueIndex]} of ${CARD_SUITS[suitIndex]}`;
}
let myCard = nameCard(1, 2); // 'Two of Diamonds'

What about when we combine a suit and a value to be a single card? What should such an object “look like”? Honestly, it doesn’t matter. You can design it in whatever way suits you. (I’ve been waiting to deal out that pun!)

Here is one such design (with hard-coded values).

let tuckInSleeve = {
suit: '♦️',
value: 'Ace',
name: 'Ace of Diamonds'
}

We’ll revise our object designs once we get into creating certain algorithms. As long as we’ve got some common core concepts coded, we can transform and re-map these to whatever shape we want later on.

There’s an API I want to eventually show you that’s all about playing cards. It’s called DeckOfCardsAPI.com. It’s a free API that you can use to generate decks of cards along with as many associated piles of cards that you might want for your game. In fact, the card images I am using on this site come from DeckOfCardsAPI.com. Some of my design choices for playing cards have been shaped by how they use/represent cards.

One of the aspects of Chase’s API that I like to use is the notion of a code that uniquely identifies a playing card. In fact, it’s probably the one design decision that makes it affordable and possible to store everybody’s cards and piles for as long as they do!

Each card can be represented simply by a two-character code that identifies the value and the suit. The first character is the digit or first letter of the card’s value (with the one exception of the value 10, which is represented by a '0'). The second character is the first letter of the card’s suit (in upper-case). That’s it! It’s elegant and clean. All of the other aspects of their JSON responses can be programmatically generated on-the-fly from that two-character code.

Let’s add that to our set of value concepts.

const CARD_CODES = ['AS', '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', '0S', 'JS', 'QS', 'KS', 'AD', '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', '0D', 'JD', 'QD', 'KD', 'AC', '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', '0C', 'JC', 'QC', 'KC', 'AH', '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', '0H', 'JH', 'QH', 'KH'];
Object.freeze(CARD_CODES);

With this, we can include some simple utility functions to handle mapping card codes to suits and values and vice-versa.

const isCardCode = (code) => typeof code === 'string' && code.length === 2 && 'A234567890JQK'.includes(code[0]) && 'SHDC'.includes(code[1]);
const suitFromCode = (code) => CARD_SUITS.find(suit => suit.startsWith(code[1]));
const valueFromCode = (code) => CARD_VALUES.find(value => value.startsWith(code[0] || value.endsWith(code[0])));
const toCode = ({value, suit}) => `${value[0] === '1' ? '0' : value[0]}${suit[0]}`;

Here’s my re-design of the Playing Card. Notice how I’m using JSDoc comments to define the structure of my playing card.

/** @typedef {{ code: string, value: string, suit: string}} Card */

You can then use that JSDoc type definition for variables that you can create. For example, a pile of cards can simply be an array of Card types.

/** @type {Card[]} */
let discardPile = [];
// ... sometime later ...
discardPile.push({ code: 'AH', value: 'Ace', suit: 'Hearts' }); // dealt from the bottom....

This will become very useful down the road in terms of generating intellisense within VS Code. For example, consider that utility function we created earlier for getting the name of any given card. We can re-write that as follows:

/**
* Describe a playing card.
*
* @param {Card} card A playing card object
* @param {boolean} valueName Whether or not to use the name or the digit for the value (defaults to `true`)
* @param {boolean} emoji Whether or not to use an emoji for the suit (defaults to `false`)
*/
function nameCard(card, valueName = true, emoji = false) {
const valueIndex = CARD_VALUES.indexOf(card.value);
const suitIndex = CARD_SUITS.indexOf(card.suit);
let theSuit = CARD_SUITS[suitIndex];
if(emoji) {
theSuit = CARD_SUIT_SYMBOLS[suitIndex];
}
let theName = CARD_VALUES[valueIndex];
if(valueName) {
theName = CARD_VALUE_NAMES[valueIndex];
}
return `${theName} of ${theSuit}`;
}

With a clear definition for our playing card, we can move on to thinking about collections of cards, such as our deck.

Simply put, a deck is just a collection or array of cards. Just about the only extra piece of useful information is knowing whether or not the deck is shuffled. (Hint: When you open a fresh deck, it’s always “unshuffled”.)

/** @typedef {{shuffled: boolean, cards: Card[]}} Deck */

Because we have frozen variables for the range of possible values, creating a deck is pretty straight forward. Just start with the CARD_CODES and a little utility function to generate the Card objects.

const buildDeck = () => ({
shuffled: false,
cards: CARD_CODES.map(x => ({ code:x , suit: suitFromCode(x), value: valueFromCode(x) }))
});

We probably could just do a loop within a loop to be a little more efficient, or we could even hard-code all the cards for blazing-fast run-time results. Either way, creating a fresh deck is easy peasy.

Closely related to the concept of a deck is the concept of a “pile” of cards. The big difference is that a “pile” is typically not an entire deck. The pile might be created in any number of ways depending on the purpose of the pile. Maybe we are creating piles by “dealing” cards to different players; here each “pile” becomes the player’s “hand”. Or maybe it’s a “discard pile” or a “scoring pile”. Either way, it’s just an array of cards.

We can add a simple meta-data item to give the pile meaning: add a name to describe its purpose.

/** @typedef {{name: string, cards: Card[]}} Pile */

With types, constants and utility functions in hand, we have all the building blocks for any card game. There are a few additional algorithms commonly used among different card games, of course. But now you have what amounts to a nice bunch of code you can expose as a JavaScript module, ready to import into whatever game you want.

Here’s the summary code.

deckOfCards.js
// Type definitions
/** @typedef { { code: string, value: string, suit: string } } Card */
/** @typedef { { shuffled: boolean, cards: Card[] } } Deck */
/** @typedef { { name: string, cards: Card[] } } Pile */
// Hard-coded ranges
const CARD_SUITS = [ 'Spades', 'Hearts', 'Diamonds', 'Clubs' ];
const CARD_SUIT_SYMBOLS = [ '♠️', '♥️', '♦️', '♣️' ];
const CARD_VALUES = [ 'Ace', '2', '3', '4', '5', '6', '7', '8',
'9', '10', 'Jack', 'Queen', 'King', 'Joker' ];
const CARD_VALUE_NAMES = [ 'Ace', 'Two', 'Three', 'Four', 'Five',
'Six', 'Seven', 'Eight', 'Nine', 'Ten',
'Jack', 'Queen', 'King', 'Joker' ];
const CARD_CODES = [ 'AS', '2S', '3S', '4S', '5S', '6S', '7S',
'8S', '9S', '0S', 'JS', 'QS', 'KS',
'AD', '2D', '3D', '4D', '5D', '6D', '7D',
'8D', '9D', '0D', 'JD', 'QD', 'KD',
'AC', '2C', '3C', '4C', '5C', '6C', '7C',
'8C', '9C', '0C', 'JC', 'QC', 'KC',
'AH', '2H', '3H', '4H', '5H', '6H', '7H',
'8H', '9H', '0H', 'JH', 'QH', 'KH'];
// Make these immutable
Object.freeze(CARD_SUITS);
Object.freeze(CARD_SUIT_SYMBOLS);
Object.freeze(CARD_VALUES);
Object.freeze(CARD_VALUE_NAMES);
Object.freeze(CARD_CODES);
// Utility functions
/**
* Determine if the string is a valid card code
*
* @param {string} code - A string to examine
* @returns {boolean} `true` if `code` is a valid card code
*/
const isCardCode = (code) => typeof code === 'string' &&
code.length === 2 &&
'A234567890JQK'.includes(code[0]) &&
'SHDC'.includes(code[1]);
const suitFromCode = (code) => CARD_SUITS.find(suit =>
suit.startsWith(code[1]));
const valueFromCode = (code) => CARD_VALUES.find(value =>
value.startsWith(code[0] || value.endsWith(code[0])));
const toCode = ({value, suit}) => `${value[0] === '1' ? '0' : value[0]}${suit[0]}`;
/**
* Build a single playing card from a card code.
*
* If the supplied code is not a valid card code, then this function returns null.
*
* @param {string} code - A valid card code
* @returns {Card | null} A playing card
*/
const buildCard = (code) => {
let result = null;
if(isCardCode(code)) {
result = {
code,
suit: suitFromCode(code),
value: valueFromCode(code)
}
}
return result;
}
/**
* Build a fresh deck of cards
*
* @returns {Deck}
*/
const buildDeck = () => {
return {
shuffled: false,
cards: CARD_CODES.map(buildCard)
}
};
/**
* Describe a playing card.
*
* @param {Card} card A playing card object
* @param {boolean} valueName `true` to use the name or the digit for the value (defaults to `true`)
* @param {boolean} emoji `true` to use an emoji for the suit (defaults to `false`)
*/
function nameCard(card, valueName = true, emoji = false) {
const valueIndex = CARD_VALUES.indexOf(card.value);
const suitIndex = CARD_SUITS.indexOf(card.suit);
let theSuit = CARD_SUITS[suitIndex];
if(emoji) {
theSuit = CARD_SUIT_SYMBOLS[suitIndex];
}
let theName = CARD_VALUES[valueIndex];
if(valueName) {
theName = CARD_VALUE_NAMES[valueIndex];
}
return `${theName} of ${theSuit}`;
}
// You can export more items, but these are good ones to start with.
export {
// Primitive ranges
CARD_SUITS, CARD_SUIT_SYMBOLS, CARD_VALUES, CARD_VALUE_NAMES,
// These are the essentials
CARD_CODES, isCardCode, buildCard, buildDeck, nameCard
}

What constitutes a useful card algorithm? Probably ones that help you manage decks and piles of cards.

We can programmatically generate a card code from the suit and value arrays. It won’t be as efficient as a hard-coded array, but it’s a great example of using a loop within a loop!

What makes a good shuffling algorithm? Randomness.

TBD

TBD

If you need to deal cards from a deck, there are several ways to achieve this.

TBD

Moving cards into and out of piles or the deck can be quite useful.

TBD


Here’s some raw code to integrate into this page…

Raw Code
const cardCodes = ['AS', '2S', '3S', '4S', '5S', '6S', '7S', '8S', '9S', '0S', 'JS', 'QS', 'KS', 'AD', '2D', '3D', '4D', '5D', '6D', '7D', '8D', '9D', '0D', 'JD', 'QD', 'KD', 'AC', '2C', '3C', '4C', '5C', '6C', '7C', '8C', '9C', '0C', 'JC', 'QC', 'KC', 'AH', '2H', '3H', '4H', '5H', '6H', '7H', '8H', '9H', '0H', 'JH', 'QH', 'KH'];
const deck = presetDeck();
const back = '/back.png';
const cards = cardCodes.map(code => `/${code}.svg`);
class Player {
constructor(name) {
}
}
const player_1 = new Player('Player Won');
const log = console.log;
log(draw(deck, 50).map(x => x.code));
log(deck.cards.map(x => x.code));
log(presetDeck().cards.map(x => x.code));
/**
* Generates the short code of a playing card
* @param {Card} card A Playing Card
* @returns {string} The code for the playing card
*/
function asCode(card) {
return card.code;
}
/**
* Generates the descriptive name of a playing card
* @param {Card} card A Playing Card
* @returns {string} The name of the playing card
*/
function asName(card) {
return `${card.value} of ${card.suit}`;
}
/** @typedef {{ code: string, value: string, suit: string}} Card */
/** @typedef {{success: boolean, deck_id: string, cards: Card[], remaining: number}} Deck */
/**
* Draws cards from a deck (if any are available).
*
* This is a mutating function, meaning that it will modify the list of cards in the deck
* @param {Deck} deck
* @param {number} count
* @returns {Card[]} An array of cards from the deck
*/
function draw(deck, count) {
const result = deck.cards.splice(0,count);
deck.remaining = deck.cards.length;
return result;
}
/**
* Make a deck of 52 cards in a preset (shuffled) order.
* @returns {Deck}
*/
function presetDeck() {
return {
"success": true,
"deck_id": "3bwa184i6asi",
"cards": [
{
"code": "4D",
"image": "https://deckofcardsapi.com/static/img/4D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/4D.svg",
"png": "https://deckofcardsapi.com/static/img/4D.png"
},
"value": "4",
"suit": "DIAMONDS"
},
{
"code": "3D",
"image": "https://deckofcardsapi.com/static/img/3D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/3D.svg",
"png": "https://deckofcardsapi.com/static/img/3D.png"
},
"value": "3",
"suit": "DIAMONDS"
},
{
"code": "4H",
"image": "https://deckofcardsapi.com/static/img/4H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/4H.svg",
"png": "https://deckofcardsapi.com/static/img/4H.png"
},
"value": "4",
"suit": "HEARTS"
},
{
"code": "6S",
"image": "https://deckofcardsapi.com/static/img/6S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/6S.svg",
"png": "https://deckofcardsapi.com/static/img/6S.png"
},
"value": "6",
"suit": "SPADES"
},
{
"code": "3H",
"image": "https://deckofcardsapi.com/static/img/3H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/3H.svg",
"png": "https://deckofcardsapi.com/static/img/3H.png"
},
"value": "3",
"suit": "HEARTS"
},
{
"code": "4S",
"image": "https://deckofcardsapi.com/static/img/4S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/4S.svg",
"png": "https://deckofcardsapi.com/static/img/4S.png"
},
"value": "4",
"suit": "SPADES"
},
{
"code": "JC",
"image": "https://deckofcardsapi.com/static/img/JC.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/JC.svg",
"png": "https://deckofcardsapi.com/static/img/JC.png"
},
"value": "JACK",
"suit": "CLUBS"
},
{
"code": "3C",
"image": "https://deckofcardsapi.com/static/img/3C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/3C.svg",
"png": "https://deckofcardsapi.com/static/img/3C.png"
},
"value": "3",
"suit": "CLUBS"
},
{
"code": "7C",
"image": "https://deckofcardsapi.com/static/img/7C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/7C.svg",
"png": "https://deckofcardsapi.com/static/img/7C.png"
},
"value": "7",
"suit": "CLUBS"
},
{
"code": "6C",
"image": "https://deckofcardsapi.com/static/img/6C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/6C.svg",
"png": "https://deckofcardsapi.com/static/img/6C.png"
},
"value": "6",
"suit": "CLUBS"
},
{
"code": "8H",
"image": "https://deckofcardsapi.com/static/img/8H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/8H.svg",
"png": "https://deckofcardsapi.com/static/img/8H.png"
},
"value": "8",
"suit": "HEARTS"
},
{
"code": "KD",
"image": "https://deckofcardsapi.com/static/img/KD.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/KD.svg",
"png": "https://deckofcardsapi.com/static/img/KD.png"
},
"value": "KING",
"suit": "DIAMONDS"
},
{
"code": "KH",
"image": "https://deckofcardsapi.com/static/img/KH.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/KH.svg",
"png": "https://deckofcardsapi.com/static/img/KH.png"
},
"value": "KING",
"suit": "HEARTS"
},
{
"code": "JH",
"image": "https://deckofcardsapi.com/static/img/JH.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/JH.svg",
"png": "https://deckofcardsapi.com/static/img/JH.png"
},
"value": "JACK",
"suit": "HEARTS"
},
{
"code": "QH",
"image": "https://deckofcardsapi.com/static/img/QH.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/QH.svg",
"png": "https://deckofcardsapi.com/static/img/QH.png"
},
"value": "QUEEN",
"suit": "HEARTS"
},
{
"code": "7H",
"image": "https://deckofcardsapi.com/static/img/7H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/7H.svg",
"png": "https://deckofcardsapi.com/static/img/7H.png"
},
"value": "7",
"suit": "HEARTS"
},
{
"code": "AS",
"image": "https://deckofcardsapi.com/static/img/AS.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/AS.svg",
"png": "https://deckofcardsapi.com/static/img/AS.png"
},
"value": "ACE",
"suit": "SPADES"
},
{
"code": "8S",
"image": "https://deckofcardsapi.com/static/img/8S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/8S.svg",
"png": "https://deckofcardsapi.com/static/img/8S.png"
},
"value": "8",
"suit": "SPADES"
},
{
"code": "3S",
"image": "https://deckofcardsapi.com/static/img/3S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/3S.svg",
"png": "https://deckofcardsapi.com/static/img/3S.png"
},
"value": "3",
"suit": "SPADES"
},
{
"code": "8C",
"image": "https://deckofcardsapi.com/static/img/8C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/8C.svg",
"png": "https://deckofcardsapi.com/static/img/8C.png"
},
"value": "8",
"suit": "CLUBS"
},
{
"code": "0S",
"image": "https://deckofcardsapi.com/static/img/0S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/0S.svg",
"png": "https://deckofcardsapi.com/static/img/0S.png"
},
"value": "10",
"suit": "SPADES"
},
{
"code": "7S",
"image": "https://deckofcardsapi.com/static/img/7S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/7S.svg",
"png": "https://deckofcardsapi.com/static/img/7S.png"
},
"value": "7",
"suit": "SPADES"
},
{
"code": "6H",
"image": "https://deckofcardsapi.com/static/img/6H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/6H.svg",
"png": "https://deckofcardsapi.com/static/img/6H.png"
},
"value": "6",
"suit": "HEARTS"
},
{
"code": "4C",
"image": "https://deckofcardsapi.com/static/img/4C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/4C.svg",
"png": "https://deckofcardsapi.com/static/img/4C.png"
},
"value": "4",
"suit": "CLUBS"
},
{
"code": "JD",
"image": "https://deckofcardsapi.com/static/img/JD.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/JD.svg",
"png": "https://deckofcardsapi.com/static/img/JD.png"
},
"value": "JACK",
"suit": "DIAMONDS"
},
{
"code": "9S",
"image": "https://deckofcardsapi.com/static/img/9S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/9S.svg",
"png": "https://deckofcardsapi.com/static/img/9S.png"
},
"value": "9",
"suit": "SPADES"
},
{
"code": "0D",
"image": "https://deckofcardsapi.com/static/img/0D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/0D.svg",
"png": "https://deckofcardsapi.com/static/img/0D.png"
},
"value": "10",
"suit": "DIAMONDS"
},
{
"code": "5S",
"image": "https://deckofcardsapi.com/static/img/5S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/5S.svg",
"png": "https://deckofcardsapi.com/static/img/5S.png"
},
"value": "5",
"suit": "SPADES"
},
{
"code": "AC",
"image": "https://deckofcardsapi.com/static/img/AC.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/AC.svg",
"png": "https://deckofcardsapi.com/static/img/AC.png"
},
"value": "ACE",
"suit": "CLUBS"
},
{
"code": "9H",
"image": "https://deckofcardsapi.com/static/img/9H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/9H.svg",
"png": "https://deckofcardsapi.com/static/img/9H.png"
},
"value": "9",
"suit": "HEARTS"
},
{
"code": "2C",
"image": "https://deckofcardsapi.com/static/img/2C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/2C.svg",
"png": "https://deckofcardsapi.com/static/img/2C.png"
},
"value": "2",
"suit": "CLUBS"
},
{
"code": "0H",
"image": "https://deckofcardsapi.com/static/img/0H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/0H.svg",
"png": "https://deckofcardsapi.com/static/img/0H.png"
},
"value": "10",
"suit": "HEARTS"
},
{
"code": "9C",
"image": "https://deckofcardsapi.com/static/img/9C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/9C.svg",
"png": "https://deckofcardsapi.com/static/img/9C.png"
},
"value": "9",
"suit": "CLUBS"
},
{
"code": "8D",
"image": "https://deckofcardsapi.com/static/img/8D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/8D.svg",
"png": "https://deckofcardsapi.com/static/img/8D.png"
},
"value": "8",
"suit": "DIAMONDS"
},
{
"code": "6D",
"image": "https://deckofcardsapi.com/static/img/6D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/6D.svg",
"png": "https://deckofcardsapi.com/static/img/6D.png"
},
"value": "6",
"suit": "DIAMONDS"
},
{
"code": "KS",
"image": "https://deckofcardsapi.com/static/img/KS.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/KS.svg",
"png": "https://deckofcardsapi.com/static/img/KS.png"
},
"value": "KING",
"suit": "SPADES"
},
{
"code": "QC",
"image": "https://deckofcardsapi.com/static/img/QC.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/QC.svg",
"png": "https://deckofcardsapi.com/static/img/QC.png"
},
"value": "QUEEN",
"suit": "CLUBS"
},
{
"code": "KC",
"image": "https://deckofcardsapi.com/static/img/KC.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/KC.svg",
"png": "https://deckofcardsapi.com/static/img/KC.png"
},
"value": "KING",
"suit": "CLUBS"
},
{
"code": "5H",
"image": "https://deckofcardsapi.com/static/img/5H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/5H.svg",
"png": "https://deckofcardsapi.com/static/img/5H.png"
},
"value": "5",
"suit": "HEARTS"
},
{
"code": "2S",
"image": "https://deckofcardsapi.com/static/img/2S.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/2S.svg",
"png": "https://deckofcardsapi.com/static/img/2S.png"
},
"value": "2",
"suit": "SPADES"
},
{
"code": "JS",
"image": "https://deckofcardsapi.com/static/img/JS.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/JS.svg",
"png": "https://deckofcardsapi.com/static/img/JS.png"
},
"value": "JACK",
"suit": "SPADES"
},
{
"code": "QD",
"image": "https://deckofcardsapi.com/static/img/QD.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/QD.svg",
"png": "https://deckofcardsapi.com/static/img/QD.png"
},
"value": "QUEEN",
"suit": "DIAMONDS"
},
{
"code": "2H",
"image": "https://deckofcardsapi.com/static/img/2H.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/2H.svg",
"png": "https://deckofcardsapi.com/static/img/2H.png"
},
"value": "2",
"suit": "HEARTS"
},
{
"code": "7D",
"image": "https://deckofcardsapi.com/static/img/7D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/7D.svg",
"png": "https://deckofcardsapi.com/static/img/7D.png"
},
"value": "7",
"suit": "DIAMONDS"
},
{
"code": "AD",
"image": "https://deckofcardsapi.com/static/img/aceDiamonds.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/aceDiamonds.svg",
"png": "https://deckofcardsapi.com/static/img/aceDiamonds.png"
},
"value": "ACE",
"suit": "DIAMONDS"
},
{
"code": "2D",
"image": "https://deckofcardsapi.com/static/img/2D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/2D.svg",
"png": "https://deckofcardsapi.com/static/img/2D.png"
},
"value": "2",
"suit": "DIAMONDS"
},
{
"code": "0C",
"image": "https://deckofcardsapi.com/static/img/0C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/0C.svg",
"png": "https://deckofcardsapi.com/static/img/0C.png"
},
"value": "10",
"suit": "CLUBS"
},
{
"code": "AH",
"image": "https://deckofcardsapi.com/static/img/AH.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/AH.svg",
"png": "https://deckofcardsapi.com/static/img/AH.png"
},
"value": "ACE",
"suit": "HEARTS"
},
{
"code": "9D",
"image": "https://deckofcardsapi.com/static/img/9D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/9D.svg",
"png": "https://deckofcardsapi.com/static/img/9D.png"
},
"value": "9",
"suit": "DIAMONDS"
},
{
"code": "5C",
"image": "https://deckofcardsapi.com/static/img/5C.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/5C.svg",
"png": "https://deckofcardsapi.com/static/img/5C.png"
},
"value": "5",
"suit": "CLUBS"
},
{
"code": "QS",
"image": "https://deckofcardsapi.com/static/img/QS.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/QS.svg",
"png": "https://deckofcardsapi.com/static/img/QS.png"
},
"value": "QUEEN",
"suit": "SPADES"
},
{
"code": "5D",
"image": "https://deckofcardsapi.com/static/img/5D.png",
"images": {
"svg": "https://deckofcardsapi.com/static/img/5D.svg",
"png": "https://deckofcardsapi.com/static/img/5D.png"
},
"value": "5",
"suit": "DIAMONDS"
}
],
"remaining": 0
}
}