Reputation: 63
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
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
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