0

Here is the code I'm trying to create, and yes its messy for now. To give some back story I'm trying to figure out how to call a class multiple times without doing it seperately. What I mean is instead of performing: Dice diceOne; Dice diceTwo; and so on, I want to know if it is possible to just put it as Dice dicewhatever(*) and have that be a modifiable variable. This is so that I can set that variable to a number and then decrement it based on a score.

I dont know if this is even possible, but at this point I've beat my head against this so much I'm just pulling at straws to see if it would be a fit.

class Dice {
public:
    Dice();
    int Roll();
    int currentDiceSide();

private:
    int diceRoll;
    int diceReRoll; //Declares and initializes the number of dice to allow for      roll next dice throw.
};

Dice::Dice()
    : //This is the beginning of the class and sets diceRoll to zero
    diceRoll(0)
{
}

int Dice::Roll()
{ //This function actually does the random roll within the class Dice.
    diceRoll = ((rand() % 6) + 1);
    return diceRoll;
}

int Dice::currentDiceSide()
{ //This function returns the value of the dice roll for the class call.
    return diceRoll;
}

void Game::Rules()
{
    ifstream inFile;
    inFile.open("Farkle Rules.txt");
    string line;

    if (inFile.fail()) {
        cerr << "Error opening file" << endl;
        exit(1);
    }
    if (inFile.is_open()) {
        while (inFile.good()) {
            getline(inFile, line);
            cout << line << endl;
        }
        inFile.close();
    }
}

void Game::GetPlayerInput(int playerInput)
{
    cin >> playerInput;
}

