Blackjack Simulation Code
Blackjack Simulation Code
C++ Code
Visual Studio 2017
Deck.h
// this file declares and defines what a "deck" is for the program to use in the future
#ifndef _DECK_H
#define _DECK_H
enum CardType { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace
}; // declaring each card type, also assigning a preliminary value to each (note: value for each
card is 2 less than it should be)
struct Card
{
CardType type;
short value; // stating that each card will eventually be given a value
};
class Deck
{
private:
Card* m_pCards; // Array to hold the cards
int m_iNumCards; // Number of cards left in the deck
int m_uiMaxCards; // Max Cards the deck array can hold
public:
Deck();
~Deck();
#endif
Game.h
// this file labels all the actions that take place in one round, in addition to all the variables we
want to keep track of, like the win count, how many decks we've used, etc
#ifndef _GAME_H
#define _GAME_H
#include "Deck.h"
#include <vector>
class Game
{
private:
Deck m_dDeck; // The main deck of cards
std::vector<Card> m_aPlayerCards; // The player's hand
std::vector<Card> m_aDealerCards; // The dealer's hand
void RefillDeck();
void DrawCard(std::vector<Card>& hand);
unsigned int EvaluateHand(const std::vector<Card>& hand) const;
public:
Game(unsigned int numberOfFullDecksPerRefill = 2, unsigned int numberOfRefills = 12);
~Game();
void Setup();
void Play();
// declaring the totals for each of the previously assigned variables - these are what will
get displayed in our final results
unsigned int TotalGamesPlayed() const;
unsigned int TotalPlayerWins() const;
unsigned int TotalPlayerBlackjackWins() const;
unsigned int TotalTieGames() const;
float PlayerWinPercentage() const;
};
#endif
Deck.cpp
// this file actually assigns values to a lot of the variables declared in deck.h
#include "Deck.h"
#include <stdlib.h>
Deck::Deck()
{
m_iNumCards = 0;
m_pCards = nullptr;
CreateNewDeckArray(104); // a standard deck has 52 cards, but we're using two decks at
once, so we use an array length of 104
}
Deck::~Deck()
{
delete m_pCards;
}
void Deck::CreateNewDeckArray(unsigned int newSize) // generates a new deck array each time
the old one runs out of cards that doesn't exceed our specified size (104)
{
Card* temp = new Card[newSize];
if (m_pCards != nullptr)
{
int copyCount = newSize > m_iNumCards ? m_iNumCards : newSize;
for (int i = 0; i < copyCount; i++)
temp[i] = m_pCards[i];
delete m_pCards;
}
m_pCards = temp;
m_uiMaxCards = newSize;
}
void Deck::AddFullSetOfCardsToDeck() // adds ONE full deck of cards each time we run out
while playing (this function gets called twice, so we actually use two decks each time we reset)
{
if (m_iNumCards + 52 > m_uiMaxCards)
CreateNewDeckArray(m_uiMaxCards + 52);
int index = 0;
for (int suit = 0; suit < 4; suit++) // telling the program that there are four of each card type per
deck
{
for (int value = 0; value < 13; value++, index++)
{
Card newCard;
newCard.type = (CardType)value;
if (value < Ten)
newCard.value = value + 2; // this off-sets the values of the numbered cards being less
than they should have been
else if (value == Ace)
newCard.value = 11;
else
newCard.value = 10;
m_iNumCards += 52;
}
if (card1 == card2) // double-checks that no card ends up in the spot where it started
{
if (card2 == m_iNumCards - 1)
card2--;
else
card2++;
}
// defining what "drawing a card" means to the program - takes the top card off the deck and
reduces the number of cards in the deck by one
bool Deck::DrawCard(Card& card)
{
if (m_iNumCards == 0)
return false;
card = m_pCards[--m_iNumCards];
return true;
}
#include "Game.h"
void Game::RefillDeck() // telling the program what needs to be done when we want to refill the
deck
{
m_dDeck.AddCardsToDeck(m_uiDecksToFillWith);
m_dDeck.Shuffle();
m_uiNumTimesFillingDeck++;
}
void Game::DrawCard(std::vector<Card>& hand) // if we are unable to draw a card, it means the
deck is empty and we need to refill it
{
Card drawnCard;
if (m_dDeck.DrawCard(drawnCard) == false)
{
RefillDeck();
m_dDeck.DrawCard(drawnCard);
}
hand.push_back(drawnCard);
}
unsigned int Game::EvaluateHand(const std::vector<Card>& hand) const // determining whether
to count an ace as an 11 or a 1
{
int val = 0;
int numAces = 0;
for (size_t i = 0; i < hand.size(); i++)
{
if (hand[i].type == Ace)
numAces++;
val += hand[i].value;
}
return val;
}
void Game::InitialDeal() // starting a new round
{
m_uiNumGamesPlayed++;
DrawCard(m_aPlayerCards);
DrawCard(m_aDealerCards);
DrawCard(m_aPlayerCards);
DrawCard(m_aDealerCards);
// we don't need to compute dealer blackjacks, because they don't matter in terms
of our total winnings - we lose the same amount whether they get blackjack or not
ResetRound();
InitialDeal();
}
}
void Game::PlayerTurn() // player logic - we choose to hit unless we have 16 or lower
{
while (EvaluateHand(m_aPlayerCards) < 17)
DrawCard(m_aPlayerCards);
if (dealerScore == playerScore || (dealerScore > 21 && playerScore > 21)) // if the player
and dealer are tied, or if both bust
m_uiNumTieGames++;
else if ((playerScore > dealerScore || dealerScore > 21) && playerScore <= 21) // if the
player has more than the dealer, or if the dealer busts - the player cannot bust here
m_uiPlayerWins++;
}
void Game::ResetRound() // this empties the players' hands
{
m_aDealerCards.clear();
m_aPlayerCards.clear();
}
Source.cpp
// this is the parent function that references everything declared in the other functions. It calls the
results from game.cpp and displays the output.
#include <iostream>
#include <time.h>
#include "Game.h"
#include <iomanip>
void main()
{
// declaring output variables and giving them an initial value
srand(static_cast<unsigned int>(time(0)));
int totalOutcome = 0;
int TotalGamesPlayed = 0;
int TotalPlayerWins = 0;
int TotalPlayerBlackjackWins = 0;
int TotalTieGames = 0;
// looping the calculations and output for each round, making only 12 rounds
for (unsigned int games = 0; games < 1000000; games++)
{
Game game(2, 1);
game.Setup();
game.Play();
// output
if (outcome < 0)
cout << "Deck " << games + 1 << " Outcome: -$" << abs(outcome) <<
'\n';
else
cout << "Deck " << games + 1 << " Outcome: $" << outcome << '\n';
}
system("PAUSE");
return;
}