user2359626
user2359626

Reputation: 63

Trying to populate List w/ Enum but getting 'type' is used like a 'variable'

I'm creating a deck of cards and have my Suits and Values in Enums but my syntax is off in trying to populate my List deck. Also as an aside, the Ace can have a value of 1 or 11, is there some way to incorporate that into my Enum or do I need to just code that in when performing things such as summing a hand for blackjack?

public class Deck
{
    private List<Card> cards;
    private Random random = new Random();
    public Deck()
    {
        cards = new List<Card>();
        for (int s = 0; s < 4; s++)
            //for (int v = 0; v < 14; v++)
            foreach(Enum v in Values)
                cards.Add(new Card((Suits)s, (Values)v));
    }

And here is my Enums for Suit and Value:

public enum Suits
{
    Spades,
    Clubs,
    Diamonds,
    Hearts
}

public enum Values
{
    Ace = 1,
    Two = 2,
    Three = 3,
    Four = 4,
    Five = 5,
    Six = 6,
    Seven = 7,
    Eight = 8,
    Nine = 9,
    Ten = 10,
    Jack = 10,
    Queen = 10,
    King = 10
}

Upvotes: 0

Views: 1563

Answers (2)

Matthew Watson
Matthew Watson

Reputation: 109567

You need to use Enum.GetValues() to get an array of all the values for an enum.

Then you should be able to do something like this (not sure if this will compile, but you should get the idea):

foreach (var suit in Enum.GetValues(typeof(Suits)))
{
    foreach (var value in Enum.GetValues(typeof(Values)))
    {
        cards.Add(new Card((Suits)suit, (Values)value));
    } 
}

I don't think your enum for values will work properly though. Once you have initialised something with one of the values between Ten to King, you will be unable to tell what it was originally.

I think you need something more like this (also rename your pluralised enum names to be singular, to match normal naming conventions):

public enum Suit
{
    Spades,
    Clubs,
    Diamonds,
    Hearts
}

public enum Rank
{
    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
}

class Card
{
    readonly Suit _suit;
    readonly Rank _rank;

    public Card(Suit suit, Rank rank)
    {
        _suit = suit;
        _rank = rank;
    }

    public Rank Rank
    {
        get
        {
            return _rank;
        }
    }

    public Suit Suit
    {
        get
        {
            return _suit;
        }
    }

    public int Value
    {
        get
        {
            if (Rank >= Rank.Ten)
            {
                return 10;
            }
            else
            {
                return (int) Rank;
            }
        }
    }

    public override string ToString()
    {
        return _rank + " of " + _suit + " with value " + Value;
    }
}

You could also use Linq to initialise your Card list as follows:

List<Card> cards = 
(
    from suit in Enum.GetValues(typeof(Suit)).OfType<Suit>()
    from rank in Enum.GetValues(typeof(Rank)).OfType<Rank>()
    select new Card(suit, rank)
).ToList();

If you want to keep the Value calculation more tightly associated with Rank rather than doing it in Card, you can write an extension method for Rank:

static class RankExt
{
    public static int Value(this Rank rank)
    {
        if (rank >= Rank.Ten)
        {
            return 10;
        }
        else
        {
            return (int)rank;
        }
    }
}

Then wherever you have a Rank you can use Rank.Value(), e.g. Card's ToString() would become:

public override string ToString()
{
    return _rank + " of " + _suit + " with value " + _rank.Value();
}

Upvotes: 1

Simon Whitehead
Simon Whitehead

Reputation: 65079

Your issue is this line:

foreach(Enum v in Values)

You cannot enumerate enum's in that way. Values is the name of your enum type declaration.. not a group of values.

You can do something like this though:

foreach (var v in Enum.GetValues(typeof(Values)))

Upvotes: 6

Related Questions