diff --git a/.gitignore b/.gitignore index 829f20f..d3358b8 100644 --- a/.gitignore +++ b/.gitignore @@ -286,4 +286,8 @@ __pycache__/ *.btp.cs *.btm.cs *.odx.cs -*.xsd.cs \ No newline at end of file +*.xsd.cs + +# Visual Studio files +*.vcxproj +*.vcxproj.filters \ No newline at end of file diff --git a/Blackjack/Blackjack.cpp b/Blackjack/Blackjack.cpp index 89db78f..3e0b60b 100644 --- a/Blackjack/Blackjack.cpp +++ b/Blackjack/Blackjack.cpp @@ -5,6 +5,7 @@ #include "blackjack.h" #include #include +#include // Get player input char getPlayerChoice() @@ -19,9 +20,9 @@ char getPlayerChoice() } // Deal a card, update scores, inform the player about it -void dealCard(int &score, const Card *&cardPtr, int &aces, bool player) { - score += getCardValue(*cardPtr++); - if ((*(cardPtr - 1)).rank == Rank::ACE) { +void dealCard(int &score, Card *&cardPtr, int &aces, bool player) { + score += (*(cardPtr++)).getCardValue(); + if ((*(cardPtr - 1)).getRank() == Card::Rank::ACE) { ++aces; } @@ -35,14 +36,14 @@ void dealCard(int &score, const Card *&cardPtr, int &aces, bool player) { verb = "has"; } std::cout << name << " got "; - printCard(*(cardPtr - 1)); + (*(cardPtr - 1)).printCard(); std::cout << "and " << verb << " a score of " << score << ".\n"; } // Game logic -bool playBlackjack(const Card deck[]) { +bool playBlackjack(Deck deck) { // Setup - const Card *cardPtr = &deck[0]; + Card *cardPtr = &deck.cards[0]; int dealerScore = 0; int playerScore = 0; int dealerAces = 0; @@ -97,7 +98,6 @@ bool playBlackjack(const Card deck[]) { } } - delete[] deck; return (playerScore > dealerScore); } @@ -122,7 +122,7 @@ int main() if (deckCount > 6) deckCount = 6; if (deckCount < 1) deckCount = 1; do { - bool playerWin = playBlackjack(getDeck(deckCount)); + bool playerWin = playBlackjack(Deck(deckCount)); if (playerWin) { std::cout << "Congratulations! You win!!!" << '\n'; diff --git a/Blackjack/Blackjack.vcxproj b/Blackjack/Blackjack.vcxproj deleted file mode 100644 index 746b1b7..0000000 --- a/Blackjack/Blackjack.vcxproj +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {D12E41C2-2A20-4D29-A7E4-B2E3B357A00E} - Win32Proj - Blackjack - 10.0.15063.0 - - - - Application - true - v141 - Unicode - - - Application - false - v141 - true - Unicode - - - Application - true - v141 - Unicode - - - Application - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - - - - - Use - Level3 - Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - - - - - Level3 - Use - MaxSpeed - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - \ No newline at end of file diff --git a/Blackjack/Blackjack.vcxproj.filters b/Blackjack/Blackjack.vcxproj.filters deleted file mode 100644 index f4293f1..0000000 --- a/Blackjack/Blackjack.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/Blackjack/Card.cpp b/Blackjack/Card.cpp new file mode 100644 index 0000000..cdd5647 --- /dev/null +++ b/Blackjack/Card.cpp @@ -0,0 +1,73 @@ +#include "stdafx.h" +#include +#include "blackjack.h" + +Card::Card(Rank r, Suit s) : rank(r), suit(s) {} + +// Prints the value of a card. +// The bool determines whether the programs prints a newline or a space between cards. +void Card::printCard(bool newline) { + switch (rank) + { + case Rank::TWO: std::cout << "two"; break; + case Rank::THREE: std::cout << "three"; break; + case Rank::FOUR: std::cout << "four"; break; + case Rank::FIVE: std::cout << "five"; break; + case Rank::SIX: std::cout << "six"; break; + case Rank::SEVEN: std::cout << "seven"; break; + case Rank::EIGHT: std::cout << "eight"; break; + case Rank::NINE: std::cout << "nine"; break; + case Rank::TEN: std::cout << "ten"; break; + case Rank::JACK: std::cout << "jack"; break; + case Rank::QUEEN: std::cout << "queen"; break; + case Rank::KING: std::cout << "king"; break; + case Rank::ACE: std::cout << "ace"; break; + default: break; + } + switch (suit) + { + case Suit::CLUB: std::cout << " of clubs"; break; + case Suit::DIAMOND: std::cout << " of diamonds"; break; + case Suit::HEART: std::cout << " of hearts"; break; + case Suit::SPADE: std::cout << " of spades"; break; + default: break; + } + if (newline) { + std::cout << '\n'; + } + else { + std::cout << ' '; + } +} + +// Get the value of a card. The value of the ace can be controlled using a boolean +int Card::getCardValue(const bool &aceEleven) { + switch (rank) + { + case Card::Rank::TWO: + case Card::Rank::THREE: + case Card::Rank::FOUR: + case Card::Rank::FIVE: + case Card::Rank::SIX: + case Card::Rank::SEVEN: + case Card::Rank::EIGHT: + case Card::Rank::NINE: + case Card::Rank::TEN: return static_cast(rank) + 2; break; + case Card::Rank::JACK: + case Card::Rank::QUEEN: + case Card::Rank::KING: return 10; break; + case Card::Rank::ACE: return aceEleven ? 11 : 1; break; + } +} + +// Return the rank of the card +Card::Rank Card::getRank() const +{ + return rank; +} + +// Return the suit of the card +Card::Suit Card::getSuit() const +{ + return suit; +} \ No newline at end of file diff --git a/Blackjack/Cards.cpp b/Blackjack/Cards.cpp deleted file mode 100644 index 64444dd..0000000 --- a/Blackjack/Cards.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "stdafx.h" -#include -#include "blackjack.h" -#include - -// Prints the value of a card. -// The bool determines whether the programs prints a newline or a space between cards. -void printCard(const Card card, bool newline) { - switch (card.rank) - { - case Rank::TWO: std::cout << "two"; break; - case Rank::THREE: std::cout << "three"; break; - case Rank::FOUR: std::cout << "four"; break; - case Rank::FIVE: std::cout << "five"; break; - case Rank::SIX: std::cout << "six"; break; - case Rank::SEVEN: std::cout << "seven"; break; - case Rank::EIGHT: std::cout << "eight"; break; - case Rank::NINE: std::cout << "nine"; break; - case Rank::TEN: std::cout << "ten"; break; - case Rank::JACK: std::cout << "jack"; break; - case Rank::QUEEN: std::cout << "queen"; break; - case Rank::KING: std::cout << "king"; break; - case Rank::ACE: std::cout << "ace"; break; - default: break; - } - switch (card.suit) - { - case Suit::CLUB: std::cout << " of clubs"; break; - case Suit::DIAMOND: std::cout << " of diamonds"; break; - case Suit::HEART: std::cout << " of hearts"; break; - case Suit::SPADE: std::cout << " of spades"; break; - default: break; - } - if (newline) { - std::cout << '\n'; - } - else { - std::cout << ' '; - } -} - -// Swap two cards -void swapCard(Card &first, Card &second) { - Card swap = first; - first = second; - second = swap; -} - -// Get a random number between two integers using a Mersenne Twister -int getRandom(int min, int max) -{ - static std::random_device rd; - static std::mt19937 mersenne(rd()); - std::uniform_int_distribution dis(min, max); - return dis(mersenne); -} - -// Shuffle a deck of cards random -void shuffleDeck(Card deck[], int size) { - for (int i = 0; i < size; ++i) { - swapCard(deck[i], deck[getRandom(0, size - 1)]); - } -} - -// Returns an ordered deck. The bool is used to return a shuffled deck. -Card* getDeck(int amount, bool shuffled) { - Card *deck = new Card[amount * 52]; - for (int i = 0; i < amount; ++i) { - for (int suit = 0; suit < static_cast(Suit::MAX_SUITS); ++suit) { - for (int rank = 0; rank < static_cast(Rank::MAX_RANKS); ++rank) { - deck[i * 52 + suit * static_cast(Rank::MAX_RANKS) + rank] = { static_cast(rank), static_cast(suit) }; - } - } - } - if (shuffled) { - shuffleDeck(deck, amount * 52); - } - return deck; -} - -// Print the entire deck -void printDeck(const Card deck[], int size) { - for (int i = 0; i < size; ++i) { - printCard(deck[i]); - } - std::cout << '\n'; -} - -// Get the value of a card. The value of the ace can be controlled using a boolean -int getCardValue(const Card &card, const bool &aceEleven) { - switch (card.rank) - { - case Rank::TWO: - case Rank::THREE: - case Rank::FOUR: - case Rank::FIVE: - case Rank::SIX: - case Rank::SEVEN: - case Rank::EIGHT: - case Rank::NINE: - case Rank::TEN: return static_cast(card.rank) + 2; break; - case Rank::JACK: - case Rank::QUEEN: - case Rank::KING: return 10; break; - case Rank::ACE: return aceEleven ? 11 : 1; break; - } -} diff --git a/Blackjack/Deck.cpp b/Blackjack/Deck.cpp new file mode 100644 index 0000000..ed75c46 --- /dev/null +++ b/Blackjack/Deck.cpp @@ -0,0 +1,56 @@ +#include "stdafx.h" +#include +#include +#include +#include "blackjack.h" + +Deck::Deck() +{ + Deck(1, true); +} + +Deck::Deck(int amount, bool shuffled) +{ + cards.resize(amount * 52); + for (int i = 0; i < amount; ++i) { + for (int suit = 0; suit < static_cast(Card::Suit::MAX_SUITS); ++suit) { + for (int rank = 0; rank < static_cast(Card::Rank::MAX_RANKS); ++rank) { + cards[i * 52 + suit * static_cast(Card::Rank::MAX_RANKS) + rank] = Card(static_cast(rank), static_cast(suit)); + } + } + } + if (shuffled) { + shuffleDeck(amount * 52); + } +} + +// Swap two cards +void Deck::swapCard(Card &first, Card &second) { + Card swap = first; + first = second; + second = swap; +} + +// Get a random number between two integers using a Mersenne Twister +int Deck::getRandom(int min, int max) +{ + static std::random_device rd; + static std::mt19937 mersenne(rd()); + std::uniform_int_distribution dis(min, max); + return dis(mersenne); +} + +// Shuffle a deck of cards random +void Deck::shuffleDeck(int size) { + for (int i = 0; i < size; ++i) { + swapCard(cards[i], cards[getRandom(0, size - 1)]); + } +} + +// Print the entire deck +void Deck::printDeck(int size) { + for (int i = 0; i < size; ++i) { + cards[i].printCard(); + } + std::cout << '\n'; +} diff --git a/Blackjack/blackjack.h b/Blackjack/blackjack.h index a0d37ed..56ffc27 100644 --- a/Blackjack/blackjack.h +++ b/Blackjack/blackjack.h @@ -1,43 +1,57 @@ #pragma once +#include #ifndef CARDS #define CARDS -enum class Rank { - TWO, - THREE, - FOUR, - FIVE, - SIX, - SEVEN, - EIGHT, - NINE, - TEN, - JACK, - QUEEN, - KING, - ACE, - MAX_RANKS -}; +class Card { +public: + enum class Rank { + TWO, + THREE, + FOUR, + FIVE, + SIX, + SEVEN, + EIGHT, + NINE, + TEN, + JACK, + QUEEN, + KING, + ACE, + MAX_RANKS + }; -enum class Suit { - CLUB, - DIAMOND, - HEART, - SPADE, - MAX_SUITS + enum class Suit { + CLUB, + DIAMOND, + HEART, + SPADE, + MAX_SUITS + }; +private: + Rank rank; + Suit suit; +public: + Card(Rank r = Rank::MAX_RANKS, Suit s = Suit::MAX_SUITS); + void printCard(bool newline = false); + int getCardValue(const bool &aceEleven = true); + Rank getRank() const; + Suit getSuit() const; }; -struct Card { - Rank rank; - Suit suit; +class Deck { +public: + std::vector cards; + Deck(); + Deck(int amount, bool shuffled = true); + void swapCard(Card &first, Card &second); + void shuffleDeck(int size); + void printDeck(int size); +private: + int getRandom(int min, int max); }; -void printCard(const Card card, bool newline = false); -void swapCard(Card &first, Card &second); -void shuffleDeck(Card deck[], int size); -Card* getDeck(int amount = 1, bool shuffled = true); -void printDeck(const Card deck[], int size); -int getCardValue(const Card &card, const bool &aceEleven = true); #endif // !CARDS diff --git a/README.md b/README.md index 7cc0c1c..a608852 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # Blackjack -Play blackjack against your computer! The Card.cpp and blackjack.h files can be used as base for any card game, since they contain all the mechanisms to create, shuffle and print packs and cards. This project uses the C++ standard library and the Visual Studio precompiled headers. The inspiration for this project was found over here: http://www.learncpp.com/cpp-tutorial/6-x-chapter-6-comprehensive-quiz/ +Play blackjack against your computer! The Card.cpp, Deck.cpp and blackjack.h files can be used as base for any card game, since they contain all the mechanisms to create, shuffle and print packs and cards. This project uses the C++ standard library and the Visual Studio precompiled headers. The inspiration for this project was found over here: http://www.learncpp.com/cpp-tutorial/6-x-chapter-6-comprehensive-quiz/