Programming With C#: Generic Collections Practice
Programming With C#: Generic Collections Practice
Microsoft|edX
Microsoft|edX
12.
After the inner for loop, add the List object to the cardPack
Dictionary collection, specifying the value of the suit variable as the
key to this item:
for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
{
List<PlayingCard> cardsInSuit = new
List<PlayingCard>(CardsPerSuit);
for (Value value = Value.Two; value <= Value.Ace; value++)
{
cardsInSuit.Add(new PlayingCard(suit, value));
}
this.cardPack.Add(suit, cardsInSuit);
}
13.
This method picks a card at random from the pack, removes the card from
the pack, and returns this card. The logic for selecting the card does not
require any changes, but the statements at the end of the method that
retrieve the card from the array must be updated to use the Dictionary
collection, instead. Additionally, the code that removes the card from the
array (it has now been dealt) must be modified; you need to search for
the card in the list and then remove it from the list. To locate the card, use
the Find method and specify a predicate that finds a card with the
matching value. The parameter to the predicate should be a PlayingCard
object (the list contains PlayingCard items).
14.
The updated statements occur after the closing brace of the
second while loop, as shown in bold in the following code:
public PlayingCard DealCardFromPack()
{
Suit suit = (Suit)randomCardSelector.Next(NumSuits);
while (this.IsSuitEmpty(suit))
{
suit = (Suit)randomCardSelector.Next(NumSuits);
}
Value value = (Value)randomCardSelector.Next(CardsPerSuit);
while (this.IsCardAlreadyDealt(suit, value))
{
Microsoft|edX
value = (Value)randomCardSelector.Next(CardsPerSuit);
}
List<PlayingCard> cardsInSuit = this.cardPack[suit];
PlayingCard card = cardsInSuit.Find(c => c.CardValue
== value);
cardsInSuit.Remove(card);
return card;
}
15.
Locate the IsCardAlreadyDealt method.
16.
This method determines whether a card has already been dealt
by checking whether the corresponding element in the array has been
set to null. You need to modify this method to determine whether a
card with the specified value is present in the list for the suit in the
cardPack Dictionary collection.
17.
To determine whether an item exists in a List<T> collection, you
use the Exists method. This method is similar to Find inasmuch as it
takes a predicate as its argument. The predicate is passed each item
from the collection in turn, and it should return true if the item matches
some specified criteria, and false otherwise. In this case, the List<T>
collection holds PlayingCard objects, and the criteria for the Exists
predicate should return true if it is passed a PlayingCard item with a
suit and value that matches the parameters passed to the
IsCardAlreadyDealt method.
18.
Update the method, as shown in the following example, in bold:
private bool IsCardAlreadyDealt(Suit suit, Value value)
{
List<PlayingCard> cardsInSuit = this.cardPack[suit];
return (!cardsInSuit.Exists(c => c.CardSuit == suit &&
c.CardValue == value));
}
19.
Display the Hand.cs file in the Code and Text Editor window. Add
the following using directive to the list at the top of the file:
using System.Collections.Generic;
20.
The Hand class currently uses an array called cards to hold the
playing cards for the hand. Modify the definition of the cards variable
to be a List<PlayingCard> collection, as shown here in bold:
Microsoft|edX
class Hand
{
public const int HandSize = 13;
private List<PlayingCard> cards = new
List<PlayingCard>(HandSize);
...
}
21.
Find the AddCardToHand method.
22.
This method currently checks to see whether the hand is full; if it
is not, it adds the card provided as the parameter to the cards array at
the index specified by the playingCardCount variable.
23.
Update this method to use the Add method of the
List<PlayingCard> collection, instead.
24.
This change also removes the need to explicitly keep track of
how many cards the collection holds because you can use the Count
property of the cards collection, instead. Therefore, remove the
playingCardCount variable from the class and modify the if statement
that checks whether the hand is full to reference the Count property of
the cards collection.
25.
The completed method should look like this, with the changes
highlighted in bold:
public void AddCardToHand(PlayingCard cardDealt)
{
if (this.cards.Count >= HandSize)
{
throw new ArgumentException("Too many cards");
}
this.cards.Add(cardDealt);
}
26.
On the Debug menu, click Start Debugging to build and run the
application.
27.
When the Card Game form appears, click Deal.
Note Remember that in the Windows Store apps version of this
application, the Deal button is located on the app bar.
28.
Verify that the cards are dealt and that the populated hands
appear as before. Click Deal again to generate another random set of
hands.
29. Stop the application and close Visual Studio.
Microsoft|edX