Added the blackjack lib

This commit is contained in:
2023-06-13 09:33:43 +02:00
parent 4d41c4618e
commit ca3142a6cd
8 changed files with 385 additions and 0 deletions

18
blackjack/CMakeLists.txt Normal file
View 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
View 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
View 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
View 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
View 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_;
};

View 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
View 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
View 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_;
};