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