Episode 5 of the Coder's Block podcast out now

In this 4th installment of my coding challenge I will be building a deck of cards, that can hopefully be used for future projects or future games, such as Blackjack. It's a super quick project, and I don't think I'll run into any issues. But we'll see. I'm giving myself 1 hour to finish this up. I'm going to try to add as many card related functions as I can, such as shuffling a deck, grabbing a card from the top or bottom and grabbing a new deck.

Deck of Cards

Name: Deck of cards
Language: JavaScript
Estimated Completion: 1 hour

Overview

A deck of traditional cards is composed of 4 sets of 13 sequential numbered cards. A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, and K. Each card in the set belongs to a particular suit: Hearts, Spades, Clubs and Diamonds. Sounds simple enough. I'll be using JavaScript as I mentioned, and my deck will consist of an Array of objects with a function to render each card.

Let's Start

This is where the fun begins. I'm going to start with declaring my variables, which gives me an idea of how I'm going to build the entire thing.


var deck = new Array();
var suits = ["spades", "diamonds", "clubs", "hearts"];
var values = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];

Create The Deck


function getDeck()
{
	var deck = new Array();

	for(var i = 0; i < suits.length; i++)
	{
		for(var x = 0; x < values.length; x++)
		{
			var card = {Value: values[x], Suit: suits[i]};
			deck.push(card);
		}
	}

	return deck;
}

Pretty simple function that returns a sequential deck of cards.

Shuffle Time

Next up I need a function to shuffle up the deck. For this, I'm going to pick 2 random locations on the deck, and then switch their values. I'm going to do this about 1000 times per shuffle, which is way more than I could do manually, so it should be good.


function shuffle()
{
	// for 1000 turns
	// switch the values of two random cards
	for (var i = 0; i < 1000; i++)
	{
		var location1 = Math.floor((Math.random() * deck.length));
		var location2 = Math.floor((Math.random() * deck.length));
		var tmp = deck[location1];

		deck[location1] = deck[location2];
		deck[location2] = tmp;
	}
}

At this point, my deck array should contain 52 objects in a random order. But it's funner to see it than to hear me talk about it, so my next trick, I'm going to make the cards appear.


function renderDeck()
{
	for(var i = 0; i < deck.length; i++)
	{
		var card = document.createElement("div");
		var value = document.createElement("div");
		var suit = document.createElement("div");
		card.className = "card";
		value.className = "value";
		suit.className = "suit " + deck[i].Suit;

		value.innerHTML = deck[i].Value;
		card.appendChild(value);
		card.appendChild(suit);

		document.getElementById("deck").appendChild(card);
	}
}

I gave each card a child with the className of its corresponding suit. And used the following sprite to grab the icons from.

So at this point, I have the functions to create a new deck of cards, shuffle them, and draw them out onto the screen. And that actually took less time than I had anticipated. It looks something like the following.

Version 2: Rendering

A cleaner way render the cards (at least to me) is a method that I used in my blackjack game, in which I use HTML entities instead of images.


    function getCardUI(card)
        {
            var el = document.createElement('div');
            var icon = '';
            if (card.Suit == 'Hearts')
            icon='♥';
            else if (card.Suit == 'Spades')
            icon = '♠';
            else if (card.Suit == 'Diamonds')
            icon = '♦';
            else
            icon = '♣';
            
            el.className = 'card2';
            el.innerHTML = card.Value + '
' + icon; return el; }
View full source

<html>
<head>
<style>
.card
{
	border: solid 1px #aaa;
	border-radius: 9px;
	width: 95px;
	height: 150px;
	float:left;
	background-color: white;
	padding: 3px 3px 3px 3px;
}

.card .value{
	font-size:15pt;
	font-family: sans-serif;
}

.card .suit
{
	background-image: url('suits.png');
	height: 100px;
	width: 90px;
}

.card .diamonds
{
	background-position-y: 100px;
}

.card .hearts
{
	background-position-x: 90px;
}

.card .clubs
{
	background-position-x:90px;
	background-position-y:100px;
}
</style>

<script type="text/javascript">
var cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"];
var suits = ["diamonds", "hearts", "spades", "clubs"];
var deck = new Array();

function getDeck()
{
	var deck = new Array();

	for(var i = 0; i < suits.length; i++)
	{
		for(var x = 0; x < cards.length; x++)
		{
			var card = {Value: cards[x], Suit: suits[i]};
			deck.push(card);
		}
	}

	return deck;
}

function deal()
{
	// remove top card from deck
	var card = deck[deck.length-1];
	deck.splice(deck.length-1, 1);
	return card;
}

function shuffle()
{
	// for 1000 turns
	// switch the values of two random cards
	for (var i = 0; i < 1000; i++)
	{
		var location1 = Math.floor((Math.random() * deck.length));
		var location2 = Math.floor((Math.random() * deck.length));
		var tmp = deck[location1];

		deck[location1] = deck[location2];
		deck[location2] = tmp;
	}
}

function renderDeck()
{
	for(var i = 0; i < deck.length; i++)
	{
		var card = document.createElement("div");
		var value = document.createElement("div");
		var suit = document.createElement("div");
		card.className = "card";
		value.className = "value";
		suit.className = "suit " + deck[i].Suit;

		value.innerHTML = deck[i].Value;
		card.appendChild(value);
		card.appendChild(suit);

		document.getElementById("deck").appendChild(card);
	}
}

function load()
{
	deck = getDeck();
	shuffle();
	renderDeck();
}

window.onload = load;
</script>
</head>

<body>
<h1>A Deck of Cards</h1>
<div id="deck"></div>

</body>
</html>

Comments (4)

M
Mads B√łtker Andersen
Thanks for this! It helped me get started on a small (potentially, big and fun) project! I Have run into a problem where the cards render twice.. which is weird.. :D
10/23/2017 11:24:00 AM
Walt
Many thanks! If you have any questions on it, feel free to shoot me a message and I'll gladly help out!
10/23/2017 8:45:11 PM
k
kaye
what do I do if I need 4 decks?
1/22/2018 11:18:01 AM
Walt
Hey there Kaye!

You can definitely do it without too much extra effort. The getDeck() function returns a whole deck, so essentially you can keep calling it for as many decks as you may need.


var deck1 = getDeck();
var deck2 = getDeck();

And if you are going to do that, then you should definitely pass in the 'deck' object that you are targeting to the shuffle() and to the render methods().

The code will be updated to reflect that to give better clarity!

1/24/2018 11:58:23 PM

Add a comment

Add comment
"sometimes you have to delete, to find your answer"
Copyright © 2018 thatsoftwaredude.com
humans.txt
TOP SCORES
Score in the top 10 and leave your Instagram handle.
Start
0
snake left
snake up
snake down
snake right