My Dice objects in C++
Hey all.
I wrote some cool Dice objects in C++ and thought I would share them with the world.
Feed back is welcome. I was thinking of this going on any type of embedded device, phone, watch etc…so I used unsigned short int to save memory space. While in the personal computer world, memory is too abundant to worry about the difference between an int and a short, but in a futuristic wristwatch that is also a video phone might not have plenty of memory.
Die.h
//---------------------------------------------------------------------------
//
// Name: Die.h
// Author: Jared Barneck
// Created: 10/4/2009 7:54:40 PM
// Description: Die class declaration
// Copyright (R): Jared Barneck
//
//---------------------------------------------------------------------------
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#ifndef DIE_AS_IN_DICE
#define DIE_AS_IN_DICE
using namespace std;
class Die
{
public:
// Constructors
Die(unsigned short int inNumberOfSides = DEFAULT_NUMBER_OF_SIDES);
Die(unsigned short int inNumberOfSides, unsigned short int inStartNumber);
Die(unsigned short int inNumberOfSides, unsigned short int inStartNumber, unsigned short int inIncrementNumber);
Die(unsigned short int inNumberOfSides, unsigned short int inStartNumber, unsigned short int inIncrementNumber, bool inStoreHistory);
Die(bool inStoreHistory);
// Destructor
~Die();
// Accessor functions
unsigned short int getNumberOfSides();
unsigned short int getStartNumber();
unsigned short int getIncrementNumber();
unsigned short int getLastNumberRolled();
unsigned short int getMaxNumber();
vector<unsigned short int> * getHistory();
void setNumberOfSides(unsigned short int inNumberOfSides);
void setStartNumber(unsigned short int inStartNumber);
void setIncrementNumber(unsigned short int inIncrementNumber);
void enableStoreHistory(bool inStoreHistoryState);
// Standard functions
bool equals(Die * inDie);
Die * clone();
string toString();
// Other functions
unsigned short int roll();
void clearHistory();
// Public Members
int currentNumber;
protected:
// Private other functions
void initDie(unsigned short int inNumberOfSides, unsigned short int inStartNumber, unsigned short int inIncrementNumber, bool inStoreHistory);
string intToString(int inInt);
void initializeCounter();
// Private Members
int mNumberOfRolls;
unsigned short int mNumberOfSides;
unsigned short int mStartNumber;
unsigned short int mIncrementNumber;
bool mStoreHistory;
vector<unsigned short int> *mHistory; // Use this to store history of rolls.
vector<unsigned short int> *mCounter; // Stores the number of times each die value is rolled.
// Default values
static const unsigned short int DEFAULT_NUMBER_OF_SIDES = 6;
static const unsigned short int DEFAULT_START_NUMBER = 1;
static const unsigned short int DEFAULT_INCREMENT_NUMBER = 1;
static const bool DEFAULT_STORE_HISTORY = false;
};
#endif
Die.cpp
//---------------------------------------------------------------------------
//
// Name: Die.cpp
// Author: Jared Barneck
// Created: 10/4/2009 7:54:40 PM
// Description: Die class declaration
// Copyright (R): Jared Barneck
//
//---------------------------------------------------------------------------
#include "stdwx.h"
#include "Die.h"
// Constructors
Die::Die(unsigned short int inNumberOfSides)
{
initDie(inNumberOfSides, DEFAULT_START_NUMBER, DEFAULT_INCREMENT_NUMBER, DEFAULT_STORE_HISTORY);
}
// Future functions
Die::Die(unsigned short int inNumberOfSides, unsigned short int inStartNumber)
{
initDie(inNumberOfSides, inStartNumber, DEFAULT_INCREMENT_NUMBER, DEFAULT_STORE_HISTORY);
}
Die::Die(unsigned short int inNumberOfSides, unsigned short int inStartNumber, unsigned short int inIncrementNumber)
{
initDie(inNumberOfSides, inStartNumber, inIncrementNumber, DEFAULT_STORE_HISTORY);
}
Die::Die(unsigned short int inNumberOfSides, unsigned short int inStartNumber, unsigned short int inIncrementNumber, bool inStoreHistory)
{
initDie(inNumberOfSides, inStartNumber, inIncrementNumber, inStoreHistory);
}
Die::Die(bool inStoreHistory)
{
initDie(DEFAULT_NUMBER_OF_SIDES, DEFAULT_START_NUMBER, DEFAULT_INCREMENT_NUMBER, inStoreHistory);
}
// Destructor
Die::~Die()
{
mHistory->clear();
//delete mHistory;
mCounter->clear();
//delete mCounter;
}
// Accessor functions
unsigned short int Die::getNumberOfSides()
{
return mNumberOfSides;
}
unsigned short int Die::getStartNumber()
{
return mStartNumber;
}
unsigned short int Die::getIncrementNumber()
{
return mIncrementNumber;
}
unsigned short int Die::getLastNumberRolled()
{
return mHistory->at(mHistory->size() - 1);
}
unsigned short int Die::getMaxNumber()
{
return mStartNumber + ((mNumberOfSides - 1) * mIncrementNumber);
}
vector<unsigned short int> * Die::getHistory()
{
return mHistory;
}
void Die::setNumberOfSides(unsigned short int inNumberOfSides)
{
mNumberOfSides = inNumberOfSides;
}
void Die::setStartNumber(unsigned short int inStartNumber)
{
mStartNumber = inStartNumber;
}
void Die::setIncrementNumber(unsigned short int inIncrementNumber)
{
mIncrementNumber = inIncrementNumber;
}
void Die::enableStoreHistory(bool inStoreHistory)
{
mStoreHistory = inStoreHistory;
if (inStoreHistory)
{
initializeCounter();
}
else
{
delete mHistory;
delete mCounter;
}
}
// Standard functions
bool Die::equals(Die * inDie)
{
if (inDie->getNumberOfSides() == mNumberOfSides
&& inDie->getStartNumber() == mStartNumber
&& inDie->getIncrementNumber() == mIncrementNumber )
{
return true;
}
return false;
}
Die * Die::clone()
{
return new Die(mNumberOfSides, mStartNumber, mIncrementNumber, mStoreHistory);
}
string Die::toString()
{
string retVal;
retVal = "Sides=" + intToString(mNumberOfSides) + ";";
retVal += "Values=" + intToString(mStartNumber) + " thru ";
retVal += intToString((mNumberOfSides * mIncrementNumber) + (mStartNumber - 1));
retVal += " by increments of " + intToString(mIncrementNumber) + ";";
return retVal;
}
// Other functions
unsigned short int Die::roll()
{
mNumberOfRolls++;
//srand(mNumberOfRolls);
int currentNumber = rand() % mNumberOfSides + 1;
if (mStoreHistory)
{
mNumberOfRolls++;
mHistory->push_back(currentNumber);
mCounter->at(currentNumber)++;
}
return currentNumber;
}
void Die::clearHistory()
{
mHistory = new vector<unsigned short int>();
}
void Die::initDie(unsigned short int inNumberOfSides, unsigned short int inStartNumber, unsigned short int inIncrementNumber, bool inStoreHistory)
{
// Set Random seed
srand((int)time(0));
mNumberOfSides = inNumberOfSides;
mStartNumber = inStartNumber;
mIncrementNumber = inIncrementNumber;
mCounter = new vector<unsigned short int>();
mHistory = new vector<unsigned short int>();
enableStoreHistory(inStoreHistory);
}
string Die::intToString(int inInt)
{
stringstream ss;
string s;
ss << inInt;
s = ss.str();
return s;
}
void Die::initializeCounter()
{
for (int i = 0; i <= getMaxNumber(); i++)
{
mCounter->push_back(0);
}
}
SetOfDice.h
//---------------------------------------------------------------------------
//
// Name: SetOfDice.h
// Author: Jared Barneck
// Created: 10/4/2009 7:54:40 PM
// Description: Die class declaration
// Copyright (R): Jared Barneck
//
//---------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
#include "Die.h"
#ifndef SET_OF_DICE_
#define SET_OF_DICE_
using namespace std;
class SetOfDice
{
public:
// Constructors
/*
* This Constructor creates a new SetOfDice object using the defaults, 2 dice with 6 sides each valuing between
* 1 and 6.
*/
SetOfDice();
/*
* This Constructor takes the die passed in and clones it, so the total number of dice equals the default number
* of dice or 2. If the die does not have history enabled, it will enable it before cloning occurs.
*/
SetOfDice(Die * inDie);
/*
* This Constructor takes the die passed in and clones as many times as needed so that the total number of dice
* equals the inNumberOfDice value.
*/
SetOfDice(Die * inDie, unsigned short int inNumberOfDice);
/*
* This Constructor takes integer passed in and creates new die objects using default values so the total number
* of dice equals the inNumberOfDice value.
*/
SetOfDice(unsigned short int inNumberOfDice);
// Destructor
~SetOfDice();
// Accessor functions
/*
* Returns the die at the index provided. Indexes start at 0 not 1.
*/
int getNumberOfDice();
/*
* Returns the die at the index provided. Indexes start at 0 not 1.
*/
Die * getDie(unsigned short int inDieIndex);
/*
* This function adds a die to the SetOfDice. If all the dice are the same type of dice, it adds another of the
* same type. However, if the there are different dice sizes, it adds a default dice. It also clears history as
* adding a new die means there is nohistory since the die has been added.
*/
void addDie();
// Standard functions
/*
* This function adds the die to the SetOfDice. It also clears history as adding a new die means there is no
* history since the die has been added.
*/
void addDie(Die * inDie);
/*
* This function enables the Store History where the dice store the results of all rolls during their lifetime.
*/
void enableStoreHistory(bool inStoreHistoryState);
/*
* This function returns the smallest possible value.
*/
unsigned short int getSmallestPossibleValue();
/*
* This function returns the greatest possible value.
*/
unsigned short int getGreatestPossibleValue();
/*
* This function returns the amount of times a certain number was rolled. History must be enabled.
*/
unsigned short int getCountThatNumberWasRolled(unsigned short int inNumber);
// Other functions
/*
* This rolls all the dice and returns the sum of dice rolled.
*/
unsigned short int rollAllDice();
/*
* This rolls the die and returns the result.
*/
unsigned short int rollSingleDice(unsigned short int inDiceIndex);
/*
* This clears all the history.
*/
void clearHistory();
/*
* This returns the statistics in a tabular format.
*/
string getStats();
private:
// Private functions
void createSetOfDie(Die * inDie, unsigned short int inNumberOfDice);
string intToString(unsigned short int inInt);
void initializeCounter();
template < class T> void deleteVectorOfPointers(T * inT);
// Members
vector<Die*> *mDice;
vector<unsigned short int> *mHistory; // Use this to store history of rolls.
vector<unsigned short int> *mCounter; // Stores the number of times each die value is rolled.
bool mStoreHistory;
// Default values
static const unsigned short int DEFAULT_NUMBER_OF_DICE = 2;
static const bool DEFAULT_STORE_HISTORY = true;
};
#endif
SetOfDice.cpp
//---------------------------------------------------------------------------
//
// Name: SetOfDice.cpp
// Author: Jared Barneck
// Created: 10/4/2009 7:54:40 PM
// Description: Die class declaration
// Copyright (R): Jared Barneck
//
//---------------------------------------------------------------------------
#include "stdwx.h"
#include "SetOfDice.h"
/*
* This Constructor creates a new SetOfDice object using the defaults, 2 dice with 6 sides each valuing between
* 1 and 6.
*/
SetOfDice::SetOfDice()
{
mStoreHistory = DEFAULT_STORE_HISTORY;
createSetOfDie(new Die(mStoreHistory), 2);
enableStoreHistory(mStoreHistory);
}
/*
* This Constructor takes the die passed in and clones it, so the total number of dice equals the default number
* of dice or 2. If the die does not have history enabled, it will enable it before cloning occurs.
*/
SetOfDice::SetOfDice(Die * inDie)
{
mStoreHistory = DEFAULT_STORE_HISTORY;
inDie->enableStoreHistory(mStoreHistory);
createSetOfDie(inDie, 2);
enableStoreHistory(mStoreHistory);
}
/*
* This Constructor takes the die passed in and clones as many times as needed so that the total number of dice
* equals the inNumberOfDice value.
*/
SetOfDice::SetOfDice(Die * inDie, unsigned short int inNumberOfDice)
{
mStoreHistory = DEFAULT_STORE_HISTORY;
inDie->enableStoreHistory(mStoreHistory);
createSetOfDie(inDie, inNumberOfDice);
enableStoreHistory(mStoreHistory);
}
/*
* This Constructor takes integer passed in and creates new die objects using default values so the total number
* of dice equals the inNumberOfDice value.
*/
SetOfDice::SetOfDice(unsigned short int inNumberOfDice)
{
mStoreHistory = DEFAULT_STORE_HISTORY;
createSetOfDie(new Die(mStoreHistory), inNumberOfDice);
enableStoreHistory(mStoreHistory);
}
// Destructor
SetOfDice::~SetOfDice()
{
deleteVectorOfPointers(mDice);
mCounter->clear();
delete mCounter;
mHistory->clear();
delete mHistory;
}
// Accessor functions
/*
* Returns the die at the index provided. Indexes start at 0 not 1.
*/
int SetOfDice::getNumberOfDice()
{
return mDice->size();
}
/*
* Returns the die at the index provided. Indexes start at 0 not 1.
*/
Die * SetOfDice::getDie(unsigned short int inDieIndex)
{
return mDice->at(inDieIndex);
}
/*
* This function adds a die to the SetOfDice. If all the dice are the same type of dice, it adds another of the
* same type. However, if the there are different dice sizes, it adds a default dice. It also clears history as
* adding a new die means there is nohistory since the die has been added.
*/
void SetOfDice::addDie()
{
bool AllDiceAreEqual = true;
for (unsigned short int i = 1; i < mDice->size(); i++)
{
if (! (mDice->at(0)->equals(mDice->at(i))))
{
AllDiceAreEqual = false;
}
}
if (AllDiceAreEqual)
{
mDice->push_back(mDice->at(0)->clone());
}
else
{
mDice->push_back(new Die(mStoreHistory));
}
}
// Standard functions
/*
* This function adds the die to the SetOfDice. It also clears history as adding a new die means there is no
* history since the die has been added.
*/
void SetOfDice::addDie(Die * inDie)
{
mDice->push_back(inDie);
}
/*
* This function enables the Store History where the dice store the results of all rolls during their lifetime.
*/
void SetOfDice::enableStoreHistory(bool inStoreHistory)
{
mStoreHistory = inStoreHistory;
for (unsigned short int i = 0; i < mDice->size(); i++)
{
mDice->at(i)->enableStoreHistory(inStoreHistory);
}
if (inStoreHistory)
{
mHistory = new vector<unsigned short int>();
}
else
{
delete mHistory;
}
}
/*
* This function returns the smallest possible value.
*/
unsigned short int SetOfDice::getSmallestPossibleValue()
{
unsigned short int retVal = 0;
for (unsigned short int i = 0; i < mDice->size(); i++)
{
retVal += mDice->at(i)->getStartNumber();
}
return retVal;
}
/*
* This function returns the greatest possible value.
*/
unsigned short int SetOfDice::getGreatestPossibleValue()
{
unsigned short int retVal = 0;
for (unsigned short int i = 0; i < mDice->size(); i++)
{
retVal += mDice->at(i)->getMaxNumber();
}
return retVal;
}
/*
* This function returns the greatest possible value.
*/
unsigned short int SetOfDice::getCountThatNumberWasRolled(unsigned short int inNumber)
{
return mCounter->at(inNumber);
}
// Other functions
/*
* This rolls all the dice and returns the sum of dice rolled.
*/
unsigned short int SetOfDice::rollAllDice()
{
int retVal = 0;
for (unsigned short int i = 0; i < mDice->size(); i++)
{
retVal += mDice->at(i)->roll();
}
if (mStoreHistory)
{
mHistory->push_back(retVal);
mCounter->at(retVal)++;
}
return retVal;
}
/*
* This rolls the die and returns the result. Indexes start at 0 not 1.
*/
unsigned short int SetOfDice::rollSingleDice(unsigned short int inDiceIndex)
{
return mDice->at(inDiceIndex)->roll();
}
/*
* This clears all the history.
*/
void SetOfDice::clearHistory()
{
for (unsigned short int i = 0; i < mDice->size(); i++)
{
mDice->at(i)->clearHistory();
}
}
/*
* This returns the statistics in a tabular format.
*/
string SetOfDice::getStats()
{
int tab1 = 8;
int tab2 = 8;
int tab3 = 12;
stringstream ss;
ss << endl;
ss << "Total number of rolls: " << mDice->at(0)->getHistory()->size() << endl;
ss << endl;
ss << setw(tab1) << "Number" << setw(tab2) << "Count" << setw(tab3) << "% Percent" << endl;
ss << setw(tab1) << "------" << setw(tab2) << "-----" << setw(tab3) << "---------" << endl;
for (int i = getSmallestPossibleValue(); i <= getGreatestPossibleValue(); i++)
{
double percent = (double)getCountThatNumberWasRolled(i) / (double)mDice->at(0)->getHistory()->size() * 100;
ss << setw(tab1) << i;
ss << setw(tab2) << getCountThatNumberWasRolled(i);
ss << setw(tab3-2) << setprecision(2) << fixed << percent << setw(2) << "%";
ss << endl;
}
ss << endl;
return ss.str();
}
void SetOfDice::createSetOfDie(Die * inDie, unsigned short int inNumberOfDice)
{
mDice = new vector<Die*>();
mDice->push_back(inDie);
for (int i = 1; i < inNumberOfDice; i++ ) // i starts at one because we already have a die
{
mDice->push_back(inDie->clone());
}
initializeCounter();
}
string SetOfDice::intToString(unsigned short int inInt)
{
stringstream ss;
string s;
ss << inInt;
s = ss.str();
return s;
}
void SetOfDice::initializeCounter()
{
mCounter = new vector<unsigned short int>();
for (int i = 0; i <= getGreatestPossibleValue(); i++)
{
mCounter->push_back(0);
}
}
/*
* Pointer deleter for a vector of pointers
*/
template < class T > void SetOfDice::deleteVectorOfPointers( T * inVectorOfPointers )
{
T::iterator i;
for ( i = inVectorOfPointers->begin() ; i < inVectorOfPointers->end(); i++ )
{
delete * i;
}
delete inVectorOfPointers;
}
Please feel free to give any feed back and/or recommendations.
If you would like to use these dice in your code, make sure to get my permission and there is a good chance I won’t charge you unless you are are making money of it yourself.

