Added the blackjack lib
This commit is contained in:
18
blackjack/CMakeLists.txt
Normal file
18
blackjack/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
add_library(blackjack "")
|
||||
target_sources(blackjack
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Deck.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Player.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Card.cpp
|
||||
)
|
||||
|
||||
target_include_directories(blackjack
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${PROJECT_BINARY_DIR}
|
||||
${PROJECT_DIR}/external
|
||||
)
|
||||
|
||||
target_compile_options(blackjack PRIVATE $<$<CONFIG:Debug>:
|
||||
-Wall -Wextra -pedantic-errors -Wconversion -Wsign-conversion -g
|
||||
>)
|
||||
100
blackjack/Card.cpp
Normal file
100
blackjack/Card.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "Card.hpp"
|
||||
|
||||
Card::Card(Rank rank, Suit suit) : rank_(rank), suit_(suit) {}
|
||||
|
||||
Card::Rank Card::getRank() const
|
||||
{
|
||||
return rank_;
|
||||
}
|
||||
Card::Suit Card::getSuit() const
|
||||
{
|
||||
return suit_;
|
||||
}
|
||||
|
||||
std::string Card::rank_to_string(void) const
|
||||
{
|
||||
std::string rank;
|
||||
switch (rank_)
|
||||
{
|
||||
case Rank::ACE:
|
||||
rank = "Ace";
|
||||
break;
|
||||
case Rank::TWO:
|
||||
rank = "Two";
|
||||
break;
|
||||
case Rank::THREE:
|
||||
rank = "Three";
|
||||
break;
|
||||
case Rank::FOUR:
|
||||
rank = "Four";
|
||||
break;
|
||||
case Rank::FIVE:
|
||||
rank = "Five";
|
||||
break;
|
||||
case Rank::SIX:
|
||||
rank = "Six";
|
||||
break;
|
||||
case Rank::SEVEN:
|
||||
rank = "Seven";
|
||||
break;
|
||||
case Rank::EIGHT:
|
||||
rank = "Eight";
|
||||
break;
|
||||
case Rank::NINE:
|
||||
rank = "Nine";
|
||||
break;
|
||||
case Rank::TEN:
|
||||
rank = "Ten";
|
||||
break;
|
||||
case Rank::JACK:
|
||||
rank = "Jack";
|
||||
break;
|
||||
case Rank::QUEEN:
|
||||
rank = "Queen";
|
||||
break;
|
||||
case Rank::KING:
|
||||
rank = "King";
|
||||
break;
|
||||
case Rank::end:
|
||||
default:
|
||||
rank = "Invalid";
|
||||
break;
|
||||
}
|
||||
|
||||
return rank;
|
||||
}
|
||||
|
||||
std::string Card::suit_to_string() const
|
||||
{
|
||||
std::string suit;
|
||||
switch (suit_)
|
||||
{
|
||||
case Suit::HEARTS:
|
||||
suit = "Hearts";
|
||||
break;
|
||||
case Suit::DIAMONDS:
|
||||
suit = "Diamonds";
|
||||
break;
|
||||
case Suit::CLUBS:
|
||||
suit = "Clubs";
|
||||
break;
|
||||
case Suit::SPADES:
|
||||
suit = "Spades";
|
||||
break;
|
||||
case Suit::end:
|
||||
default:
|
||||
suit = "Invalid";
|
||||
break;
|
||||
}
|
||||
return suit;
|
||||
}
|
||||
|
||||
std::string Card::to_string() const
|
||||
{
|
||||
return rank_to_string() + " of " + suit_to_string();
|
||||
}
|
||||
|
||||
bool Card::operator==(const Card &other) const
|
||||
{ return (rank_ == other.getRank()
|
||||
&& suit_ == other.getSuit());
|
||||
}
|
||||
52
blackjack/Card.hpp
Normal file
52
blackjack/Card.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <ctime>
|
||||
#include <algorithm> // for "shuffle"
|
||||
|
||||
#include "IterableEnum.hpp"
|
||||
|
||||
class Card
|
||||
{
|
||||
public:
|
||||
ITERABLE_ENUM_BEGIN(Rank)
|
||||
ACE = 1,
|
||||
TWO,
|
||||
THREE,
|
||||
FOUR,
|
||||
FIVE,
|
||||
SIX,
|
||||
SEVEN,
|
||||
EIGHT,
|
||||
NINE,
|
||||
TEN,
|
||||
JACK,
|
||||
QUEEN,
|
||||
KING
|
||||
ITERABLE_ENUM_END;
|
||||
|
||||
ITERABLE_ENUM_BEGIN(Suit)
|
||||
HEARTS,
|
||||
DIAMONDS,
|
||||
CLUBS,
|
||||
SPADES
|
||||
ITERABLE_ENUM_END;
|
||||
|
||||
Card(Rank rank, Suit suit);
|
||||
|
||||
Rank getRank() const;
|
||||
Suit getSuit() const;
|
||||
|
||||
std::string rank_to_string() const;
|
||||
std::string suit_to_string() const;
|
||||
std::string to_string() const;
|
||||
|
||||
bool operator==(const Card &other) const;
|
||||
|
||||
private:
|
||||
Rank rank_;
|
||||
Suit suit_;
|
||||
};
|
||||
30
blackjack/Deck.cpp
Normal file
30
blackjack/Deck.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "Deck.hpp"
|
||||
|
||||
Deck::Deck(void)
|
||||
{
|
||||
for (Iterable<Card::Suit> suit; suit < Card::Suit::end; suit++)
|
||||
{
|
||||
for (Iterable<Card::Rank> rank = Card::Rank::ACE; rank < Card::Rank::end; rank++)
|
||||
{
|
||||
cards_.push_back(std::make_unique<Card>(rank.val(), suit.val()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Deck::shuffledeck(void)
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(cards_.begin(), cards_.end(), g);
|
||||
}
|
||||
|
||||
std::unique_ptr<Card> Deck::drawCard(void)
|
||||
{
|
||||
if (cards_.empty())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<Card> card = std::move(cards_.back());
|
||||
cards_.pop_back();
|
||||
return card;
|
||||
}
|
||||
21
blackjack/Deck.hpp
Normal file
21
blackjack/Deck.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include "Card.hpp"
|
||||
#include "IterableEnum.hpp"
|
||||
|
||||
class Deck
|
||||
{
|
||||
public:
|
||||
Deck(void);
|
||||
|
||||
void shuffledeck(void);
|
||||
std::unique_ptr<Card> drawCard();
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Card>> cards_;
|
||||
};
|
||||
95
blackjack/IterableEnum.hpp
Normal file
95
blackjack/IterableEnum.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#define ITERABLE_ENUM_BEGIN(name) enum class name : int {
|
||||
#define ITERABLE_ENUM_END ,end, begin = 0 }
|
||||
|
||||
template <class T>
|
||||
class Iterable
|
||||
{
|
||||
public:
|
||||
Iterable(T value = T::begin) : mValue(value) {}
|
||||
Iterable(const Iterable& other) : mValue(other.mValue) {}
|
||||
|
||||
Iterable& operator++()
|
||||
{
|
||||
assert(mValue >= T::begin && mValue < T::end);
|
||||
mValue = static_cast<T>(static_cast<int>(mValue) + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterable operator++(int)
|
||||
{
|
||||
Iterable prev = *this;
|
||||
mValue = static_cast<T>(static_cast<int>(mValue) + 1);
|
||||
return prev;
|
||||
}
|
||||
|
||||
Iterable& operator--()
|
||||
{
|
||||
assert(mValue >= T::end && mValue < T::begin);
|
||||
mValue = static_cast<T>(static_cast<int>(mValue) - 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterable operator--(int)
|
||||
{
|
||||
Iterable prev = *this;
|
||||
mValue = static_cast<T>(static_cast<int>(mValue) - 1);
|
||||
return prev;
|
||||
}
|
||||
|
||||
Iterable operator+(int i)
|
||||
{
|
||||
return static_cast<T>(static_cast<int>(mValue) + i);
|
||||
}
|
||||
|
||||
Iterable operator+(T i)
|
||||
{
|
||||
return static_cast<T>(static_cast<int>(mValue) + static_cast<int>(i));
|
||||
}
|
||||
|
||||
Iterable operator-(int i)
|
||||
{
|
||||
return static_cast<T>(static_cast<int>(mValue) - i);
|
||||
}
|
||||
|
||||
Iterable operator-(T i)
|
||||
{
|
||||
return static_cast<T>(static_cast<int>(mValue) - static_cast<int>(i));
|
||||
}
|
||||
|
||||
|
||||
bool operator >(const T& other) const
|
||||
{
|
||||
return static_cast<int>(mValue) > static_cast<int>(other);
|
||||
}
|
||||
|
||||
bool operator >=(const T& other) const
|
||||
{
|
||||
return static_cast<int>(mValue) >= static_cast<int>(other);
|
||||
}
|
||||
|
||||
bool operator <(const T& other) const
|
||||
{
|
||||
return static_cast<int>(mValue) < static_cast<int>(other);
|
||||
}
|
||||
|
||||
bool operator <=(const T& other) const
|
||||
{
|
||||
return static_cast<int>(mValue) <= static_cast<int>(other);
|
||||
}
|
||||
|
||||
bool operator ==(const T& other) const
|
||||
{
|
||||
return static_cast<int>(mValue) == static_cast<int>(other);
|
||||
}
|
||||
|
||||
bool valid() const { return mValue != T::end; }
|
||||
|
||||
operator T() const { return mValue; }
|
||||
operator T&() { return mValue; }
|
||||
T val() const { return mValue; }
|
||||
|
||||
private:
|
||||
T mValue;
|
||||
};
|
||||
48
blackjack/Player.cpp
Normal file
48
blackjack/Player.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "Player.hpp"
|
||||
|
||||
void Player::addCard(std::unique_ptr<Card> card)
|
||||
{
|
||||
hand_.push_back(std::move(card));
|
||||
}
|
||||
|
||||
Card Player::getLastCard(void) const
|
||||
{
|
||||
return Card(hand_.back()->getRank(), hand_.back()->getSuit());
|
||||
}
|
||||
|
||||
int Player::getHandValue() const
|
||||
{
|
||||
int value = 0;
|
||||
int aces = 0;
|
||||
for (const auto &card : hand_)
|
||||
{
|
||||
int cardValue = (int)card->getRank();
|
||||
if (cardValue >= 10)
|
||||
{
|
||||
cardValue = 10;
|
||||
}
|
||||
else if (cardValue == (int)Card::Rank::ACE)
|
||||
{
|
||||
aces++;
|
||||
cardValue = 11;
|
||||
}
|
||||
value += cardValue;
|
||||
}
|
||||
|
||||
while (value > 21 && aces > 0)
|
||||
{
|
||||
value -= 10;
|
||||
aces--;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string Player::getHandString() const
|
||||
{
|
||||
std::string handString;
|
||||
for (const auto &card : hand_)
|
||||
{
|
||||
handString += card->to_string() + " ";
|
||||
}
|
||||
return handString;
|
||||
}
|
||||
21
blackjack/Player.hpp
Normal file
21
blackjack/Player.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include "Card.hpp"
|
||||
|
||||
class Player
|
||||
{
|
||||
public:
|
||||
void addCard(std::unique_ptr<Card> card);
|
||||
|
||||
Card getLastCard(void) const;
|
||||
int getHandValue() const;
|
||||
std::string getHandString() const;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Card>> hand_;
|
||||
};
|
||||
Reference in New Issue
Block a user