-3

I am a novice coder learning C# for my class and am having trouble with a practice exercise where we have to make a deck of cards and deal them out.

We need to make a class that creates cards by receiving parameters from another class through a constructor. Then use those values in a Tostring method to set the value and suit of those cards with switch statements and return a card. In the second class we populate an array with cards and call the Tostring method in a Dealing method to randomly generate a user specified amount of cards by pulling them out of the array.

The problem is my array isn't being populated I have tried to Console.WriteLine parts of the array directly after they would be assigned and they are empty. You don't have to give me the full answer put just put me on the right track.

Here is the code:

This is the card creation class

 `  class Card
{

    static int value; 
    static int suit;
    static string cdvalue;
    static string cdsuit;

    string card;

    public Card(int ranvalue, int ransuit) //constructor that sets value and suit
    {
        value = ranvalue;
        suit = ransuit;
    }
    public override string ToString()
    {
        switch (value) //switch statement for card value
        {
            case 1: cdvalue = "ace";
                break;
            case 2: cdvalue = "two";
                break;
            case 3: cdvalue = "three";
                break;
            case 4: cdvalue = "four";
                break;
            case 5: cdvalue = "five";
                break;
            case 6: cdvalue = "six";
                break;
            case 7: cdvalue = "seven";
                break;
            case 8: cdvalue = "eight";
                break;
            case 9: cdvalue = "nine";
                break;
            case 10: cdvalue = "ten";
                break;
            case 11: cdvalue = "jack";
                break;
            case 12: cdvalue = "queen";
                break;
            case 13: cdvalue = "king";
                break;
        }
        switch (suit) // switch for card suit
        {
            case 1: cdsuit = "Hearts ";
                break;
            case 2: cdsuit = "Spades ";
                break;
            case 3: cdsuit = "Diamonds ";
                break;
            case 4: cdsuit = "Clubs ";
                break;
        }
        card = cdvalue + " of " + cdsuit;

        return card;// returns a string in the form of "value of suit"`

This class creates the deck

class Deck
{
    Random rng = new Random(); //Random object



