Constructor-Random. Sometime random, sometime not.

Why the these constructors produces different result?
The first constructor produces random result each time (in a vector).
The second constructor produces same result every time (in a vector).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <vector>
#include <random>
using std::cout;
using std::endl;

double randomize(const double &minVal, const double &maxVal){
	std::random_device rd;
	std::mt19937 genEngine(rd());
	std::uniform_real_distribution<double> distrib(minVal, maxVal);
	return distrib(genEngine);
}

constexpr char weak   = 'w';
constexpr char normal = 'n';
constexpr char strong = 's';
double HMaxAttrib     = randomize(0.95,1.00) * 100;

class Human {
private:
    double _health;
    double _attack;

public:
    Human(){
        _health      = HMaxAttrib * randomize(0.6,0.8);
        _attack      = HMaxAttrib * randomize(0.6,0.8);;
    }

    Human(const char &strength){
        if (strength == 'w'){
            _health  = HMaxAttrib * randomize(0.6,0.8);
            _attack  = HMaxAttrib * randomize(0.6,0.8);
        }
        if (strength == 'n'){
            _health  = HMaxAttrib * randomize(0.7,0.9);
            _attack  = HMaxAttrib * randomize(0.7,0.9);
        }
        if (strength == 's'){
            _health  = HMaxAttrib * randomize(0.8,1.0);
            _attack  = HMaxAttrib * randomize(0.8,1.0);
        }
    }

    auto getHealth(){
        return _health;
    }

    auto getAttack(){
        return _attack;
    }
};

int main(int argc, char* args[]){

    cout<<"Using first constructor"<<"\n";
    std::vector<Human> itWorked(3);
    for (auto i = 0; i < 3; i++){
        cout<<"Health: "<< itWorked[i].getHealth();
        cout<<"\nAttack: "<< itWorked[i].getAttack()<<endl<<endl;
    }

    cout<<"Using second constructor"<<"\n";
    std::vector<Human> hu(3, strong);
    for (auto i = 0; i < 3; i++){
        cout<<"Health: "<<hu[i].getHealth();
        cout<<"\nAttack: "<<hu[i].getAttack()<<endl<<endl;
    }

    cin.get();
    return 0;
}
The vector will store three copies of the Human object that is passed to the constructor. That is why all of them are the same.
http://www.cplusplus.com/reference/vector/vector/vector/

(2) fill constructor
Constructs a container with n elements. Each element is a copy of val (if provided).


val
Value to fill the container with. Each of the n elements in the container will be initialized to a copy of this value.
Member type value_type is the type of the elements in the container, defined in vector as an alias of its first template parameter (T).


For the second, you provided 'val' in the first you didn't. In the second one, that's basically asking it to initialize all elements to be a copy of the one you sent in.
So, how can I get around this?
How to make the second vector initialize the objects different each time?
Don't send in a default value. It creates different ones for the first way you did it, doesn't it?
Thanks,

But what do you mean by default value? It is the const char &strength ?

I originally wanted the user to be able to choose the difficulty level (weak,norm,strong) before entering the number of Human (before fighting with enemy).

Using the first way I did, I was able to complete the whole fighting simulation using vectors. Now I just wanted to add new "features" to the program and the same time learning more C++.

std::vector<Human> hu(3, strong);
That created 3 of the same.
strong will be used to create the first one and the other 2 will be copies of the first.

std::vector<Human> itWorked(3);
This one created 3 different ones. Use this one if you want three different ones.
So, I'll have to create three classes for three difficulties?

That is the only way?

If it were you, how would you do it? in general.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <algorithm>
#include <iterator>
// ...

    cout << "Using second constructor" << "\n";
    std::vector<Human> hu;
    std::generate_n(std::back_inserter(hu), 3, [] {return Human(strong); });

    for (auto i = 0; i < 3; i++) {
        cout << "Health: " << hu[i].getHealth();
        cout << "\nAttack: " << hu[i].getAttack() << endl << endl;
    }

// ... 

No. Just make an empty vector. Then push new ones in as you create them. You can push anything you want into it. It just creates copies when you give it an initial value upon creation.

Like what cire did. That will create 3 different ones, all created with 'strong'.

But notice, the vector is declared std::vector<Human> hu;
An empty vector with no initial values. After that the vector is filled up.
Thanks cire and JayhawkZombie.
I will read about generate_n and back_inserter now. (no idea what it is yet).

I will also try the empty vector idea (brilliant idea btw).
Thanks.
Topic archived. No new replies allowed.