So this is something I have seen a number of times on StackOverflow, so I thought I would spend some time while I was on a ferry creating a solution for. So what we have is a standard deck of cards, 52 cards (no jokers), 4 suits (Clubs, Diamonds, Hearts and Spades) each with 13 cards (ace through to king). In this post I will go through the code that has been produced and at the bottom of the post there is a download link for the entire solution, unit tests and all.

Deck of Cards

 
Source: http://www.leadersinstitute.com/wp-content/uploads/2011/02/playing-cards.jpg

 

Suit Enum

namespace Cards.Domain.Standard
{
    public enum Suit
    {
        Club = 1,
        Diamond = 2,
        Heart = 3,
        Spades = 4,
    }
}

Card Number Enum

I decided to use an enum for the card number as well as for the suit as rather than having numbers directly for the card number I could have an appropriate value, which could be given an Attribute to allow for further information to be associated with it.

namespace Cards.Domain.Standard
{
    public enum CardNumber
    {
        Ace = 1,
        Two = 2,
        Three = 3,
        Four = 4,
        Five = 5,
        Six = 6,
        Seven = 7,
        Eight = 8,
        Nine = 9,
        Ten = 10,
        Jack = 11,
        Queen = 12,
        King = 13,
    }
}

Card class

The card class is extremely simple, it is just two properties, one for the suit and one for the card number.

namespace Cards.Domain.Standard
{
    public class Card
    {
        public Suit Suit { get; set; }
        public CardNumber CardNumber { get; set; }
    }
}

Deck class

The Deck class is where most of the interesting stuff happens.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Cards.Domain.Standard
{
    public class Deck
    {
        public Deck()
        {
            Reset();
        }

        public List<Card> Cards { get; set; }

        public void Reset()
        {
            Cards = Enumerable.Range(1, 4)
                .SelectMany(s => Enumerable.Range(1, 13)
                                    .Select(c => new Card()
                                    {
                                        Suit = (Suit)s,
                                        CardNumber = (CardNumber)c
                                    }
                                            )
                            )
                   .ToList();
        }

        public void Shuffle()
        {
            Cards = Cards.OrderBy(c => Guid.NewGuid())
                         .ToList();
        }

        public Card TakeCard()
        {
            var card = Cards.FirstOrDefault();
            Cards.Remove(card);

            return card;
        }

        public IEnumerable<Card> TakeCards(int numberOfCards)
        {
            var cards = Cards.Take(numberOfCards);

            var takeCards = cards as Card[] ?? cards.ToArray();
            Cards.RemoveAll(takeCards.Contains);

            return takeCards;
        }
    }
}

Reset

This method uses a nice piece of LINQ to generate all the required cards for the standard 52 card deck and populate the Cards property of the deck. This method is called by the constructor to set up the Deck class.

Shuffle

When the cards are generated they are created in an ordered fashion, this method orders all the cards randomly again using LINQ.

TakeCard

This method as the name suggests takes a card from the Deck. It will get the next Card in the Deck and return it, removing it from the Cards collection so it can’t be taken again. If there are no more Cards in the Deck then this method will return a null.

TakeCards

This method is like TakeCard although it allows for the user to take more than one Card. I made a design decision to return the requested amount or the remainder of the Cards in the Deck, so if the user asks for five Cards but there are only three left, then it will return those three, although some might say that as we are not able to correctly fulfil the request we should be throw an exception.

Deck of Cards usage

The deck of cards code can be used to implement your own card game software, a solitaire, poker game etc. the code it pretty simple and well defined so shouldn’t require much in the way of adjustments for any standard 52 card deck game. If you want to add Jokers then that will require a little more work but nothing too major (I’m just not too sure about their usage in games so I thought I would leave them out).

Anyway the solution that I produced for the deck of cards is available for download here (Deck of Cards in C#)

Deck of Cards in C#
Tagged on:

4 thoughts on “Deck of Cards in C#

  • 25 February 2014 at 11:32 pm
    Permalink

    So what should I write in an external form to click on a button and see the result in a label?

    Reply
  • 20 May 2014 at 11:36 pm
    Permalink

    I’m only a novice but it seems to me that a TakeCard() and a TakeCards() would only serve to create a potential maintainability issue (albeit a small chance that there would be a reason to change either) because they both do essentially the same thing but with their own implementations. Shouldn’t TakeCard() either call TakeCards(1) ….or TakeCards(int x) call TakeCard() x number of times. Perhaps I’m over analyzing.

    The Guid structure and NewGuid method are new to me and I find the use of them to create a Shuffling function to be brilliant. Thanks tremendously for this post.

    Reply
  • 10 August 2014 at 3:06 am
    Permalink

    You are a genius. So simple and elegant, why can’t I write something like this?!?!. one day….. one day

    Reply
  • 16 May 2015 at 2:16 am
    Permalink

    Good work with those LINQ uses.

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.