- Learn how to create a descent project structure
- Learn how to create a descent GIT repository
- Learn how to create a console application
- Learn how to implement a domain
- Learn how to write descent unit tests
- Learn how to link a
Class Library,xUnit Test Project - Learn how to create a solution
- Learn how to link projects to a solution
BlackJack is an easy card game. There is one dealer and at least one player. For simplicity, we'll implement a game for only one player.
The player plays againts the dealer. The goal is to draw cards untill you're as close as possible to 21 without exceeding this value. The player wins when his total is less than or equal to 21 and higher than the dealer's total. He loses when his total is higher than 21 and lower than or equal to the dealer's total. In the latter case, the dealer's total may not exceed 21.
Both player and dealer start with two cards. Only the dealer's first card is visible. The player starts: he can draw cards to come as close to 21 as possible. When the player is satisfied with the total, he gives turn to the dealer. The dealer draws cards until his total is higher than or equal to the player's total.
Every card counts for his value, except for the jack, queen and kind which stand for 10. The ace counts as 1 or 11, whatever suits you best. When your first two cards add up to 21 (10 or jack/queen/kind combined with an ace), you have Blackjack and win.
The Game has been published in a Blazor version (see later in Chapter 6) and can already be played. In this exerice you'll only implement the Domain and Unit Tests. You can start by playing the game to get a better understanding of the Domain. The deployed version can be found here.
- Create the following folder structure
- ch-3-exercise-3
- src
- tests
- ch-3-exercise-3
- Use a dotnet command to create a new solution in the root folder called
BlackJack - Use a dotnet command to create a
.gitignorefile in the root folderch-3-exercise-3 - Use a
gitcommand to make the root folderch-3-exercise-3a GIT repository - Use a
gitcommand or Visual Studio to commit your changes- Make sure there are no binary files tracked in the repository.
- Use a
dotnetcommand to create a new console application in thesrcfolder calledApp - Use a
dotnetcommand to create aclass libraryin thesrcfolder calledDomain - Use a
dotnetcommand to reference theDomainclass library in the console application - Remove the class
Class1 - Add the
AppandDomainproject to theBlackJacksolution - Use a
gitcommand or Visual Studio to commit your changes - Implement the following class diagram
- All methods should throw a
NotImplementedException - Explanation of each class can be found below
- All methods should throw a
-
Use a
gitcommand or Visual Studio to commit your changes -
Use a
dotnetcommand to create anxUnit test projectin thetestsfolder namedDomain.Tests -
Use a
dotnetcommand to reference theDomainclass library in the test project -
Remove the class
UnitTest1.cs -
Add the
Domain.Testsproject to theBlackJacksolution -
Use a
gitcommand or Visual Studio to commit your changes -
Copy all test classes from the
mainbranch into your test project and make the tests pass (also include theDeckStubs)CardTest: finished test class, make it passBlackJackCardTest: implement the given tests and make it passHandTest: implement the leftover tests and make it pass
-
Use a
gitcommand to commit your changes (per class) -
Create a class
DeckTestin the test project and implement the following tests:- constructor creates a deck of 52
BlackJackCards - method
Drawreturns an object of typeBlackJackCard - method
Drawthrows anInvalidOperationExceptionwhen the deck is empty
- constructor creates a deck of 52
-
Use a
gitcommand to commit your changes -
Copy the
BlackJackTestclass and make it pass -
Use a
gitcommand to commit your changes -
Copy the
Program.csfrom themainbranch into yourAppproject -
Use a
gitcommand to commit your changes -
Start playing!
A possible solution can be found here.
- Contains all informatin of one card from the deck, namely the suit (hearts...) and face (1, 2, ..., king).
- Stored in the properties
SuitandFaceValue
- Stored in the properties
- Has one constructor to create one card
- Inherits from
Card - Stores extra information for cards in the BlackJack game
- Properties
FaceUp: whether the face of card is visibleValue: the BlackJack value of this card, 0 if the card is not visible
- Has one constructor
- Face is not visible on creation
- Methods
TurnCard: makes the card (in)visible
- Represents a deck of cards
- Fields
_cards: the cards in the deck
- Has one constructor
- Creates a deck of 52 cards
Hint: to create a deck, you can loop over all enum values using a
foreachandEnum.GetValues(...)
- Methods
Draw: returns the first card from the deck, throws anInvalidOperationExceptionif the deck is emptyShuffle(private): shuffles the cards
- Represent a player/dealer
- Fields
_cards: cards in the player's hand
- Properties
Cards: returns the player's cardsNrOfCards: returns the number of cards in this handValue: total value of all cards
- Has one constructor
- Creates an empty hand
- Methods
AddCard: add aBlackJackCardto this handTurnAllCardsFaceUp: flips all cards with the face up
- Represent the whole game
- Two constants
FaceDown: has valuefalseFaceUp: has valuetrue
- Properties
DealerHand: dealer's handPlayerHand: player's handGameState: state of the game: player has turn, dealer has turn, game over
- Constructors
- One constructor creates two hands and a new
Deck - The other creates two hands and uses the given
Deck - Remember: both of the player's cards are faced up, but only one for the dealer + the player may already have BlackJack
- One constructor creates two hands and a new
- Methods
GivePlayerAnotherCard: gives a new card to the player, only if theGameStateifPlayerPlays. Could change theGameState. Throws anInvalidOperationExceptionif it's not possible to draw a card with the currentGameState.PassToDealer: gives turn to the dealer, his cards are faced up and theGameStatebecomesDealerPlays. The dealer plays untilGameStateGameOveris reached.GameSummary:nullif the game isn't finished yet, possibilities:- Player Burned, Dealer Wins
- Dealer Burned, Player Wins
- Equal, Dealer Wins
- Dealer Wins
- Player Wins
- BLACKJACK
AddCardToHand(private): gives a card to the given player, could be faced up/downAdjustGameState(private):- could set a given
GameState - Also checks the other domain rules (player/dealer has a total over 21, ...)
- could set a given
Deal(private): player and dealer get their initial cardsLetDealerFinalize(private): dealer plays untilGameStateisGameOver
