patterncppMinor
Simplifying member functions in Blackjack game
Viewed 0 times
membergamesimplifyingfunctionsblackjack
Problem
For my display functions in my Blackjack game, I want to control each player's stats output based on whether a turn is in progress or has ended. Normally, you could only see one card that your opponent(s) hold, while the rest are only revealed at the end of each turn. My code does that well, but I'm having trouble making it more concise.
The display function in
How could I simplify this code to achieve the same output (shown below the code)?
Game.cpp
Player.cpp
```
void Player::displayPlayerStats() const
{
// always shown
std::stringstream ss;
std::cout << "\n* " << name << ": ";
std::cout << "($" << chips << ") ";
// displays two-digit card rank total (always shown)
if (totalCardsValue <= 9)
ss << "(0" << totalCardsValue << ") ";
else
ss << "(" << totalCardsValue << ") ";
std::cout << ss.str();
// displays human player's hand
playerHand[0].displayPlayerHand();
}
void Player::displayCPUStats(bool showResults) const
{
// always shown
std::stringstream ss;
std::cout << "\n* " << name <<
The display function in
Game is called to display each player's stats (name, chips, and hand). It takes a Boolean argument to determine if it should display each CPU's partial stats (during each turn) or full stats (after each turn). At the function call in Game, the bool argument is passed to the respective display function in Player, where the human player and CPU player have individual display procedures. The display functions in Player primarily display the chip amounts and card rank totals. They also call respective Hand display functions which, again, solely depend on the Boolean argument for displaying the CPUs' stats.How could I simplify this code to achieve the same output (shown below the code)?
Game.cpp
displayStats(false); // function call elsewhere in Game
void Game::displayStats(bool showCPUResults) const
{
players[0].displayPlayerStats(); // displays player stats
for (int i = 1; i < numPlrs; i++)
players[i].displayCPUStats(showCPUResults); // displays CPU stats
}Player.cpp
```
void Player::displayPlayerStats() const
{
// always shown
std::stringstream ss;
std::cout << "\n* " << name << ": ";
std::cout << "($" << chips << ") ";
// displays two-digit card rank total (always shown)
if (totalCardsValue <= 9)
ss << "(0" << totalCardsValue << ") ";
else
ss << "(" << totalCardsValue << ") ";
std::cout << ss.str();
// displays human player's hand
playerHand[0].displayPlayerHand();
}
void Player::displayCPUStats(bool showResults) const
{
// always shown
std::stringstream ss;
std::cout << "\n* " << name <<
Solution
If you want to make things more consice, you could change a few things:
-
Number of card printed on 2 digits:
could be written
or
-
No need for temporary
I think you could just
-
Removing duplicated code:
Corresponding code for Hand.cpp is:
-
Removing duplicated code: things can be changed in Player.cpp too as
Edited to finish my answer: Indeed,
Corresponding code for Player.cpp is:
-
Number of card printed on 2 digits:
if (totalCardsValue <= 9)
ss << "(0" << totalCardsValue << ") ";
else
ss << "(" << totalCardsValue << ") ";could be written
ss << ((totalCardsValue <= 9) ? "(0" : "(") << totalCardsValue << ") ";or
ss << "(" << std::setw(2) << std::setfill('0') << totalCardsValue << ") ";-
No need for temporary
std::stringstream.I think you could just
std::cout directly without using std::stringstream ss.-
Removing duplicated code:
void Hand::displayPlayerHand() does the same as void Hand::displayCPUHand(true). This would probably better if you were naming this method display and calling the parameter displayAllCards or displayOnlyFirst. Also, you might want to give it a default value. Corresponding code for Hand.cpp is:
void Hand::display(bool displayAllCards) const
{
// displays the first card
std::cout << cards[0] << " ";
// displays the rest of the cards if required
if (displayAllCards)
{
for (unsigned i = 1; i < cards.size(); i++)
std::cout << cards[i] << " ";
}
}-
Removing duplicated code: things can be changed in Player.cpp too as
Player::displayCPUStats and Player::displayPlayerStats really look alike.Edited to finish my answer: Indeed,
displayPlayerStats() is nothing but displayCPUStats(true). Here again, it might be worth changing the names of methods and variables.Corresponding code for Player.cpp is:
void Player::displayStats(bool displayAllCards) const
{
std::cout << "\n* " << name << ": ";
std::cout << "($" << chips << ") ";
if (displayAllCards)
{
std::cout << ((totalCardsValue <= 9) ? "(0" : "(") << totalCardsValue << ") ";
}
playerHand[0].displayHand(displayAllCards);
}Code Snippets
if (totalCardsValue <= 9)
ss << "(0" << totalCardsValue << ") ";
else
ss << "(" << totalCardsValue << ") ";ss << ((totalCardsValue <= 9) ? "(0" : "(") << totalCardsValue << ") ";ss << "(" << std::setw(2) << std::setfill('0') << totalCardsValue << ") ";void Hand::display(bool displayAllCards) const
{
// displays the first card
std::cout << cards[0] << " ";
// displays the rest of the cards if required
if (displayAllCards)
{
for (unsigned i = 1; i < cards.size(); i++)
std::cout << cards[i] << " ";
}
}void Player::displayStats(bool displayAllCards) const
{
std::cout << "\n* " << name << ": ";
std::cout << "($" << chips << ") ";
if (displayAllCards)
{
std::cout << ((totalCardsValue <= 9) ? "(0" : "(") << totalCardsValue << ") ";
}
playerHand[0].displayHand(displayAllCards);
}Context
StackExchange Code Review Q#24831, answer score: 5
Revisions (0)
No revisions yet.