How to best initialize a more then one card of Deck

T

Tony Johansson

Hello!

Here is some code that initialize one card of Deck A card of Deck have 52
cards.
Now to my question I also want to be able to initialize any number of decks
in a collection
For example when this method InitDeck is called the array collection cards
have already been allocated to the right size.
So the comment is there now but I just wonder if there is possible to write
some nice code that initialize for example 3
card of deck which mean that this cards array can store three decks of card

private void InitDeck()
{
int currentCard;

cards[0] = new Card(0, 0); //index on position 0 is not used

// for (int deck = 1; deck <= cards.Length/52; deck++)
// {
for (int suit = (int)CardSuit.Club; suit <= (int)CardSuit.Spade;
suit++)
{
for (int rank = (int)CardValue.Ace; rank <=
(int)CardValue.King; rank++)
{
currentCard = (rank + (suit - 1) * 13) * deck;
cards[currentCard] = new Card((CardSuit)suit,
(CardValue)rank);
}
}
// }
}

//Tony
 
A

Arne Vajhøj

Here is some code that initialize one card of Deck A card of Deck have 52
cards.
Now to my question I also want to be able to initialize any number of decks
in a collection
For example when this method InitDeck is called the array collection cards
have already been allocated to the right size.
So the comment is there now but I just wonder if there is possible to write
some nice code that initialize for example 3
card of deck which mean that this cards array can store three decks of card

private void InitDeck()
{
int currentCard;

cards[0] = new Card(0, 0); //index on position 0 is not used

// for (int deck = 1; deck<= cards.Length/52; deck++)
// {
for (int suit = (int)CardSuit.Club; suit<= (int)CardSuit.Spade;
suit++)
{
for (int rank = (int)CardValue.Ace; rank<=
(int)CardValue.King; rank++)
{
currentCard = (rank + (suit - 1) * 13) * deck;
cards[currentCard] = new Card((CardSuit)suit,
(CardValue)rank);
}
}
// }
}

Assuming that the class is named Deck.

You could make Deck support multipla of 52 cards by doing something
like:

public Deck() : this(1)
{
}

public Deck(int n)
{
cards = new Card[n*52];
}

Or if you are on 4.0/2010 you could use the new default value
possibility.

An unrelated note: I would just name the method Init.

Arne
 
T

Tony Johansson

Arne Vajhøj said:
Here is some code that initialize one card of Deck A card of Deck have 52
cards.
Now to my question I also want to be able to initialize any number of
decks
in a collection
For example when this method InitDeck is called the array collection
cards
have already been allocated to the right size.
So the comment is there now but I just wonder if there is possible to
write
some nice code that initialize for example 3
card of deck which mean that this cards array can store three decks of
card

private void InitDeck()
{
int currentCard;

cards[0] = new Card(0, 0); //index on position 0 is not used

// for (int deck = 1; deck<= cards.Length/52; deck++)
// {
for (int suit = (int)CardSuit.Club; suit<=
(int)CardSuit.Spade;
suit++)
{
for (int rank = (int)CardValue.Ace; rank<=
(int)CardValue.King; rank++)
{
currentCard = (rank + (suit - 1) * 13) * deck;
cards[currentCard] = new Card((CardSuit)suit,
(CardValue)rank);
}
}
// }
}

Assuming that the class is named Deck.

You could make Deck support multipla of 52 cards by doing something
like:

public Deck() : this(1)
{
}

public Deck(int n)
{
cards = new Card[n*52];
}

Or if you are on 4.0/2010 you could use the new default value
possibility.

An unrelated note: I would just name the method Init.

Arne

I use this cards = new Card[n*52];
to allocate the correct size but my question is how can I rewrite the method
InitDeck that is listed above so all the cards are stored in the collection
array

//Tony
 
A

Arne Vajhøj

Arne Vajhøj said:
Here is some code that initialize one card of Deck A card of Deck have 52
cards.
Now to my question I also want to be able to initialize any number of
decks
in a collection
For example when this method InitDeck is called the array collection
cards
have already been allocated to the right size.
So the comment is there now but I just wonder if there is possible to
write
some nice code that initialize for example 3
card of deck which mean that this cards array can store three decks of
card

private void InitDeck()
{
int currentCard;

cards[0] = new Card(0, 0); //index on position 0 is not used

// for (int deck = 1; deck<= cards.Length/52; deck++)
// {
for (int suit = (int)CardSuit.Club; suit<=
(int)CardSuit.Spade;
suit++)
{
for (int rank = (int)CardValue.Ace; rank<=
(int)CardValue.King; rank++)
{
currentCard = (rank + (suit - 1) * 13) * deck;
cards[currentCard] = new Card((CardSuit)suit,
(CardValue)rank);
}
}
// }
}

Assuming that the class is named Deck.

You could make Deck support multipla of 52 cards by doing something
like:

public Deck() : this(1)
{
}

public Deck(int n)
{
cards = new Card[n*52];
}

Or if you are on 4.0/2010 you could use the new default value
possibility.

An unrelated note: I would just name the method Init.

Arne

I use this cards = new Card[n*52];
to allocate the correct size but my question is how can I rewrite the method
InitDeck that is listed above so all the cards are stored in the collection
array

I thought they did.

Hm.

Maybe:

currentCard = rank + (suit - 1) * 13 + (deck - 1) * 52;

Arne
 
T

Tony Johansson

Peter Duniho said:
Hello!

Here is some code that initialize one card of Deck A card of Deck have 52
cards.
Now to my question I also want to be able to initialize any number of
decks
in a collection
For example when this method InitDeck is called the array collection
cards
have already been allocated to the right size.
So the comment is there now but I just wonder if there is possible to
write
some nice code that initialize for example 3
card of deck which mean that this cards array can store three decks of
card

Yes, it is possible to write the code _much_ more nicely than what you've
posted, and for it to work as well (though, Arne's suggestion should
address the basic logic error in your original code).

First: the "index on position 0 is not used" is ridiculous. If it's not
used, why are you allocating a Card instance to store in it? And why not
use it? Zero-based arrays are a fundamental feature of C#; it's silly to
not base your index values on 0, because if you don't, you just wind up
having to add or subtract 1 everywhere when using indexes.

Second: casting your (apparently?) enum values to ints and then iterating
that way is silly and fragile. What if Club winds up not being the first
value, or Spade winds up not being the last? Why should the enum values
have to have anything at all to do with the array index being computed?
What if for whatever reason it turns out you need your enum values to be
something other than a sequential index? Why should your code have to
assume any underlying value for the enum at all?

Third: what's with all the computation for the index into the array of
Cards? In theory, you're just going to be iterating through the array
sequentially, so you might as well just maintain an index and increment it
with each new card.

Here's a version of the code that IMHO is much better:

enum CardSuit { Club, Diamond, Heart, Spade }

enum CardRank
{
Ace, One, Two, Three, Four, Five, Six, Seven,
Eight, Nine, Ten, Jack, Queen, King
}

// One deck is always 52 cards; a shoe may have more than one deck
static void InitShoe(Card[] cards)
{
if (cards.Length % 52 != 0)
{
throw new ArgumentException("cards array must have a multiple of 52
elements");
}

int icard = 0;

while (icard < cards.Length)
{
foreach (CardSuit suit in Enum.GetValues(typeof(CardSuit)))
{
foreach (CardRank rank in Enum.GetValues(typeof(CardRank)))
{
cards[icard++] = new Card(suit, rank);
}
}
}
}

Hope that helps.

Pete

Really nice solution Pete!!

//Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top