    private static Card[] deck;
    static string[] cards; 
    public Deck()
    {
        deck = new Card[52];//creates array of 52 elements
        int l = 0;
        for (int i = 1; i <= 13; i++)//loops to create cards 
        {
            for (int j = 1; j <= 4; j++)
            {

                deck[l++] = new Card(i,j); // populates the array with all 52 cards



            }
        }

    }
    static string dealt;
    static int Rndm;
    public string deal(int number)//parameter received from user
    {
        cards = new string[number];//creates an array to contain dealt card objects
        int m = 0;

        for (int num=0;num<number;num++) // determines the amount of cards to be dealt
        {

            Rndm = rng.Next(0,53);
            cards[m++] = deck[Rndm].ToString();//fills the card array with randomly dealt cards from the deck
            dealt = string.Join(" ", cards); // turns the card array into a single string of the cards dealt



        }
        return dealt;//returns the cards dealt

This is the test class

  static void Main(string[] args)
    {

        // get the number of cards from the user - must be between 1 and 52
        int cardsDealt = -1;
        do
        {
            Console.Write("Enter number of cards to get (1-52): ");
            String dealStr = Console.ReadLine();
            Boolean parsed = int.TryParse(dealStr, out cardsDealt);
        } while (cardsDealt < 1 || cardsDealt > 52);

        // create a Deck object
        Deck cardDeck = new Deck();

        // Call the deal method
        String cards = cardDeck.deal(cardsDealt);

        // List the result
        Console.WriteLine("\nCards dealt:\n" + cards);
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92

2 Answers2

1

In your Card class you have the variables value and suit marked as static.

private static int value;
private static int suit;

Because these two variables are static, the reference to these variables will be maintained across instances of the Card objects. What this means is that every time you create a new Card object you are inadvertently updating all the other Card objects value and suit variables with the same value. So now whenever you get an instance of a Card it will be the same card as all other instances (the last Card that was created).

Remove the static keyword from these declarations and you should be ok.

Also I would suggest reading up on static to more familiarize yourself with its usage: Static keyword in c#

Community
  • 1
  • 1
Darren H
  • 450
  • 3
  • 5
0

Your code is very close to being correct. You seem to have a misunderstanding of when to use static or not.

If you need a variable that is shared amongst all instances of a class, then use static. But if you need per instance values, then don't.

There are no variables in your code that should be static.

Also, just to help you with your code, you don't need to define all of your variables at the class-level. A lot can (and should) be declared within each method.

Here's the refactored version of your code so that you can see what should be done.

void Main()
{
    // get the number of cards from the user - must be between 1 and 52
    int cardsDealt = -1;
    while (cardsDealt < 1 || cardsDealt > 52)
    {
        Console.Write("Enter number of cards to get (1-52): ");
        String dealStr = Console.ReadLine();
        Boolean parsed = int.TryParse(dealStr, out cardsDealt);
    }

    // create a Deck object
    Deck cardDeck = new Deck();

    // Call the deal method
    String cards = cardDeck.deal(cardsDealt);

    // List the result
    Console.WriteLine("\nCards dealt:\n" + cards);
}

public class Card
{
    private int value;
    private int suit;

    public Card(int ranvalue, int ransuit) //constructor that sets value and suit
    {
        value = ranvalue;
        suit = ransuit;
    }
    public override string ToString()
    {
        string cdvalue = null;
        switch (value) //switch statement for card value
        {
            case 1:
                cdvalue = "ace";
                break;
            case 2:
                cdvalue = "two";
                break;
            case 3:
                cdvalue = "three";
                break;
            case 4:
                cdvalue = "four";
                break;
            case 5:
                cdvalue = "five";
                break;
            case 6:
                cdvalue = "six";
                break;
            case 7:
                cdvalue = "seven";
                break;
            case 8:
                cdvalue = "eight";
                break;
            case 9:
                cdvalue = "nine";
                break;
            case 10:
                cdvalue = "ten";
                break;
            case 11:
                cdvalue = "jack";
                break;
            case 12:
                cdvalue = "queen";
                break;
            case 13:
                cdvalue = "king";
                break;
        }
        string cdsuit = null;
        switch (suit) // switch for card suit
        {
            case 1:
                cdsuit = "Hearts ";
                break;
            case 2:
                cdsuit = "Spades ";
                break;
            case 3:
                cdsuit = "Diamonds ";
                break;
            case 4:
                cdsuit = "Clubs ";
                break;
        }
        string card = cdvalue + " of " + cdsuit;
        return card;// returns a string in the form of "value of suit"`
    }
}

public class Deck
{
    private Random rng = new Random(); //Random object
    private Card[] deck;

    public Deck()
    {
        deck = new Card[52];//creates array of 52 elements
        int l = 0;
        for (int i = 1; i <= 13; i++)//loops to create cards 
        {
            for (int j = 1; j <= 4; j++)
            {
                deck[l++] = new Card(i, j); // populates the array with all 52 cards
            }
        }
    }

    public string deal(int number)//parameter received from user
    {
        string[] cards = new string[number];//creates an array to contain dealt card objects
        for (int num = 0; num < number; num++) // determines the amount of cards to be dealt
        {
            int Rndm = rng.Next(deck.Length);
            cards[num] = deck[Rndm].ToString();//fills the card array with randomly dealt cards from the deck
        }
        string dealt = string.Join(" ", cards); // turns the card array into a single string of the cards dealt
        return dealt;//returns the cards dealt
    }
}

The only other concern with this is that your dealing code produces duplicate cards. You may need to do something about that.


If I were coding this, this is how I would do it:

public class Card
{
    private int value;
    private int suit;
    public Card(int ranvalue, int ransuit)
    {
        value = ranvalue;
        suit = ransuit;
    }
    public override string ToString()
    {
        var values = new []
        {
            "ace", "two", "three", "four", "five", "six", "seven",
            "eight", "nine", "ten", "jack", "queen", "king"
        };
        var suits = new []
        {
            "Hearts", "Spades", "Diamonds", "Clubs"
        };
        return String.Format("{0} of {1}", values[value - 1], suits[suit - 1]);
    }
}

public class Deck
{
    private Random rng = new Random();
    private Card[] deck;

    public Deck()
    {
        deck =
        (
            from value in Enumerable.Range(1, 13)
            from suit in Enumerable.Range(1, 4)
            select new Card(value, suit)
        ).ToArray();
    }

    public string deal(int number)
    {
        string dealt = string.Join(" ", deck.OrderBy(x => rng.Next()).Take(number));
        return dealt;
    }
}

This fixes the duplicate card issue.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172