Question
C++ I finished majority of the code but I just need help with the last function calc_score I have provided the two code files below
C++ I finished majority of the code but I just need help with the last function calc_score I have provided the two code files below and the requirements asked
For the main I just need steps 9-11
main.cpp
#include
#include
#include
#include
#include
#include "card.hh"
using cards = std::deque
//function to generate a deck of cards
cards gen_deck_of_cards()
{
cards retval;
for (card_faces f(card_faces_begin), fEnd; f != fEnd; ++f)
for (card_suits s(card_suits_begin), sEnd; s != sEnd; ++s)
retval.push_back(card{*f,*s});
return retval;
}
//function that shuffles the deck of cards
void shuffle_cards(cards& cs)
{
std::random_device rd;
std::mt19937 gen(rd());
std::shuffle (cs.begin(), cs.end(), gen);
}
//function that draws 'N' cards from the deck
cards draw (std::size_t num, cards& deck)
{
auto pos = deck.begin();
if (num
{
std::advance(pos, num);
}
else
pos = deck.end();
cards drawn(deck.begin(), pos);
deck.erase(deck.begin(), pos);
return drawn;
}
//function that calculates the score of the hand
auto calc_score(std::size_t const&, card const&)
{
size_t low = std::accumulate(hand.begin(), hand.end(), size_t{}, LOW_SUM_OP);
size_t high = std::accumulate(hand.begin(), hand.end(), size_t{}, HIGH_SUM_OP);
return {low, high};
}
int main()
{
cards deck;
cards hand;
//generates a deck of cards
deck = gen_deck_of_cards();
//shuffles the deck of cards
shuffle_cards(deck);
//prints out the deck of cards
std::cout
copy(deck.begin(), deck.end(), std::ostream_iterator
std::cout
//draws 3 cards from the deck
hand = draw(3,deck);
std::cout
copy(deck.begin(), deck.end(), std::ostream_iterator
std::cout
copy(hand.begin(), hand.end(), std::ostream_iterator
std::cout
//calculates score of the hand
calc_score(hand);
copy(hand.begin(), hand.end(), std::ostream_iterator
return 0;
} card.hh
#ifndef card_hxx_
#define card_hxx_
//===========================================================================
#include
#include
#include
#include
#include
#include
#include
//===========================================================================
class card
{
public:
using face_type = char;
enum { invalid=0, ace=1, jack=11, queen=12, king=13 };
enum suit_type : char { club, spade, diamond, heart };
private:
face_type face_;
suit_type suit_;
public:
// default construct invalid card value when face_ == 0...
constexpr card() : face_{} { };
constexpr card(card const&) = default;
constexpr card(card&&) = default;
constexpr card& operator =(card const&) = default;
constexpr card& operator =(card&&) = default;
constexpr card(face_type const& f, suit_type const& s) :
face_{f},
suit_{s}
{
if (!valid())
throw std::domain_error("Invalid card.");
}
constexpr auto operator (card const&) const noexcept = default;
constexpr operator bool() const noexcept
{
return valid();
}
constexpr bool valid() const noexcept
{
return face_
}
constexpr face_type face() const noexcept { return face_; }
constexpr suit_type suit() const noexcept { return suit_; }
constexpr void invalidate() noexcept
{
face_ = invalid;
}
constexpr void set(face_type const& f, suit_type const& s)
{
card tmp(f,s);
swap(tmp);
}
constexpr void swap(card& b) noexcept
{
using std::swap;
swap(face_, b.face_);
swap(suit_, b.suit_);
}
friend std::istream& operator >>(std::istream&, card&);
friend std::ostream& operator
};
inline constexpr auto operator (
card::suit_type const& a,
card::suit_type const& b
) noexcept
{
return
static_cast<:underlying_type_t>>(a)
static_cast<:underlying_type_t>>(b)
;
}
inline constexpr void swap(card& a, card& b) noexcept
{
a.swap(b);
}
//===========================================================================
struct card_faces_begin_t final { };
constexpr card_faces_begin_t card_faces_begin{};
class card_faces
{
private:
card::face_type face_;
public:
constexpr card_faces(card_faces_begin_t const&) noexcept :
face_{card::ace}
{
}
constexpr card_faces(card::face_type const& f = card::king+1) :
face_{f}
{
}
constexpr card_faces(card_faces const&)
noexcept = default;
constexpr card_faces& operator =(
card_faces const&) noexcept = default;
constexpr bool operator ==(card_faces const& b) const
noexcept = default;
constexpr card::face_type const& operator *() const noexcept
{
return face_;
}
// prefix ++
constexpr card_faces& operator ++() noexcept
{
++face_;
return *this;
}
// postfix ++
constexpr card_faces operator ++(int) noexcept
{
card_faces retval(*this);
this->operator ++();
return retval;
}
};
//===========================================================================
struct card_suits_begin_t final { };
constexpr card_suits_begin_t card_suits_begin{};
class card_suits
{
private:
std::optional<:suit_type> suit_;
public:
// default constructor constructs invalid suit...
constexpr card_suits() noexcept :
suit_{}
{
}
constexpr card_suits(card_suits_begin_t const&) noexcept :
suit_{card::club}
{
}
constexpr card_suits(card::suit_type const& s) :
suit_{s}
{
}
constexpr card_suits(card_suits const&) noexcept = default;
constexpr card_suits& operator =(card_suits const&) noexcept = default;
constexpr bool operator ==(card_suits const& b) const
noexcept = default;
constexpr card::suit_type const& operator *() const noexcept
{
return *suit_;
}
// prefix ++
constexpr card_suits& operator ++() noexcept
{
if (suit_)
{
switch (*suit_)
{
case card::club: suit_ = card::spade; break;
case card::spade: suit_ = card::diamond; break;
case card::diamond: suit_ = card::heart; break;
default:
case card::heart: suit_.reset(); break;
}
}
return *this;
}
// postfix ++
constexpr card_suits operator ++(int) noexcept
{
card_suits retval(*this);
this->operator ++();
return retval;
}
};
//===========================================================================
//
// For I/O purposes:
// * a "0" face is an invalid card.
// * a "1" face is a 10.
// * a "A", "J", "Q", or "K" face is the same.
// * otherwise the face is a number between 2 and 9.
// * the suit is one of "H", "D", "C", or "S" representing
// hearts, diamonds, clubs, and spades respectively
// * when read in, the suit or face can be in lower case
// * when written out, the suit or face will always be upper case
//
inline std::istream& operator >>(std::istream& is, card& c)
{
std::istream::sentry s(is);
if (s)
{
// read in card "number"...
char ch;
if (is >> ch) // this can skip whitespace
{
switch (ch)
{
case '0': c.face_ = card::invalid; break;
case 'a':
case 'A': c.face_ = card::ace; break;
case '2': c.face_ = 2; break;
case '3': c.face_ = 3; break;
case '4': c.face_ = 4; break;
case '5': c.face_ = 5; break;
case '6': c.face_ = 6; break;
case '7': c.face_ = 7; break;
case '8': c.face_ = 8; break;
case '9': c.face_ = 9; break;
case '1': c.face_ = 10; break;
case 'j':
case 'J': c.face_ = card::jack; break;
case 'q':
case 'Q': c.face_ = card::queen; break;
case 'k':
case 'K': c.face_ = card::king; break;
default:
is.setstate(std::ios::failbit);
is.unget();
return is;
}
}
// read in card suit...
auto ch2 = is.get();
// i.e., unformatted call to get char so no whitespace is skipped
if (ch2 == std::istream::traits_type::eof())
{
// NOTE: unformatted calls return traits_type::eof() to indicate
// an error. This is like checking for a EOF or -1 error when
// doing file I/O in C.
is.setstate(std::ios::badbit);
return is;
}
switch (static_cast
{
case 'C': c.suit_ = card::club; break;
case 'S': c.suit_ = card::spade; break;
case 'H': c.suit_ = card::heart; break;
case 'D': c.suit_ = card::diamond; break;
default:
is.setstate(std::ios::badbit); // invalid suit
break;
}
}
return is;
}
inline std::ostream& operator
{
std::ostream::sentry s(os);
if (s)
{
// output number/face...
switch (c.face_)
{
case card::invalid: os
case card::ace: os
case card::jack: os
case card::queen: os
case card::king: os
case 10: os
default: os (c.face_); break;
}
// output suit...
switch (c.suit_)
{
case card::club: os
case card::spade: os
case card::diamond: os
case card::heart: os
}
}
return os;
}
//===========================================================================
#endif // #ifndef card_hxx_
Write the code in calc_score() as follows: 1. size_t low = accumulate(hand.begin(), hand.end(), size_t{}, LOW_SUM_OP); 2. size_t high = accumulate(hand.begin(), hand.end(), size_t{}, HIGH_SUM_OP); 3. return { low, high }; where LOW_SUM_OP and HIGH_SUM_OP are functions, lambda functions, or function objects (of your choosing) to calculate the low and high score in a hand respectively. (Try using lambda functions here!) The signature of LOW_SUM_OP and HIGH_SUM_OP are what std::accumulate requires when a binary operator is passed in. The first argument is the current sum, and, the second argument is the next element in the container to add to the current sum. Thus, the return value of both LOW_SUM_OP and HIGH_SUM_OP is the first argument + whatever score the current card is. This also means the first argument will be std::size_t const& and the second argument is card const&. Tip: Check that this function works before continuing further. Writing main() Your main() function should now be easy to write if you wrote test code for the above! The code in main() is to do the following in the order listed: 1. In a single line of code, construct a local variable called deck of type cards passing the result of gen_deck_of_cards() to it. 2. In a single line of code, call shuffle_cards() using deck from step 1. 3. Output "Deck: " followed by all cards in deck (each card is separated by a space) followed by a newline char. 4. Output an empty line. 5. Output "Drawing 3 cards... In". 6. In a single line of code, construct a local variable called hand passing the result of draw(3, deck) to it. 7. Output "Deck: " followed by all cards currently in deck (each card is separated by a space) followed by a newline char. 8. Output "Hand: " followed by all cards in hand (each card is separated by a space) followed by a newline char. 9. In a single line of code, construct a local variable with the result returned by calc_score(hand). 10. If the first and second score results are the same, then output "Score: " followed by the score and then a newline char. 11. Otherwise output "Possible Score: " followed by the low and high scores and then a newline char. Write the code in calc_score() as follows: 1. size_t low = accumulate(hand.begin(), hand.end(), size_t{}, LOW_SUM_OP); 2. size_t high = accumulate(hand.begin(), hand.end(), size_t{}, HIGH_SUM_OP); 3. return { low, high }; where LOW_SUM_OP and HIGH_SUM_OP are functions, lambda functions, or function objects (of your choosing) to calculate the low and high score in a hand respectively. (Try using lambda functions here!) The signature of LOW_SUM_OP and HIGH_SUM_OP are what std::accumulate requires when a binary operator is passed in. The first argument is the current sum, and, the second argument is the next element in the container to add to the current sum. Thus, the return value of both LOW_SUM_OP and HIGH_SUM_OP is the first argument + whatever score the current card is. This also means the first argument will be std::size_t const& and the second argument is card const&. Tip: Check that this function works before continuing further. Writing main() Your main() function should now be easy to write if you wrote test code for the above! The code in main() is to do the following in the order listed: 1. In a single line of code, construct a local variable called deck of type cards passing the result of gen_deck_of_cards() to it. 2. In a single line of code, call shuffle_cards() using deck from step 1. 3. Output "Deck: " followed by all cards in deck (each card is separated by a space) followed by a newline char. 4. Output an empty line. 5. Output "Drawing 3 cards... In". 6. In a single line of code, construct a local variable called hand passing the result of draw(3, deck) to it. 7. Output "Deck: " followed by all cards currently in deck (each card is separated by a space) followed by a newline char. 8. Output "Hand: " followed by all cards in hand (each card is separated by a space) followed by a newline char. 9. In a single line of code, construct a local variable with the result returned by calc_score(hand). 10. If the first and second score results are the same, then output "Score: " followed by the score and then a newline char. 11. Otherwise output "Possible Score: " followed by the low and high scores and then a newline char
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started