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.

Leave a Reply

How to post code in comments?