void Game::RunGame()
{
    Rules();

    bool farkle = false;

    double turnSum = 0;
    double value = 0;
    int i = 0;
    int w = 6;
    int players = 0;
    int numPlayer = 0;
    int diceOneValue = 0;
    int diceTwoValue = 0;
    int diceThreeValue = 0;
    int diceFourValue = 0;
    int diceFiveValue = 0;
    int diceSixValue = 0;

    int num1s = 0; //Declaring and initializing the variables to hold how many times a number shows up in a roll.
    int num2s = 0;
    int num3s = 0;
    int num4s = 0;
    int num5s = 0;
    int num6s = 0; //

    srand(static_cast<unsigned int>(time(0)));

    cout << "Welcome to Farkle!" << endl
         << endl;
    cout << "Please enter the number of players " << endl;
    cin >> players;

    //Dice diceOne;
    //diceOne.currentDiceSide();
    //Dice diceTwo;
    //diceTwo.currentDiceSide();
    //Dice diceThree;
    //diceThree.currentDiceSide();
    //Dice diceFour;
    //diceFour.currentDiceSide();
    //Dice diceFive;
    //diceFive.currentDiceSide();
    //Dice diceSix;
    //diceSix.currentDiceSide();

    Dice diceOne(w);
< -this is the line that I would like to create with a variable that is modifiable.
drescherjm
  • 10,365
  • 5
  • 44
  • 64
bowzer
  • 11
  • 1
  • 1
    Have you learned about arrays and `std::vector`? – alter_igel Jun 27 '18 at 22:59
  • Not yet, no, and honestly this is for my final, so I doubt we will. – bowzer Jun 27 '18 at 23:01
  • 1
    How about arrays then? Do you know about those? – Some programmer dude Jun 27 '18 at 23:02
  • 3
    On an unrelated note, `while (inFile.good())` is really no different than `while (!inFile.eof())`. And [that should always be considered wrong](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – Some programmer dude Jun 27 '18 at 23:03
  • Possible duplicate of [Is it possible to use dynamic name for variables in c++](https://stackoverflow.com/questions/29257495/is-it-possible-to-use-dynamic-name-for-variables-in-c) – Travis Jun 27 '18 at 23:40
  • What kind of C++ course hasn't covered `std::vector` by the *final*?! – Kevin Jun 28 '18 at 00:42
  • @Kevin, it is a 8 week course and we jumped around in the book. Most of my programming courses so far have been like this. It is rather frustrating, as usually I'm just getting a really good handle and then boom here is your final and I have to switch gears for a new course and drop what I was doing. – bowzer Jun 28 '18 at 05:24

1 Answers1

0

You cannot give each Dice object a name, but you can create a Vector of Dice object pointers (vectors are basically resizable arrays), like this:

#include <vector>
#include <iostream>

//...

std::cout << "Please enter the number of players " << std::endl;
std::cin >> players;

// do something to make sure players is an integer

// initialize the empty playerDice vector
std::vector<Dice*> playerDice = {};

for (unsigned i = 0; i < players; ++i) {
    playerDice.push_back(new Dice); // this adds a new Dice object pointer to the end of the vector
    playerDice.at(i)->currentDiceSide();
}

You have then called the currentDiceSide() function on each Dice object you created, and have neatly organized them in a Vector, which you can access like this:

// say we want to access the third Dice Object,
// Vectors start counting at 0, so we acces the element at Index 2.
playerDice.at(2)->doSomething();

Now because you instantiated those Dice objects with new you have to remember to delete them when you're finished with them, otherwise this will create a memory leak.

//...
// this deletes all the Dice objects in the vector, and points the remaining pointers to null
for (auto d : playerDice) {
    delete d;
    d = nullptr;
}

Or, better yet, if you're using C++11, you can use std::unique_ptr instead of the raw C-style pointers. Those will prevent you from creating memory leaks, because they will be deleted when they go out of scope. Note you have to #include <memory> to use these.

The vector definition then turns into:

std::vector< std::unique_ptr<Dice> > playerDice = {};

And the creation of the objects would look like this

for (unsigned i = 0; i < players; ++i) {
    Dice* temp = new Dice;
    temp->currentDiceSide();
    std::unique_ptr<Dice> uPtr{ temp };
    playerDice.push_back(std::move(uPtr));
}

You can then just clear the vector when you're done with all the objects:

playerDice.clear();

which will delete all the Dice objects that you put into the vector.

L. Kue
  • 473
  • 5
  • 19
  • First to everyone, THANK YOU for the feedback so far. @ L. Kue's answer in regards to vectors before I tear my program apart, am I right in thinking that "players" could be defined by a the variable players, that I could then modify? I ask this because if so, that takes care of my problem....I think... I'm gonna have to fight this more, but I think I may be able to make that work. – bowzer Jun 28 '18 at 05:21
  • Also, am I reading the code you put in correctly where you put Dice and Dice* (Correct me if I'm wrong in that, this designates a pointer). Would I be calling my Dice class in my program as I already have it and just running that class and its function through this new function which creates the Vector(s) / Vector Arrays? – bowzer Jun 28 '18 at 05:27
  • Question in how to incorporate the vector arrays. From what I understand of this code, it is going to make a new temporary dice object. I am using a switch statement to do my counts and scores based on the rolls within the dice. I've seen where people have used an array within a switch and just stated "switch (dice[i])" and it works fine. My question would be this, how would I know the name of the vector array for the dice? The point of this is I have to roll 6 dice and then when a 1,5, or 3 of a kind come up remove the scoring dice and re roll. So I was using the switch to evaluate. – bowzer Jun 28 '18 at 05:48
  • The * after a variable type designates it to be a pointer. If you wanted to alter the number of players through user input, after already having created the initial number of players, you would need to create a function that adds or removes a player, creates a `Dice` object for them and calls any initializing functions on that object, as well as adds it to the vector for you. The `Dice` object created by this is in no way temporary, but the pointer to it is. – L. Kue Jun 28 '18 at 11:18
  • Regarding your last question: you should really do some reading on vectors and arrays, you can access the elements by either index or value (the former being faster, as you don't need to look at each element). – L. Kue Jun 28 '18 at 11:21