Example File: AGameOfTwentyone.7z
Dice.h
#ifndef DICE_H_
#define DICE_H_
#include <string>
using std::string;
#include <vector>
using std::vector;
class Dice
{
private:
const int MIN_VALUE = 1; // The lowest die value
const int NUM_DICE = 2; // The number of dice
const int DIE_SIDES = 6; // The number of die sides
const int NUMELS = 5; // The number of elements in a row of the diceGfx 2D-vector
vector<vector<string>> diceGfx; // Holding a graphic representation of a die
vector<int> diceValues = {}; // Holding the dice values
public:
Dice();
void seedRng();
void roll();
void outputDice();
vector<int> getDiceValues() const
{ return diceValues; }
};
#endif
Dice.cpp
#include "Dice.h"
#include <cstdlib>
#include <ctime>
#include <iomanip>
using std::setw;
#include <iostream>
using std::cout;
/* **********************************************************
Dice::Dice()
This constructor, via initializer-list, initializes the
diceValues vector and the diceGfx vector of vectors.
********************************************************** */
Dice::Dice() : diceValues { 0, 0 },
diceGfx { {},
{ "+-----+", "| |", "| O |", "| |", "+-----+" },
{ "+-----+", "| O |", "| |", "| O |", "+-----+" },
{ "+-----+", "| O |", "| O |", "| O |", "+-----+" },
{ "+-----+", "| O O |", "| |", "| O O |", "+-----+" },
{ "+-----+", "| O O |", "| O |", "| O O |", "+-----+" },
{ "+-----+", "| O O |", "| O O |", "| O O |", "+-----+" } }
{
seedRng();
}
/* **********************************************************
Dice::seedRng()
This function seeds the random number generator.
********************************************************** */
void Dice::seedRng()
{
srand(static_cast<unsigned int> (time(0)));
}
/* **********************************************************
Dice::roll()
This function simulates the rolling of two dice. When it
is called, the diceValues vector is cleared, the roll of
n-number of dice is simulated, and the values are pushed
back into the vector.
********************************************************** */
void Dice::roll()
{
diceValues.clear();
for (int i = 0; i < NUM_DICE; i++)
{
diceValues.push_back((rand() % DIE_SIDES - MIN_VALUE + 1) + MIN_VALUE);
}
}
/* **********************************************************
Dice::outputDice()
This function outputs the dice to screen.
********************************************************** */
void Dice::outputDice()
{
cout << "\n";
for (int i = 0; i < NUMELS; ++i)
{
for (int j = 0; j < NUM_DICE; ++j)
{
cout << setw(12) << diceGfx[getDiceValues()[j][i] << setw(17);
}
cout << "\n";
}
cout << "\n";
}
Player.h
#ifndef PLAYER_H_
#define PLAYER_H_
#include <string>
using std::string;
class Player
{
private:
string playerName; // The players' name
int roundScore; // The players' round score
int finalScore; // The players' final score
int highScore; // The players' highscore
public:
Player();
void setPlayerName();
bool isPlayerName(string);
void addRoundScore(int score)
{ roundScore += score; }
void addFinalScore()
{ finalScore = roundScore; }
void setHighscore(int high)
{ highScore += high; }
void resetScore()
{
roundScore = 0;
finalScore = 0;
}
string getPlayerName() const
{ return playerName; }
int getRoundScore() const
{ return roundScore; }
int getFinalScore() const
{ return finalScore; }
int getHighscore() const
{ return highScore; }
};
#endif
Player.cpp
#include "Player.h"
#include <iostream>
using std::cout;
using std::cin;
/* **********************************************************
Player::Player() - Default constructor
********************************************************** */
Player::Player()
{
playerName = "Player One";
roundScore = 0;
finalScore = 0;
highScore = 0;
}
/* **********************************************************
Player::setPlayerName()
This function asks the player to enter his or her name.
********************************************************** */
void Player::setPlayerName()
{
string tempName = "";
cout << "\nAs you enter the ISN-RADIO BAR backroom, you notice, that the room is\n"
<< "almost empty, except for one person sitting behind a table, playing some\n"
<< "sort of game with dice. As you approach the table, he looks up and greets\n"
<< "you.\n\n";
cout << "Aah, finally! I've been waiting all evening for a player to show up!\n"
<< "My name's Jack Black. Call me Jack, if you like. And what is your name?\n\n";
cout << "You tell him, that he can call you: ";
cin.ignore();
getline(cin, tempName);
while (isPlayerName(tempName) == false)
{
getline(cin, tempName);
}
}
/* **********************************************************
Player::isPlayerName()
This function validates the players input.
********************************************************** */
bool Player::isPlayerName(string tempName)
{
if (tempName.empty() || tempName.at(0) == ' ')
{
cout << "\nSorry, but I did not get your name.\n"
<< "Could you repeat it please? ";
return false;
}
else
{
playerName = tempName;
return true;
}
return false;
}
Dealer.h
#ifndef DEALER_H_
#define DEALER_H_
#include <string>
using std::string;
class Dealer
{
private:
string dealerName; // The dealers' name
int roundScore; // The dealers' round score
int finalScore; // The dealers' final score
int highScore; // The dealers' highscore
public:
Dealer()
{
dealerName = "Jack Black";
roundScore = 0;
finalScore = 0;
}
void addRoundScore(int score)
{ roundScore += score; }
void addFinalScore()
{ finalScore = roundScore; }
void setHighscore(int high)
{ highScore += high; }
void resetScore()
{
roundScore = 0;
finalScore = 0;
}
string getDealerName() const
{ return dealerName; }
int getRoundScore() const
{ return roundScore; }
int getFinalScore() const
{ return finalScore; }
int getHighscore() const
{ return highScore; }
};
#endif
Game.h
#ifndef GAME_H_
#define GAME_H_
#include "Dice.h"
#include "Dealer.h"
#include "Player.h"
class Game
{
private:
enum Choice { ROLL = 'R', HOLD = 'H' };
enum Highscore { BLACK_JACK = 21, WIN = 2 };
const int MAX_SCORE = 21;
bool isPlayerTurn;
bool isDealerTurn;
bool isGameOver;
char choice;
int score;
Dice dice;
Player player;
Dealer dealer;
public:
Game();
void run();
void setup();
void resetGame();
void giveChoice();
void firstTurn();
void playerTurn();
void dealerTurn();
void switchPlayers();
void calcScore();
bool isWin();
bool isWinDealer();
void displayScoreboard();
void displayHighscore();
char getChoice() const
{ return toupper(choice); }
bool getTurnStateDealer() const
{ return isDealerTurn; }
bool getTurnStatePlayer() const
{ return isPlayerTurn; }
int getScore() const
{ return score; }
bool getGameState() const
{ return isGameOver; }
};
#endif
Game.cpp
#include "Game.h"
#include <iomanip>
using std::setw;
#include <iostream>
using std::cin;
using std::cout;
/* **********************************************************
Game::Game() - Default constructor
********************************************************** */
Game::Game()
{
isDealerTurn = true;
isGameOver = false;
}
/* **********************************************************
Game::setup()
This function makes a call to the player class, allowing
the player to enter his or her player name.
********************************************************** */
void Game::setup()
{
player.setPlayerName();
}
/* **********************************************************
Game::run()
This function represents the main gameloop. Upon entry, a
call to the firstTurn function is made, the players are
switched, and the players turn begins. If he or she or
the artificial dealer wins or loses, the game is over, and
the player asked, if he or she wishes to play again.
********************************************************** */
void Game::run()
{
char again = ' ';
do
{
firstTurn();
playerTurn();
if (getGameState() == false)
{
switchPlayers();
dealerTurn();
}
if (getGameState() == true)
{
cout << "Do you wish to play another round? ";
cin >> again;
while (toupper(again) != 'Y' && toupper(again) != 'N')
{
cout << "Do you wish to play another round? ";
cin >> again;
}
if (toupper(again) == 'Y')
{
resetGame();
}
}
} while (getGameState() == false);
}
/* **********************************************************
Game::switchPlayer()
This function switches dealer and player. If one is active
the other is set to false, and vice versa.
********************************************************** */
void Game::switchPlayers()
{
if (getTurnStateDealer() == true)
{
isDealerTurn = false;
isPlayerTurn = true;
}
else
{
isPlayerTurn = false;
isDealerTurn = true;
}
}
/* **********************************************************
Game::firstTurn()
This function simulates the first turn for both dealer and
player. After rolling the dice a score is calculated, and
the result is passed to the appropriate member function of
the dealer or player class.
********************************************************** */
void Game::firstTurn()
{
dice.roll();
calcScore();
dealer.addRoundScore(getScore());
switchPlayers();
dice.roll();
calcScore();
player.addRoundScore(getScore());
}
/* **********************************************************
Game::displayScoreboard()
This function outputs the dealer and player score.
********************************************************** */
void Game::displayScoreboard()
{
if (getTurnStateDealer() == true)
{
cout << dealer.getDealerName() << "'s Score: "
<< dealer.getRoundScore() << " \n\n";
}
else
{
cout << player.getPlayerName() << "'s Score: "
<< player.getRoundScore() << " \n\n";
}
}
/* **********************************************************
Game::playerTurn()
This function represents the players' turn. The player is
given a choice to roll or hold. A player is able to roll
the dice as long as no winning condition is met. If the
player decides to 'H'old, which is possible at any time,
his or her turn is over, his or her final score is set,
and the function exits.
********************************************************** */
void Game::playerTurn()
{
cout << "\n" << player.getPlayerName() << "'s Turn\n";
displayScoreboard();
do
{
giveChoice();
if (getChoice() == ROLL)
{
dice.roll();
dice.outputDice();
calcScore();
player.addRoundScore(getScore());
displayScoreboard();
}
if (getChoice() == HOLD)
{
cout << "\n" << player.getPlayerName() << " Stands!\n"
<< player.getPlayerName() << "'s Turn is over ...\n\n";
player.addFinalScore();
}
} while (isWin() == false && getChoice() != HOLD);
}
/* **********************************************************
Game::giveChoice()
This function asks the player during his or her turn, if
they wish to roll or hold. The input is validated.
********************************************************** */
void Game::giveChoice()
{
cout << "Do you wish to [R]oll or [H]old? ";
cin >> choice;
while (getChoice() != ROLL && getChoice() != HOLD)
{
cout << "Do you wish to [R]oll or [H]old? ";
cin >> choice;
}
}
/* **********************************************************
Game::dealerTurn()
This function represents the dealers' turn. The dice are
rolled, the score calculated and passed to the appropriate
member function of the dealer class, until a general or a
specific winning condition unique to the dealer is met.
********************************************************** */
void Game::dealerTurn()
{
cout << "\n" << dealer.getDealerName() << "'s Turn\n";
displayScoreboard();
do
{
dice.roll();
dice.outputDice();
calcScore();
dealer.addRoundScore(getScore());
displayScoreboard();
} while (isWin() == false && isWinDealer() == false);
}
/* **********************************************************
Game::calcScore()
This function calculates and passes the score achieved to
either the dealer or player classes member function.
********************************************************** */
void Game::calcScore()
{
score = 0;
for (auto points : dice.getDiceValues())
{
score += points;
}
}
/* **********************************************************
Game::isWin()
This function evaluates the basic winning conditions of
this game. If a winning or losing condition is met, the
winner or loser is announced, the isGameOver condition is
set to true und is returned from the function.
********************************************************** */
bool Game::isWin()
{
if (player.getRoundScore() == MAX_SCORE || dealer.getRoundScore() == MAX_SCORE)
{
cout << "BLACK JACK!\n";
if (player.getRoundScore() == MAX_SCORE)
{
cout << player.getPlayerName() << " Wins!\n\n";
player.setHighscore(BLACK_JACK);
}
else
{
cout << dealer.getDealerName() << " Wins!\n\n";
dealer.setHighscore(BLACK_JACK);
}
return isGameOver = true;
}
if (player.getRoundScore() > MAX_SCORE || dealer.getRoundScore() > MAX_SCORE)
{
if (player.getRoundScore() > MAX_SCORE)
{
cout << player.getPlayerName() << " Busts ...\n"
<< dealer.getDealerName() << " Wins!\n\n";
dealer.setHighscore(WIN);
}
else
{
cout << dealer.getDealerName() << " Busts ...\n"
<< player.getPlayerName() << " Wins!\n\n";
player.setHighscore(WIN);
}
return isGameOver = true;
}
return isGameOver = false;
}
/* **********************************************************
Game::isWin()
This function evaluates additional winnings conditions,
specific to the dealer.
********************************************************** */
bool Game::isWinDealer()
{
if (dealer.getRoundScore() > player.getFinalScore())
{
cout << dealer.getDealerName() << " Wins!\n";
dealer.setHighscore(WIN);
return isGameOver = true;
}
else if (dealer.getRoundScore() == player.getFinalScore())
{
cout << "DRAW!\n\n";
return isGameOver = true;
}
return isGameOver = false;
}
void Game::displayHighscore()
{
cout << "\n" << setw(23) << "HIGHSCORE LIST\n\n";
cout << setw(15) << dealer.getDealerName() << setw(20) << dealer.getHighscore() << "\n"
<< setw(15) << player.getPlayerName() << setw(20) << player.getHighscore() << "\n";
}
/* **********************************************************
Game::isWin()
This function evaluates additional winnings conditions,
specific to the dealer.
********************************************************** */
void Game::resetGame()
{
isGameOver = false;
isDealerTurn = true;
dealer.resetScore();
player.resetScore();
}
Example Output: