For some games I eventually want to program/play in, I want to create a framework that will roll dice in a number of different ways. For my test, I want a polyhedral dice structure, chosen as six for simplicity. The first roll is simply rolling the die and recording the number. The second roll is somewhat like that used in White Wolf's Storyteller system. Specifically, the computer will roll the die and return 1 if a 5 or 6 was rolled, -1 if a 1 was rolled, and 0 otherwise. The basic die structure I have is:
Code:
struct Basic_Die //state must be initialized before use
{
unsigned num_sides;
//unsigned (* roll_die) (struct Basic_Die *this, void * roll_params); //different rolling schemes
signed (* roll_die) (struct Basic_Die *this);
signed last_rolled;
};
The commented line for "different rolling" is one solution to my problem. A simple roll is accomplished with (assuming it compiles):
Code:
signed int basic_roll(struct Basic_Die *this) //changes state of *this
{
this->last_rolled = 1 + (rand() % this->num_sides); //this is noted as being a bad idea, but I am using this method for simplicity
return this->last_rolled; //return new value
}
This code works well with just the number of sides on the die. However, I have realized this scheme will not suffice for the "Storyteller" die roll.
Code:
signed int ww_roll_p5(struct Basic_Die *this) //changes state of *this, function like White Wolf's Storyteller rolls
{
int raw_roll = 1 + (rand() % this->num_sides);
if (raw_roll >= 5)
{
this->last_rolled = 1; /*Rolled high enough*/
}
else if (raw_roll == 1)
{
this->last_rolled = -1; /*Failed on this die*/
}
else
{
this->last_rolled = 0; /*No loss, no gain*/
}
return this->last_rolled;
}
The disadvantage clearly evident is the hard coded values for the different results e.g. greater than five. One solution I have thought of is passing an additional pointer to the roll_die() function. A second solution is to provide parameter storage in the Basic_Die structure. A third is encapsulating the Basic_Die in a different structure. For the second proposal, I could do a list of additional parameters, with minimal extra overhead. Which of these is the best option, or are there even better options not listed? I am programming in C.