I am currently coding a BlackJack Game, and now I am at the Sprint for the HAND and the thing is that the Hand has a HandVALUE and a HandRATING. This Value or Rating represent the Handsproperties or fields. The problem is (you will se it more in the code) that when I create a new HAND in the Console.NetFramework (UI) and type Console.WriteLine(Console.WriteLine("The Value of the hand is: " + hand.HandValue); or Console.WriteLine("The Rating of the hand is: " + hand.HandRating); that they always are 0 and None. 0 = HandValue and None is the HandRating. But they should have other Values and Ratings because (as you will see in the code) there are 3 cards with the value of 7 each = HANDVALUE : 21 and the HandRating should be TripleSeven (because we have 3 7-value cards). The Properties should be used and should set the HandValue and HandRating. (The code is very shortly shown here. If I would left something behind no one would understand the problem and code constructions)
Console.WriteLine("HAND - TESTS");
Hand hand = new Hand();
Console.WriteLine("First, output of the cards in the hand at the beginning. If their is nothing to see, the test" +
"is positive.");
ICard card3 = new Card(CardValue.Seven, CardSuit.Heart);
ICard card4 = new Card(CardValue.Seven, CardSuit.Spade);
ICard card5 = new Card(CardValue.Seven, CardSuit.Diamond);
Console.WriteLine("");
Console.WriteLine("Press <ENTER> to add one card to the hand:");
Console.ReadLine();
hand.AddCard(card3);
Console.WriteLine("If there is only one card ---> then this hand function is working.");
hand.CardsInHandConsole();
Console.WriteLine("Press <ENTER> to add the next card:");
Console.ReadLine();
hand.AddCard(card4);
hand.AddCard(card5);
Console.WriteLine("If there are 3 cards ---> then this hand function is working.");
hand.CardsInHandConsole();
Console.WriteLine("Press <ENTER> to continue:");
Console.ReadLine();
Console.WriteLine("The Value of the hand is: " + hand.HandValue);
Console.WriteLine("The Rating of the hand is: " + hand.HandRating);
The hand class and the last down ENUM HandRating:
public class Hand
{
private List<ICard> _cardsInHand = new List<ICard>();
private int _handValue;
private HandRating _handRating;
public int HandValue
{
get
{
return _handValue;
}
set
{
CalculateHandValue();
}
}
public HandRating HandRating
{
get
{
return _handRating;
}
set
{
//TripleSeven
if (_cardsInHand[0].Value == CardValue.Seven &&
_cardsInHand[1].Value == CardValue.Seven &&
_cardsInHand[2].Value == CardValue.Seven)
{
_handRating = HandRating.TripleSeven;
}
//BlackJack
else if (_cardsInHand[0].Value == CardValue.Jack &&
_cardsInHand[1].Value == CardValue.Ace)
{
_handRating = HandRating.BlackJack;
}
//Busted
else if (_handValue > 21)
{
_handRating = HandRating.Busted;
}
//None
else {
_handRating = HandRating.None;
}
}
}
public IEnumerable<ICard> CardsInHand
{
get
{
return _cardsInHand;
}
}
public void CardsInHandConsole()
{
foreach (ICard card in _cardsInHand)
{
Console.WriteLine(card.ToString());
}
}
public void AddCard(ICard card)
{
_cardsInHand.Add(card);
}
public void ClearHand()
{
_cardsInHand.Clear();
_handValue = 0;
_handRating = HandRating.None;
}
private void CalculateHandValue()
{
for (int i = 0; i <= _cardsInHand.Count(); i++)
{
ReturnValue(i);
}
}
public void ReturnValue(int index)
{
if (_cardsInHand[index].Value == CardValue.Two)
{
_handValue =+2;
}
else if (_cardsInHand[index].Value == CardValue.Three)
{
_handValue =+3;
}
else if (_cardsInHand[index].Value == CardValue.Four)
{
_handValue =+4;
}
else if (_cardsInHand[index].Value == CardValue.Five)
{
_handValue =+5;
}
else if (_cardsInHand[index].Value == CardValue.Six)
{
_handValue =+6;
}
else if (_cardsInHand[index].Value == CardValue.Seven)
{
_handValue =+7;
}
else if (_cardsInHand[index].Value == CardValue.Eight)
{
_handValue =+8;
}
else if (_cardsInHand[index].Value == CardValue.Nine)
{
_handValue =+9;
}
else if (_cardsInHand[index].Value == CardValue.Queen)
{
_handValue =+10;
}
else if (_cardsInHand[index].Value == CardValue.King)
{
_handValue =+10;
}
else if (_cardsInHand[index].Value == CardValue.Jack)
{
_handValue =+10;
}
else if (_cardsInHand[index].Value == CardValue.Ace)
{
if ((_handValue + 11) > 21)
{
_handValue =+1;
}
else
{
_handValue =+11;
}
}
}
#endregion
}
public enum HandRating
{
BlackJack,
TripleSeven,
Busted,
None,
}
There are a couple of things that needed to be changed in order to get the code to work:
In the Hand
class, HandValue
and HandRating
both have setters which does nothing, and should be refactored to be:
public int HandValue { get; private set; }
public HandRating HandRating { get; private set; }
At the same time, remove the _handValue
and _handRating
fields as it's not necessary, and replace with the properties above.
In CalculateHandValue()
, there's a bug which introduces an IndexOutOfRange
exception (the <= in the for loop should be <). CalculateHandValue()
can be refactored to make use of a foreach loop, like below:
private void CalculateHandValue()
{
foreach (var card in _cardsInHand)
{
ReturnValue(card);
}
}
ReturnValue()
doesn't cover all the card values (for instance 7 which was the use case in your console. Also, the incrementing was done incorrectly (should be += 2 instead of = +2). This is what it will look like if we add the new use case and fix the increment:
private void ReturnValue(ICard card)
{
if (card.Value == CardValue.Two)
{
HandValue += 2;
}
else if (card.Value == CardValue.Three)
{
HandValue += 3;
}
else if (card.Value == CardValue.Four)
{
HandValue += 4;
}
else if (card.Value == CardValue.Seven)
{
HandValue += 7;
}
}
I'll leave it up to you as an exercise to fill in the rest of the hand values, and maybe look into converting it into a switch
statement.
Create a new method CalculateHandRating()
which will use most of the logic from the HandRating
setter, but with modifications to ensure no no IndexOutOfRangeException
happens:
private void CalculateHandRating()
{
//TripleSeven
if (_cardsInHand.Count == 3 &&
_cardsInHand[0].Value == CardValue.Seven &&
_cardsInHand[1].Value == CardValue.Seven &&
_cardsInHand[2].Value == CardValue.Seven)
{
HandRating = HandRating.TripleSeven;
}
//BlackJack
else if (_cardsInHand.Count == 2 &&
_cardsInHand[0].Value == CardValue.Jack &&
_cardsInHand[1].Value == CardValue.Ace)
{
HandRating = HandRating.BlackJack;
}
//Busted
else if (HandValue > 21)
{
HandRating = HandRating.Busted;
}
//None
else
{
HandRating = HandRating.None;
}
}
Note the _cardsInHand.Count
clauses at each if block to ensure we have the correct number of cards in hand before evaluating.
Finally, in AddCard
, add the following like so:
public void AddCard(ICard card)
{
_cardsInHand.Add(card);
CalculateHandValue();
CalculateHandRating();
}
The class should look like this:
public class Hand
{
private List<ICard> _cardsInHand = new List<ICard>();
public int HandValue { get; private set; }
public HandRating HandRating { get; private set; }
public IEnumerable<ICard> CardsInHand
{
get
{
return _cardsInHand;
}
}
public void CardsInHandConsole()
{
foreach (ICard card in _cardsInHand)
{
Console.WriteLine(card.ToString());
}
}
public void AddCard(ICard card)
{
_cardsInHand.Add(card);
CalculateHandValue();
CalculateHandRating();
}
public void ClearHand()
{
_cardsInHand.Clear();
HandValue = 0;
HandRating = HandRating.None;
}
private void CalculateHandValue()
{
foreach (var card in _cardsInHand)
{
ReturnValue(card);
}
}
private void CalculateHandRating()
{
//TripleSeven
if (_cardsInHand.Count == 3 &&
_cardsInHand[0].Value == CardValue.Seven &&
_cardsInHand[1].Value == CardValue.Seven &&
_cardsInHand[2].Value == CardValue.Seven)
{
HandRating = HandRating.TripleSeven;
}
//BlackJack
else if (_cardsInHand.Count == 2 &&
_cardsInHand[0].Value == CardValue.Jack &&
_cardsInHand[1].Value == CardValue.Ace)
{
HandRating = HandRating.BlackJack;
}
//Busted
else if (HandValue > 21)
{
HandRating = HandRating.Busted;
}
//None
else
{
HandRating = HandRating.None;
}
}
private void ReturnValue(ICard card)
{
if (card.Value == CardValue.Two)
{
HandValue += 2;
}
else if (card.Value == CardValue.Three)
{
HandValue += 3;
}
else if (card.Value == CardValue.Four)
{
HandValue += 4;
}
else if (card.Value == CardValue.Seven)
{
HandValue += 7;
}
}
}