Reputation: 93
I wanted to know what the best way would be to create a deck of cards with a score or to calculate the score ? as you will see below I have a calculate class to deal with the cards score, to check what the card is and give it a value and to calculate the winner.
Im creating a blackjack game and I have gotten the cards to randomly generate but now in having trouble with the score for each card...
I am only going to show you the classes I have so far so you can get a sense of what im doing and where im at.
I know that this is a lot of code an is not ailing to people who will try and help but please try and bear with me...
Card class
public static class Card
{
// Should be enumes eg. Privat enume suite{}
private static string[] Suite = new string[4] {"Clubs", "Hearts", "Spades", "Diamonds" };
private static string[] FaceValue = new string[13] {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
public static List<string> CreateDeck()
{
List<string> deckOfCards = new List<string>();
for (int s = 0; s < 4; s++ )
{
string sut = Suite[s];
for (int fV = 0; fV < 13; fV++)
{
string value = FaceValue[fV];
deckOfCards.Add(sut + value);
}
}
// End of For loop.
deckOfCards.Shuffle();
return deckOfCards;
}
public static void Shuffle<T>(this IList<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
Dealer class(this is the center class per say as the dealer will get, shuffle and deal the cards out)
class Dealer
{
private List<string> randomisedCards;
public Dealer()
{
randomisedCards = Card.CreateDeck();
}
public string dealCard()
{
string randCard = randomisedCards[0];
randomisedCards.RemoveAt(0);
// Creating the object.
Calculate c = new Calculate(randCard);
return randCard;
}
}
Player class
class Player
{
// Member variables.
private int newPlayerScore;
private int newPlayerWin;
private int newPlayerLosses;
private int newPlayerTies;
// Defalut constructor used to set the member variables to their default values and will be used to reset
// the players details.
public Player()
{
newPlayerScore = 0;
newPlayerWin = 0;
newPlayerLosses = 0;
newPlayerTies = 0;
}
// Propertie used to get and set the players score.
public int calcPlayerScore
{
get
{
return newPlayerScore;
}
set
{
newPlayerScore = value;
}
}
public void getPlayerDetails()
{
Calculate c = new Calculate(newPlayerScore);
}
}
Calculate class(this is what I was using to calculate the winner and the score for each card, this is my issue as this is not the best way to do things)
class Calculate
{
Player p = new Player();
// Member variable.
private string newCard;
private int pScore;
private int dScore;
// Overloaded constructor.
public Calculate(string card)
{
newCard = card;
}
public Calculate(int playerScore)
{
pScore = playerScore;
}
public void calculateScore()
{
switch (newCard)
{
case "Spades2":
case "Hearts2":
case "Diamonds2":
case "Clubs2":
pScore = 2;
p.calcPlayerScore = pScore;
break;
case "Spades3":
case "Hearts3":
case "Diamonds3":
case "Clubs3":
pScore = 3;
p.calcPlayerScore = pScore;
break;
case "Spades4":
case "Hearts4":
case "Diamonds4":
case "Clubs4":
pScore = 4;
p.calcPlayerScore = pScore;
break;
case "Spades5":
case "Hearts5":
case "Diamonds5":
case "Clubs5":
pScore = 5;
p.calcPlayerScore = pScore;
break;
case "Spades6":
case "Hearts6":
case "Diamonds6":
case "Clubs6":
pScore = 6;
p.calcPlayerScore = pScore;
break;
case "Spades7":
case "Hearts7":
case "Diamonds7":
case "Clubs7":
pScore = 7;
p.calcPlayerScore = pScore;
break;
case "Spades8":
case "Hearts8":
case "Diamonds8":
case "Clubs8":
pScore = 8;
p.calcPlayerScore = pScore;
break;
case "Spades9":
case "Hearts9":
case "Diamonds9":
case "Clubs9":
pScore = 9;
p.calcPlayerScore = pScore;
break;
default:
pScore = 10;
p.calcPlayerScore = pScore;
break;
}
}
}
Thanks in advance.
Upvotes: 0
Views: 1919
Reputation: 41
Maybe its better to use integer values for the cards value so that you can use them directly for the scoring. Though for the ace you will have to define it as 1 or 11 in your scoring logic.
And then use the ToString() to display the value 1, 11, 12, 13 as Ace, jack, Queen, King
Card struct:
public struct Card
{
public int value;
public string suite;
public Card(int value, string suite)
{
this.value = value;
this.suite = suite;
}
public override string ToString()
{
switch (value)
{
case 1:
return "Ace of " + suite;
case 11:
return "Jack of " + suite;
case 12:
return "Queen of " + suite;
case 13:
return "King of " + suite;
default:
return value + " of " + suite;
}
}
}
also made a CardDeck class with indexer to access your cards like this:
var deck = new CardDeck();
var aCard = deck[0];
And IEnumerable<Card>
to use with a Foreach like this:
Foreach(Card card in Deck)
{
}
CardDeck class:
public class CardDeck : IEnumerable<Card>
{
private List<Card> _cards;
public Card this[int index] { get { return _cards[index]; } private set; }
public CardDeck()
{
string[] suits = new string[4] {"Clubs", "Hearts", "Spades", "Diamonds" };
int[] values = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
_cards = new List<Card>();
// Populate deck
for (int i = 0; i < values.Length; i++)
{
int value = values[i];
for (int x = 0; i < suits.Length; x++)
{
_cards.Add(new Card(value, suits[x]));
}
}
}
public void RemoveAt(int index)
{
_cards.RemoveAt(index);
}
public void Shuffle()
{
// shuffle based on http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Random rng = new Random();
int n = _cards.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
var value = _cards[k];
_cards[k] = _cards[n];
_cards[n] = value;
}
}
public IEnumerator<Card> GetEnumerator()
{
for (int index = 0; index < _cards.Count; index++)
{
yield return _cards[index];
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Upvotes: 0
Reputation: 45119
Don't work with simple strings. Put them into enums and create a immutable class Card
that will take three properties Suite
, Value
, Score
:
public enum Suite
{
Clubs,
Hearts,
Spades,
Diamonds
}
public enum Value
{
Ace,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight,
Nine,
Ten,
Jack,
Queen,
King
}
public class Card
{
public Card(Suite suite, Value value, decimal score)
{
Suite = suite;
Value = value;
Score = score;
}
public Suite Suite { get; private set; }
public Value Value { get; private set; }
public decimal Score { get; private set; }
}
With this stuff in hand you can create all desired cards with an individual score.
Maybe the score is even not a property of the Card itself, but only for the player that holds all cards. This can make sense if a score of a card can change depending on other cards the player is holding (e.g. the Ace in Black Jack can either be one or eleven, but if you have two of them than it is 21). So in that last case you should maybe create a static class specific for the game you like to play that is able to give you all the things you need:
public static class BlackJack
{
public static IEnumerable<Card> CreateNewDeck()
{
var suits = Enum.GetValues(typeof(Suite)).Cast<Suite>();
var values = Enum.GetValues(typeof(Value)).Cast<Value>();
// Create a new deck that contains all cards as often as needed.
var simpleDeck = suits.SelecMany(suit => values.Select(value => new Card(suit, value)));
// E.g. in one BlackJack deck you'll find all cards four times (IMHO).
var deck = Enumerable.Repeat(simpleDeck, 4).SelectMany(x => x);
.ToList();
deck.Shuffle();
return deck;
}
public static decimal ComputeScore(IEnumerable<Card> playerCards)
{
// Iterate through all cards the player is currently holding
// and tell the current player score.
throw new NotImplementException();
}
}
Upvotes: 1
Reputation: 567
Maybe something like this
public struct Card
{
public string suite;
public string value;
}
private static string[] Suite = new string[4] { "Clubs", "Hearts", "Spades", "Diamonds" };
private static string[] FaceValue = new string[13] { "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King" };
public static List<Card> CreateDeck()
{
List<Card> deckOfCards = new List<Card>();
for (int s = 0; s < Suite.Length; s++)
{
string sut = Suite[s];
for (int fV = 0; fV < FaceValue.Length; fV++)
{
Card myCard;
myCard.suite = sut;
myCard.value = FaceValue[fV];
deckOfCards.Add(myCard);
}
}
// End of For loop.
deckOfCards.Shuffle();
return deckOfCards;
}
Upvotes: 0