543 lines
16 KiB
C++
543 lines
16 KiB
C++
/*
|
|
Program Name: Character Sheet Creator
|
|
Process: shows a menu when executed, asks the user for a lot of information
|
|
about their character, records it, and then saves it to a file.
|
|
includes a new version of my previous dice roller program to introduce
|
|
a OOP structure.
|
|
Function Input/Parameters: ???
|
|
Function Output/Parameters: ???
|
|
Function Output/Returned: ???
|
|
Device Input/Device: ???
|
|
Device Output/Monitor: ???
|
|
Dependencies: ???
|
|
*/
|
|
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <cstring>
|
|
#include <list>
|
|
#include <set>
|
|
#include <unordered_map>
|
|
#include <time.h>
|
|
|
|
using namespace std;
|
|
|
|
// Function Prototypes
|
|
int addDiceList(list<int> inputList);
|
|
void displayDiceList(list<int> inputList);
|
|
|
|
// enum values for menu
|
|
typedef enum
|
|
{
|
|
QUIT_CHARACTER_CREATOR = -1,
|
|
ROLL_DICE_NOTATION,
|
|
ROLL_DICE_NO_MOD,
|
|
ROLL_DICE_MOD,
|
|
SET_GAMEMODE,
|
|
START_CHARACTER_CREATOR
|
|
} MENU_OPTIONS;
|
|
|
|
typedef enum
|
|
{
|
|
PRE_ADD_MODIFIER = 0,
|
|
POST_ADD_MODIFIER
|
|
} GAME_OPTIONS;
|
|
|
|
class Dice
|
|
{
|
|
//
|
|
public:
|
|
Dice(string diceRollString)
|
|
{
|
|
// this will have the format of XdY[+N]
|
|
// parse dice, checking to make sure it obeys the rule XdY.
|
|
// find the 'd' character within the string, then get the substring from 0 - pos of 'd'
|
|
numDice = stoi(diceRollString.substr(0, diceRollString.find('d')));
|
|
// check to see if there is a modifier
|
|
if ((diceRollString.find('+')) != string::npos)
|
|
{
|
|
// set the number of dice faces
|
|
numFace = stoi(diceRollString.substr(diceRollString.find('d') + 1, diceRollString.find('+') + 1));
|
|
// set the modifer for each roll
|
|
modifier = stoi(diceRollString.substr(diceRollString.find('+') + 1));
|
|
}
|
|
else
|
|
{
|
|
// set the number of dice faces
|
|
numFace = stoi(diceRollString.substr(diceRollString.find('d') + 1));
|
|
// no modfier
|
|
modifier = 0;
|
|
}
|
|
}
|
|
Dice(int numDice, int numFace)
|
|
{
|
|
// this will allow for a number of dice and sides to be input
|
|
numDice = numDice;
|
|
numFace = numFace;
|
|
// no modifier
|
|
modifier = 0;
|
|
}
|
|
Dice(int numDice, int numFace, int modifier)
|
|
{
|
|
// this will improve on the last constructor with an added modifier
|
|
numDice = numDice;
|
|
numFace = numFace;
|
|
modifier = modifier;
|
|
}
|
|
|
|
private:
|
|
int numDice;
|
|
int numFace;
|
|
int modifier;
|
|
int diceRoll;
|
|
list<int> rolledDiceList;
|
|
int rolledDiceListSize;
|
|
list<int> rolledDiceListMod;
|
|
void setNumDice(int diceAmount)
|
|
{
|
|
// set the number of dice to the specified amount
|
|
numDice = diceAmount;
|
|
}
|
|
int getNumDice()
|
|
{
|
|
// return the number of dice to the user/programmer
|
|
return numDice;
|
|
}
|
|
void setNumFace(int diceFaces)
|
|
{
|
|
// set the number of faces to the specified amount
|
|
numFace = diceFaces;
|
|
}
|
|
int getNumFace()
|
|
{
|
|
// return the number of faces to the user/programmer
|
|
return numFace;
|
|
}
|
|
void setModifier(int mod)
|
|
{
|
|
// set the modifier to the specified amount
|
|
modifier = mod;
|
|
}
|
|
int getModifier()
|
|
{
|
|
// return the modifier to the user/programmer
|
|
return modifier;
|
|
}
|
|
void rollDice(GAME_OPTIONS gameModeSel)
|
|
{
|
|
// use the previous code I've baked up to 'roll dice'
|
|
int rolledDice = 0;
|
|
int diceIterator;
|
|
int temp = 0;
|
|
// roll the dice numDice number of times with the correct range
|
|
for (diceIterator = 0; diceIterator < numDice; diceIterator++)
|
|
{
|
|
// roll the dice, add to the list
|
|
rolledDice = 1 + (rand() % numFace);
|
|
rolledDiceList.push_back(rolledDice);
|
|
}
|
|
// sort the list
|
|
rolledDiceList.sort();
|
|
// reverse the list
|
|
rolledDiceList.reverse();
|
|
// check game mode
|
|
if (gameModeSel == PRE_ADD_MODIFIER)
|
|
{
|
|
rolledDiceListSize = rolledDiceList.size();
|
|
// if PRE_MODIFIER
|
|
// iterate through the list, copy element, place in new list.
|
|
for (diceIterator = 0; diceIterator < rolledDiceListSize; diceIterator++)
|
|
{
|
|
// add the modifier to each roll
|
|
rolledDiceListMod.push_back(rolledDiceList.front() + modifier);
|
|
rolledDiceList.pop_front();
|
|
}
|
|
// display the list to user
|
|
// display once in reverse sorted order (advantage mode)
|
|
printf("High-Low Dice List: ");
|
|
displayDiceList(rolledDiceListMod);
|
|
// display once in sorted order (disadvantage mode) [make sure to reverse here since it will be in reverse order]
|
|
rolledDiceListMod.reverse();
|
|
printf("Low-High Dice List: ");
|
|
displayDiceList(rolledDiceListMod);
|
|
// add the list in total, display total of list
|
|
addDiceList(rolledDiceListMod);
|
|
// show the highest roll
|
|
cout << "Highest Roll: " << rolledDiceListMod.front() << endl;
|
|
// show the lowest roll
|
|
cout << "Lowest Roll: " << rolledDiceListMod.back() << endl;
|
|
}
|
|
else
|
|
{
|
|
// if POST_MODIFIER
|
|
// add the list in total, add the modifier once
|
|
// display total of list
|
|
rolledDiceListSize = rolledDiceList.size();
|
|
// iterate through the list, copy element, place in new list.
|
|
for (diceIterator = 0; diceIterator < rolledDiceListSize; diceIterator++)
|
|
{
|
|
// add the modifier to each roll
|
|
rolledDiceListMod.push_back(rolledDiceList.front() + modifier);
|
|
rolledDiceList.pop_front();
|
|
}
|
|
//
|
|
temp = addDiceList(rolledDiceListMod);
|
|
printf("High-Low Dice List: ");
|
|
displayDiceList(rolledDiceListMod);
|
|
temp = temp + modifier;
|
|
printf("Battle Roll: %d\n", temp);
|
|
}
|
|
}
|
|
// void getDiceRoll()
|
|
// {
|
|
// //
|
|
// }
|
|
};
|
|
|
|
class Character
|
|
{
|
|
//
|
|
public:
|
|
Character()
|
|
{
|
|
// character initialization
|
|
characterName = "HUMAN";
|
|
characterLevel = 1;
|
|
experiencePoints = 0;
|
|
statMap["STRENGTH"] = 10;
|
|
statMap["DEXTERITY"] = 10;
|
|
statMap["CONSTITUTION"] = 10;
|
|
statMap["INTELLIGENCE"] = 10;
|
|
statMap["WISDOM"] = 10;
|
|
statMap["CHARISMA"] = 10;
|
|
}
|
|
Character(string characterName)
|
|
{
|
|
// character initialization, character name only.
|
|
characterName = characterName;
|
|
characterLevel = 1;
|
|
experiencePoints = 0;
|
|
statMap["STRENGTH"] = 10;
|
|
statMap["DEXTERITY"] = 10;
|
|
statMap["CONSTITUTION"] = 10;
|
|
statMap["INTELLIGENCE"] = 10;
|
|
statMap["WISDOM"] = 10;
|
|
statMap["CHARISMA"] = 10;
|
|
}
|
|
Character(string characterName, int characterLevel, int experiencePoints, unordered_map<string, int> statMapInput)
|
|
{
|
|
// character initialization, with all relevant information.
|
|
characterName = characterName;
|
|
characterLevel = characterLevel;
|
|
experiencePoints = experiencePoints;
|
|
statMap = statMapInput;
|
|
}
|
|
|
|
private:
|
|
//
|
|
string characterName;
|
|
int characterLevel;
|
|
int experiencePoints;
|
|
unordered_map<string, int> statMap;
|
|
void setCharacterName(string charName)
|
|
{
|
|
//
|
|
characterName = charName;
|
|
}
|
|
string getCharacterName()
|
|
{
|
|
//
|
|
return characterName;
|
|
}
|
|
void setCharacterLevel(int charLevel)
|
|
{
|
|
//
|
|
characterLevel = charLevel;
|
|
}
|
|
int getCharacterLevel()
|
|
{
|
|
//
|
|
return characterLevel;
|
|
}
|
|
void setExperiencePoints(int exp)
|
|
{
|
|
//
|
|
experiencePoints = exp;
|
|
}
|
|
int getExperiencePoints()
|
|
{
|
|
//
|
|
return experiencePoints;
|
|
}
|
|
void setStats(unordered_map<string, int> statMapInput)
|
|
{
|
|
//
|
|
statMap = statMapInput;
|
|
}
|
|
unordered_map<string, int> getStats()
|
|
{
|
|
//
|
|
return statMap;
|
|
}
|
|
};
|
|
|
|
// do while loop for a menu,
|
|
// menu options:
|
|
// 1 - roll dice
|
|
// 2 - set gamemode
|
|
// 3 - set file printing (??? may not implement)
|
|
// 4 - quit dice roller
|
|
|
|
// roll dice:
|
|
// ask user to input XdY[+N] where, X is the number of dice to roll, Y is the sides of the dice,
|
|
// and N is an optional modifier to apply to all rolls.
|
|
// random number generate X times, with any number between 1 and Y.
|
|
// store in a list, sort the list, then reverse the list.
|
|
// need to parse through the 'dice' using: https://codereview.stackexchange.com/questions/41403/simple-dice-roll-using-stdstring-as-dice-notation
|
|
// A way to parse the strings would be to use std::string::find() to find the index of the 'd' and std::string::find_first_of() to find the index of the '-' or '+'.
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
// print title
|
|
printf("\nCharles' Character Creator\n");
|
|
printf("==========================\n");
|
|
// define the menu selection and gamemode selection
|
|
MENU_OPTIONS menuSelection = QUIT_CHARACTER_CREATOR;
|
|
GAME_OPTIONS gameModeSel = PRE_ADD_MODIFIER;
|
|
// define local variables
|
|
int menuSelInt = -1;
|
|
int gameSelInt = 0;
|
|
int numDice = 0;
|
|
int numFace = 0;
|
|
int modifier = 0;
|
|
int temp = 0;
|
|
// define a few needed strings related to dice rolling
|
|
string diceRoll;
|
|
string newFace;
|
|
// random number seeder
|
|
srand((unsigned)time(NULL));
|
|
// menu controller
|
|
do
|
|
{
|
|
// print out the menu with all of the options available.
|
|
printf(" Menu Options:\n");
|
|
printf(" 1: Roll Dice\n");
|
|
printf(" 2: Set Gamemode\n");
|
|
printf(" 3: Start Character Creation\n");
|
|
printf(" 4: Quit Character Creator\n");
|
|
printf("Select a menu option: ");
|
|
// ask for the menu selection
|
|
scanf("%d", &menuSelInt);
|
|
// print a new line
|
|
printf("\n");
|
|
// check to see what menu was selected.
|
|
if (menuSelInt == 1)
|
|
{
|
|
// set the menu selection to start dice rolling.
|
|
// menuSelection = ROLL_DICE;
|
|
// ask the user in how they would like to input their dice
|
|
printf("How would you like to input your rolls?\n");
|
|
printf(" 1: In Dice Notation\n");
|
|
printf(" 2: Rolls, Sides, No Modifier\n");
|
|
printf(" 3: Rolls, Sides, with Modifier\n");
|
|
printf("Select an option: ");
|
|
scanf("%d", &menuSelInt);
|
|
printf("\n");
|
|
if (menuSelInt == 1)
|
|
{
|
|
//
|
|
menuSelection = ROLL_DICE_NOTATION;
|
|
}
|
|
else if (menuSelInt == 2)
|
|
{
|
|
//
|
|
menuSelection = ROLL_DICE_NO_MOD;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
menuSelection = ROLL_DICE_MOD;
|
|
}
|
|
}
|
|
else if (menuSelInt == 2)
|
|
{
|
|
// set the menu selection to move to the select gamemode menu
|
|
menuSelection = SET_GAMEMODE;
|
|
}
|
|
else if (menuSelInt == 3)
|
|
{
|
|
// set the menu selection to start creation.
|
|
menuSelection = START_CHARACTER_CREATOR;
|
|
}
|
|
else
|
|
{
|
|
// set the menu selection to quit
|
|
menuSelection = QUIT_CHARACTER_CREATOR;
|
|
}
|
|
// start the menu selections
|
|
switch (menuSelection)
|
|
{
|
|
case ROLL_DICE_NOTATION:
|
|
// ask the user for a roll in dice notation, (modifier optional)
|
|
printf("Please input your roll in dice notation(XdY[+N]): ");
|
|
// ask the user for the input
|
|
cin >> diceRoll;
|
|
// print a new line
|
|
printf("\n");
|
|
try
|
|
{
|
|
new Dice(diceRoll);
|
|
}
|
|
catch (const std::exception &e)
|
|
{
|
|
printf("You've attempted to input %d dice with %d sides, and a modifier of %d\n", numDice, numFace, modifier);
|
|
std::cerr << e.what() << '\n';
|
|
}
|
|
printf("\n");
|
|
// end the roll dice, in proper notation option
|
|
break;
|
|
|
|
case ROLL_DICE_MOD:
|
|
// ask the user for number of dice.
|
|
printf("Please input number of dice: ");
|
|
// ask the user for the input
|
|
cin >> numDice;
|
|
// print a new line
|
|
printf("\n");
|
|
// ask the user for number of dice.
|
|
printf("Please input number of faces: ");
|
|
// ask the user for the number of faces on the dice
|
|
cin >> numFace;
|
|
// print a new line
|
|
printf("\n");
|
|
// ask the user for the modifier
|
|
printf("Please input the modifier: ");
|
|
// ask the user for the input
|
|
cin >> modifier;
|
|
// print a new line
|
|
printf("\n");
|
|
try
|
|
{
|
|
new Dice(numDice, numFace, modifier);
|
|
}
|
|
catch (const std::exception &e)
|
|
{
|
|
printf("You've attempted to input %d dice with %d sides, and a modifier of %d\n", numDice, numFace, modifier);
|
|
std::cerr << e.what() << '\n';
|
|
}
|
|
printf("\n");
|
|
// end the roll dice, with modifier option
|
|
break;
|
|
|
|
case ROLL_DICE_NO_MOD:
|
|
// ask the user for number of dice.
|
|
printf("Please input number of dice: ");
|
|
// ask the user for the input
|
|
cin >> numDice;
|
|
// print a new line
|
|
printf("\n");
|
|
// ask the user for number of dice.
|
|
printf("Please input number of faces: ");
|
|
// ask the user for the number of faces on the dice
|
|
cin >> numFace;
|
|
// print a new line
|
|
printf("\n");
|
|
try
|
|
{
|
|
new Dice(numDice, numFace);
|
|
}
|
|
catch (const std::exception &e)
|
|
{
|
|
printf("You've attempted to input %d dice with %d sides.\n", numDice, numFace);
|
|
std::cerr << e.what() << '\n';
|
|
}
|
|
printf("\n");
|
|
// end the roll dice, no modifier option
|
|
break;
|
|
|
|
case SET_GAMEMODE:
|
|
// have a mode that adds the modifier to EACH 'roll'
|
|
// aka, roll with advantage/disadvantage
|
|
// have a mode that adds the modifier AFTER the 'roll'
|
|
// aka, add multiple dice together, then add the modifier.
|
|
printf(" Gamemode Options:\n");
|
|
printf(" 1: Add modifier to each roll (Advantage/Disadvantage Mode)\n");
|
|
printf(" 2: Add modifier to totaled roll (Battle Roll Mode)\n");
|
|
printf("Select a mode: ");
|
|
scanf("%d", &gameSelInt);
|
|
printf("\n");
|
|
|
|
if (gameSelInt == 1)
|
|
{
|
|
// set the 'gamemode' to the PRE MODIFIER
|
|
gameModeSel = PRE_ADD_MODIFIER;
|
|
}
|
|
else
|
|
{
|
|
// set the 'gamemode' to the POST MODIFIER
|
|
gameModeSel = POST_ADD_MODIFIER;
|
|
}
|
|
|
|
// finish with the set gamemode menu
|
|
break;
|
|
case START_CHARACTER_CREATOR:
|
|
printf("Character creator works.\n");
|
|
break;
|
|
// have to add this line or it won't compile
|
|
default:
|
|
break;
|
|
}
|
|
} while (menuSelection != QUIT_CHARACTER_CREATOR);
|
|
|
|
// print the program end
|
|
printf("Program End.");
|
|
// return zero (main fct)
|
|
return 0;
|
|
}
|
|
|
|
// compiles using "g++ -Wall -pedantic .\hm3.cpp -o .\hm3.exe" - note to programmer
|
|
|
|
/*
|
|
Name: addDiceList
|
|
Process: iterate through the dice list, and sum the dice
|
|
Function Input/Parameters: list<int>
|
|
Function Output/Parameters: ???
|
|
Function Output/Returned: int
|
|
Device Input/Device: ???
|
|
Device Output/Monitor: ???
|
|
Dependencies: list
|
|
*/
|
|
int addDiceList(list<int> inputList)
|
|
{
|
|
int returnNum = 0;
|
|
//
|
|
for (list<int>::iterator diceItr = inputList.begin(); diceItr != inputList.end(); diceItr++)
|
|
{
|
|
//
|
|
// cout << *diceItr << endl;
|
|
returnNum = returnNum + *diceItr;
|
|
}
|
|
return returnNum;
|
|
}
|
|
|
|
/*
|
|
Name: displayDiceList
|
|
Process: iterate through the dice list, and display the dice rolls
|
|
Function Input/Parameters: list<int>
|
|
Function Output/Parameters: ???
|
|
Function Output/Returned: int
|
|
Device Input/Device: ???
|
|
Device Output/Monitor: ???
|
|
Dependencies: list
|
|
*/
|
|
void displayDiceList(list<int> inputList)
|
|
{
|
|
//
|
|
for (list<int>::iterator diceItr = inputList.begin(); diceItr != inputList.end(); ++diceItr)
|
|
{
|
|
//
|
|
cout << *diceItr << " ";
|
|
}
|
|
cout << endl;
|
|
}
|