Reputation: 93
This is a 2 part question, I am making a blackjack game and I am trying to randomly generate a key and value (KEY = string(card value e.g. Hearts2), And VALUE = int (Score for that specific card value)), and I would like to try and return the key and value.
I have a deck, dealer and player class. My Deck class has 2 methods, Deck() and Shuffel(), deck() is used to create the deck and shuffle90 well shuffles the deck(). I would like to send the random card to the dealer class to deal the cards. I am not sure if it is possible to return the key and value so the dealer class method (dealCards()) can receive a string and int as parameters.
Also I found a way to randomize my dictionary but it is returning the entire dictionary randomized, but I only need one card to be returned.
This is what I have so far for the Deck class...
This is my
public static Dictionary<string, int> deck()
{
string[] Suite = new string[4] { "Spades", "Clubs", "Hearts", "Diamonds" };
string[] FaceValue = new string[13] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
int score;
Dictionary<string, int> deckOfCards = new Dictionary<string, int>();
for (int s = 0; s < 4; s++)
{
string sute = Suite[s];
for (int f = 0; f < 13; f++)
{
string fV = FaceValue[f];
if (f == 0)
{
score = 0;
}
else if (f >= 9)
{
score = 10;
}
else
{
score = (f + 1);
}
string card = (sute + fV);
deckOfCards.Add(card, score);
}
}
Dictionary<string, int> ranCard = deckOfCards.Shuffle();
return ranCard;
}
As you can see I created 2 simple arrays and used for loops to iterate through them and add them to the dictionary.
The last two lines, the first is declaring a new dictionary to hold the random card and reciving its value from the Shuffle()
method,(is posted bellow) and I would like to know if there is a way to return ranCard.Key, ranCard.Value
? so I can have my Dealer class method like this (dealCard(string card, int score)
)?
This is my Shuffle()
method for my Deck
class...
public static Dictionary<TKey, TValue> Shuffle<TKey, TValue>(this Dictionary<TKey, TValue> Cards)
{
Random r = new Random();
Cards = Cards.OrderBy(x => r.Next(0, Cards.Count)).ToDictionary(item => item.Key, item => item.Value);
return Cards;
}
Now with this method The entire dictionary is randomized and I would like to just return one randome value if possible. I tried to remove the parameters in the r.Next(**) but still the same.
I am using vs2012.
Upvotes: 1
Views: 1147
Reputation: 11607
First things first.
The game rules require that you have state. What I mean is that you don't have a stateless random return value, but you MUST retain the state across the generation of random values, as the probabilities change. In layman's terms: you can't draw the same card more than n times because the game rules specify how the deck is composed.
That said, it is clear that one way or another you have to keep track of the cards in the deck. In your code you shuffle the whole deck and return that. All you need now is an object that wraps it and keeps internally its state, like so:
class Dealer
{
private List<Card> shuffledCards; // keep state of the current shuffle
public Dealer(...)
{
shuffledCards = Shuffle(...); // use your method to get the shuffled cards
}
public Card Deal() // remove the first card from the deck and hand it out
{
Card c;
c = shuffledCards[0];
shuffledCards.RemoveAt(0);
return c;
}
}
There are many more ways to implement this, at least another 2 come to my mind, but the result is just the same.
Upvotes: 1
Reputation: 1503290
There are several issues here:
OrderBy
may not be reflected when you iterate over the dictionary later. I believe in the current implementation it may happen to do that, but fundamentally you shouldn't rely on it.Basically, a deck of cards isn't a dictionary - it's a sequence of cards. So you should be modelling a card:
public sealed class Card
{
// Fields for face value and suit, and a property to compute the score
}
How you choose to represent the face value and suit are up to you, but you should consider using enums given that there are natural sets of valid values here.
Once you've got a deck as a List<Card>
(or a Queue<Card>
), you can easily shuffle that, and then just deal Card
values to players.
Upvotes: 1