I'm creating a blackjack game for the hell of it (Another topic about War card game sparked my interest in trying to make a blackjack game).
Anyway, I have a class written that I'd like to get some feedback on. I don't want to give much detail about it because one thing I want is for you guys to tell me the complex areas that are not easily understandable and such.
So, this is a representation of a blackjack hand. Please comment and critique on it if you don't mind.
/// <summary>
/// Represents a collection of playing cards that a player is holding.
/// </summary>
/*
* Public Interface:
* Properties
* Cards : IEnumerable collection of cards
* IsSoftened : Boolean attribute that when any ace has been represented as one is true
* IsBusted : Boolean attribute that when hand total exceeds bust amount is true
* Total : Integer attribute set to total value of all cards in hand.
* Methods
* AddCard() : Method that allows adding a card to the collection of cards in hand.
* Refresh() : Re-calculation of hand's current state in regards to IsSoftened, IsBusted, and Total.
* Fold() : Empties collection of cards and sets IsSoftened and IsBusted to false, and Total to zero.
*/
class BlackjackHand
{
// Internal collection of cards for this hand.
private IList<Card> cards = null;
/// <summary>
/// Collection of cards in this hand.
/// </summary>
public IEnumerable<Card> Cards
{
get
{
Initialize();
return cards;
}
}
/// <summary>
/// Whether or not this hand is softened by an Ace represented as one instead of eleven.
/// </summary>
public bool IsSoftened
{ get; private set; }
/// <summary>
/// Whether or not we have gone over bust limit.
/// </summary>
public bool IsBusted
{ get; private set; }
/// <summary>
/// Represents the total of the hand by face values.
/// </summary>
public int Total
{ get; private set; }
public BlackjackHand()
{
Initialize();
}
/// <summary>
/// Singular location to create a new instance of cards. Subsequent runs will essentially be ignored.
/// </summary>
private void Initialize()
{
if (cards == null)
cards = new List<Card>();
}
/// <summary>
/// Adds a card to this hand and forces refresh of hand's state.
/// </summary>
/// <param name="card">the card to be added.</param>
public void AddCard(Card card)
{
Initialize();
cards.Add(card);
Refresh();
}
/// <summary>
/// Re-establishes settings of exposed properties in hand.
/// Can be called manually, or is called by adding a new card to hand.
/// </summary>
public void Refresh()
{
// First, get total which also sets IsSoftened.
Total = CalculateTotal();
// Next, find out if it's busted yet.
IsBusted = (Total > BlackjackRules.Bust);
}
/// <summary>
/// Remove all cards from hand and update IsSoftened, IsBusted, and Total to starting values.
/// </summary>
public void Fold()
{
Initialize();
cards.Clear();
IsSoftened = false;
IsBusted = false;
Total = 0;
}
/// <summary>
/// Calculates the total of all cards in hand.
/// Side Effects:
/// If aces required softening, sets IsSoftened to true.
/// </summary>
private int CalculateTotal()
{
Initialize();
// Method's return variable:
int total = 0;
// retrieve total number of aces in this hand:
int aceCount = cards.Count(card => card.Face == Faces.Ace);
// Excluding aces, add all face values in hand to total.
foreach (Card card in cards)
{
if (card.Face == Faces.Ace)
continue;
total += card.FaceValue;
}
// Based on current total, identify how many soft aces are required.
int softAceCount = GetSoftAceCount(total, aceCount);
// Hard aces are the left over aces that have not been softened.
int hardAceCount = aceCount - softAceCount;
// There's absolutely nothing we can do to manipulate the total any further so add hard aces and soft aces to total:
total += (hardAceCount * BlackjackRules.HardAce) + softAceCount;
// If we had to soften an ace, this hand is considered softened.
IsSoftened = (softAceCount > 0);
// Preserve calculated total to a non-calculated property.
Total = total;
// Finally, return the total
return total;
}
/// <summary>
/// Based on the total, identify how many aces must be softened for this hand.
/// </summary>
private int GetSoftAceCount(int total, int aces)
{
// Method's return variable:
int totalSoftAces = 0;
// If total is already greater than 21 then all aces need to be softened.
if (total > BlackjackRules.Bust)
totalSoftAces = aces;
// Otherwise, find out what it takes to process all aces while staying as below 21 as possible.
else
{
for (int acesLeft = aces; acesLeft >= aces; acesLeft--)
{
// Would treating current ace as hard bust us?
if ((total + BlackjackRules.HardAce) > BlackjackRules.Bust)
{
// We cannot process any more aces so soften remaining aces and exit loop:
totalSoftAces += acesLeft;
break;
}
// Add a hard ace to total (which is the hand's total)
else
{
total += BlackjackRules.HardAce;
}
}
}
// At this point, we know the total soft aces required even if it busts us in the process.
return totalSoftAces;
}
}
Thanks.

New Topic/Question
Reply




MultiQuote





|