- 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
.gitignore
file in the root folderch-3-exercise-3
- Use a
git
command to make the root folderch-3-exercise-3
a GIT repository - Use a
git
command or Visual Studio to commit your changes- Make sure there are no binary files tracked in the repository.
- Use a
dotnet
command to create a new console application in thesrc
folder calledApp
- Use a
dotnet
command to create aclass library
in thesrc
folder calledDomain
- Use a
dotnet
command to reference theDomain
class library in the console application - Remove the class
Class1
- Add the
App
andDomain
project to theBlackJack
solution - Use a
git
command 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
git
command or Visual Studio to commit your changes -
Use a
dotnet
command to create anxUnit test project
in thetests
folder namedDomain.Tests
-
Use a
dotnet
command to reference theDomain
class library in the test project -
Remove the class
UnitTest1.cs
-
Add the
Domain.Tests
project to theBlackJack
solution -
Use a
git
command or Visual Studio to commit your changes -
Copy all test classes from the
main
branch 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
git
command to commit your changes (per class) -
Create a class
DeckTest
in the test project and implement the following tests:- constructor creates a deck of 52
BlackJackCard
s - method
Draw
returns an object of typeBlackJackCard
- method
Draw
throws anInvalidOperationException
when the deck is empty
- constructor creates a deck of 52
-
Use a
git
command to commit your changes -
Copy the
BlackJackTest
class and make it pass -
Use a
git
command to commit your changes -
Copy the
Program.cs
from themain
branch into yourApp
project -
Use a
git
command 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
Suit
andFaceValue
- 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
foreach
andEnum.GetValues(...)
- Methods
Draw
: returns the first card from the deck, throws anInvalidOperationException
if 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 aBlackJackCard
to this handTurnAllCardsFaceUp
: flips all cards with the face up
- Represent the whole game
- Two constants
FaceDown
: has valuefalse
FaceUp
: 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 theGameState
ifPlayerPlays
. Could change theGameState
. Throws anInvalidOperationException
if it's not possible to draw a card with the currentGameState
.PassToDealer
: gives turn to the dealer, his cards are faced up and theGameState
becomesDealerPlays
. The dealer plays untilGameState
GameOver
is reached.GameSummary
:null
if 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 untilGameState
isGameOver