0

I am having this silly issue and I have no idea how to fix, im creating a blackjack game and I have a card class with a Deck() and Shuffle() methods, and a dealer class that will hand out the cards.

The shuffle method is an Extension method that I got on this site funny enough but I cant get it to receive the list of cards from the Deck() method...

I did originaly use a dictionary and had trouble shuffling the dictionary and asked for help on this site Here And they suggested using a list and now im here.

Here is the Card and Dealer Classes

Card.cs

public static class Card
{
    private static List<string> deckOfCards = new List<string>();


    private static string[] Suite = new string[4] {"Clubs", "Hearts", "Spades", "Diamonds" };
    private static string[] FaceValue = new string[13] {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };


    public static void Deck()
    {
        for (int s = 0; s < 4; s++ )
        {
            string sut = Suite[s];

            for (int fV = 0; fV < 13; fV++)
            {
                string value = FaceValue[fV];

                deckOfCards.Add(sut + value);
            }
        }
        // End of For loop.
        Shuffle(deckOfCards);
    }

    public static void Shuffle<T>(this IList<T> list)
    {
        Random rng = new Random();
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            T value = list[k];
            list[k] = list[n];
            list[n] = value;
        }
    }
}

Dealer.cs

class Dealer
{
    private List<string> randomisedCards = new List<string>();

    public Dealer()
    {
        randomisedCards.Shuffle();
    }


    public string dealCard()
    {
        string randCard = randomisedCards[0];
        randomisedCards.RemoveAt(0);

        return randCard;
    }
}

Criticism is highlight recommended as that's how you learn but please keep in mind that im still a beginner and have no experience at all.

Thanks

Community
  • 1
  • 1
Jody Stocks
  • 93
  • 1
  • 2
  • 15
  • I do not see any connection between `Dealer` and `Card` classes. – Giannis Paraskevopoulos Aug 29 '14 at 08:59
  • Your `Card` class does not represent a card, it represents a `Deck`, kinda. You'd probably want to reorganize your classes more logically and use enums instead of `string[]` for the suites and card values. That aside, [CodeReview](http://codereview.stackexchange.com/) is the proper forum. – SimpleVar Aug 29 '14 at 08:59
  • The card class had to be made static so I don't really understand how to make the connection. also this is a test project so all my bugs are being sorted out here and im bust learning enums at the moment and will be implementing them in the final project. – Jody Stocks Aug 29 '14 at 09:01
  • @Jody He means that `randomisedCards` is just a `new List()` and you're shuffling an empty list, not using any of the deck generation logic implemented in the `Deck` method. I'm sure that if you'll reorganize your classes more logically it will be clearer how the logic of the game goes within the code. – SimpleVar Aug 29 '14 at 09:02
  • Alright I see so now how do I fix the issue, could I return the Deck() method list randomized to the dealer class ? – Jody Stocks Aug 29 '14 at 09:04
  • And What do you mean by recognizing the logic of the classes ? Because in a blackjack game you have a dealer, player, and a deck of cards, I know it should have been deck.cs instead of card,cs – Jody Stocks Aug 29 '14 at 09:10

1 Answers1

2

I think it is a horrible idea to save the Deck as a static value in your class, I would recommend this:

public static class Cards
{
    private static string[] Suite = new string[4] {"Clubs", "Hearts", "Spades", "Diamonds" };
    private static string[] FaceValue = new string[13] {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };


    public static List<string> CreateDeck()
    {
        var deck = new List<string>();
        for (int s = 0; s < 4; s++ )
        {
            string sut = Suite[s];

            for (int fV = 0; fV < 13; fV++)
            {
                string value = FaceValue[fV];

                deck.Add(sut + value);
            }
        }
        // End of For loop.
        Shuffle(deck);
        return deck;
    }

    private static void Shuffle<T>(this IList<T> list)
    {
        Random rng = new Random();
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = rng.Next(n + 1);
            T value = list[k];
            list[k] = list[n];
            list[n] = value;
        }
    }
}

use it like this:

class Dealer
{
    private List<string> randomisedCards;

    public Dealer()
    {
        randomisedCards = Cards.CreateDeck();
    }


    public string dealCard()
    {
        string randCard = randomisedCards[0];
        randomisedCards.RemoveAt(0);

        return randCard;
    }
}

Please note that I did not check your code (CreateDeck, Shuffle, ...)

Also I would recommend making this cleaner by:

  • implementing a class for your Card (Suite, Face)
  • implementing a class for your Deck (collection of cards)
  • make everything immutable (on the outside - meaning: you can shuffle your cards as is, but don't let someone change your deck - create new ones instead for the interface - for example, drawing a card by the dealer should give you a card and another deck (lacking this card) - this improves the testability of your code
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • So I am very new to OOP... so shouldn't the Deck class inherit from the card class seeing as a card in from a deck ? Also im guessing that the shuffle method should move to the deck class and return the shuffled deck. What I dont really understand is point 3... I should deal a random card and then when I deal again, I must get another deck, with the cards removed that have been handed out ? If so I was going to do something similar where by adding the handed cards into a collection and if the random card is selected it must be compared with the collection. – Jody Stocks Aug 29 '14 at 09:28
  • Also how would testing be easier with a new deck every time ? – Jody Stocks Aug 29 '14 at 09:29
  • First question: No - the Deck class should just be a representation of a bunch of cards. / Shuffle: you could do it but you would have to change the logic as you do a destructive operation there(shuffle inplace) / why immutable data are easier to test: to big for a comment - just a few things: setup is obvious, no internal state that could hurt testing, no problems with parallel tests, no need for a special ordering of your tests, you can test properties like "the random card + the rest deck = the original deck (as sets)" easily (there are frameworks using those) – Random Dev Aug 29 '14 at 09:55
  • ... in short: make it functional :D – Random Dev Aug 29 '14 at 09:56