I am learning C++ and I took on this small project to get more familiar with OOP. The goal was to create a Die class that randomly rolls and returns a value based on the sides of the die, the number of dice rolled, and any added modifiers, (ex: +2).
Die.hpp:
#pragma once
#include <random> //std::random_device, std::mt19937, std::uniform_real_distribution
class Die
{
private:
int m_sides; //Number of sides on dice
int m_num; //Number of dice to roll
int m_mod; //Modifiers that add/sub to overall value
int m_val; //The die's value when rolled
static const int sc_MIN_VAL = 1; //Static constant for minimum value of a die roll
static const int sc_MIN_SIDES = 2; //Static constant for minimum sides of a die, 2 sides = coinflip
static const int sc_MIN_NUM = 1; //Static constant for minimum number of dice, must be >= 1
inline static std::random_device s_rd; //Static random seed
inline static std::mt19937 s_engine; //Static random number generator engine (mt19937) seeded with std::random_device
std::uniform_int_distribution<int> m_dist; //Uniform int distribution for each die instance, based on number of sides
public:
Die(); //Constructor #0: Default Constructor, no parameters
Die(int); //Constructor #1: Dice(sides)
Die(int, int); //Constructor #2: Dice(sides, number of dice)
Die(int, int, int); //Constructor #3: Delegated Constructor - Dice(sides, number of dice, modifiers)
int roll(); //Perform a random dice roll with mt19937 engine, return m_val value of roll
void setSides(int); //Change the number of sides of the die
void setNumber(int); //Change the number of dice rolled
void setModifier(int m) {m_mod = m;} //Change modifier added to the dice roll
int getSides() const {return m_sides;} //Returns number of sides of the die
int getNumber() const {return m_num;} //Returns number of dice being rolled at once
int getModifier() const {return m_mod;} //Returns modifier being added to dice roll value
};
Die.cpp:
#include "Die.hpp"
//Random Number Generator
std::random_device s_rd;
std::mt19937 s_engine(s_rd());
//Constructor #0: Default Constructor
Die::Die() : Die(6, 1, 0) {}
//Constructor #1
Die::Die(int s) : Die(s, 1, 0) {}
//Constructor #2
Die::Die(int s, int n) : Die(s, n, 0) {}
//Constructor #3: Delegated Constructor
Die::Die(int s, int n, int m)
: m_sides(s), m_num(n), m_mod(m), m_dist(sc_MIN_VAL, s)
{
//Exception Handling
if(m_sides < sc_MIN_SIDES)
m_sides = sc_MIN_SIDES;
if(m_num < sc_MIN_NUM)
m_num = sc_MIN_NUM;
}
//Main method: returns int value of dice roll sums + modifier
int Die::roll()
{
//reset m_val to hold new roll value
m_val = 0;
//Generate value for dice rolls
for(int i = 0; i < m_num; i++)
{
m_val += m_dist(s_engine);
}
//Add modifiers to value, then return m_val
return m_val += m_mod;
}
//Setters
void Die::setSides(int s)
{
if(s < sc_MIN_SIDES) //if sides was set to an impossible value less than 2
m_sides = sc_MIN_SIDES; //set to minimum # of sides, 2
else m_sides = s; //set normally if value is >= 2
//Update distribution for random num generator, so that it doesn't become stale
std::uniform_int_distribution<int>::param_type p(sc_MIN_VAL, m_sides);
m_dist.param(p);
}
void Die::setNumber(int n)
{
if(n < sc_MIN_NUM) //if number of dice was set to an impossible value less than 1
m_num = sc_MIN_NUM; //set to minimum # of dice, 1
else m_num = n; //set normally if value is >= 1
}