rand() C++

** IF THE SEEDS ARE HARD TO FIND IN THE CODE LOOK FOR ***
// SEEDING HERE
srand(time(NULL) // SEEDING HERE
// SEEDING HERE
** THOSE COMMENTS TO FIND THE SEEDS ***

Hey guys so you have to set Seeds to use random?
And in my program im writing Im using a lot of randoms.Just curious how my seeding should work. Or if Im doing it right/wrong.

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
 
// playerFight(Player *p) - pass the player object, create a new enemy. And eneter a fight loop
// that ends when either player or enemy reaches 0 health. 
void playerFight(Player *p) {
    // local variables 
    bool battle = true; // battle will always be true
    bool playersTurn = true; // player will always start (true)
    bool enemyTurn = false; // player will always go first
    int randomAbility = 0; // random number for which ability the enemy will choose 
    int enemyLevel = 0; // our enemies level 
// SEEEDING HERE// SEEEDING HERE
    srand(time(NULL)); // seed for random numbers // SEEEDING HERE
    // SEEEDING HERE// SEEEDING HERE
    // used in the fight loop 
    int nChoice; // used to get the ability choice of the player each turn 
    std::string abilityUsed; // the ability being used 
    bool enemyDodge = false; // is the enemy dodging? 
    bool playerDodge = false; // is the player dodging? 
    
    // depending on the players level 
    // make random enemy levels 
    if(p->getLevel() < 3)
    {
// SEEEDING HERE
        srand(time(NULL));// SEEEDING HERE
// SEEEDING HERE
        enemyLevel = rand() % 3 + 1; // lvls 1 - 3
    }else if(p->getLevel() > 5){
        enemyLevel = 5; // lvl 5 
    }else{
// SEEEDING HERE
        srand(time(NULL));// SEEEDING HERE
// SEEEDING HERE
        enemyLevel = rand() % 5 + 1; // lvls 1 - 5
    }
    
    // create an enemy to battle 
    Enemy e; // enemy obj 
    e.setLevel(enemyLevel);
    
    // battle will usually always be true 
    while(battle) {
        if(playersTurn) {
            // promt the player 
            std::cout << "Players turn: \n"; 
            // players turn 
            // prompt them with their attacks 
            std::cout << "You are fighting a " << e.getType() << '\n'; 
            std::cout << "Please select your attack:\n"; 
            p->getAbilities();
            
            // let the user input their ability choice 
            // and then set the new abilityused var to 
            // that ability of choice 
            std::cin >> nChoice;
            abilityUsed = p->getAbility(nChoice); 
            
            // random, did the enemy dodge or no? 
            enemyDodge = e.didDodge(); 
            
            // if enemy dodged let the player know 
            // otherwise make the enemy take damage 
            if(enemyDodge) {
                std::cout << "Enemy dodged your attack!\n"; 
            }else{
                e.takeDamage(p->getAbilityDamage(abilityUsed));    
            }
             
            // After the player finishes their turn set 
            // it to false and the enemys to true 
            playersTurn = false; 
            enemyTurn = true;  
        }else{
            // prompt the player
            std::cout << "Enemies turn: \n"; 
            // enemies turn 
            playerDodge = false; 
            // get a random abilnum
// SEEEDING HERE
            srand(time(NULL));// SEEEDING HERE
// SEEEDING HERE
            randomAbility = rand() % 4 + 1; 
            
            // output to the user the enemy, their attack, and their damage 
            std::cout << "Enemy " << e.getType() << " attacks with " 
                      << e.getAbility(randomAbility) << " for " 
                      << e.getAbilityDamage(e.getAbility(randomAbility)) << '\n';
                      
            // random, did the player dodge or not? 
            playerDodge = p->didDodge(); 
                      
            // if player dodged let the player know 
            // otherwise make the enemy take damage 
            if(playerDodge) {
                std::cout << "Player dodged the attack!\n"; 
            }else{
                p->takeDamage(e.getAbilityDamage(e.getAbility(randomAbility))); 
            }
            
            // After the enemy finishes their turn set 
            // it to false and the players to true 
            playersTurn = true; 
            enemyTurn = false;
            
            // let the player know the enemies turn is over 
            std::cout << "Enemy's turn is over\n"; 
        } 
        
        if(p->getHealth() < 0)
        {
            // player died 
            std::cout << "Players health has fallen below zero. Enemy wins!\n"; 
            
            // end the battle 
            battle = false;  
        }else if(e.getHealth() < 0)
        {
            // enemy died 
            std::cout << "Enemy has been defeated, congrats!\n"; 
            // end the battle 
            battle = false; 
        }
    }
}


As you can see Im seeding before every random var i create. Is this right or wrong and how should I do this effectively. Thanks guys
Last edited on
Seems ok.
srand() should be called no more than once per thread.
Seed the legacy rng by caling std::srand() once, at the start of the program.

There is no guarantee that std::srand() or std::rand() are thread-safe (the same seed is shared by all threads).
(Note that "once per process" doesn't contradict "no more than once per thread".)
(Note that "no more than once per thread" implies "many times per process, though not more than once for each thread".)
(Nope. If you never call srand() in a given thread then you've called it no more than once. So no, that's not an implication.)
(Nope: "no more than once per thread" implies that it may be called once per thread.)
(So if I forbid you from killing my cat am I giving you permission to beat it?)
Last edited on
(So, if you say "no more than once per thread" you are saying "may be multiple times in a process if the process has more than one thread.)
(No, that's not an equivalent rephrasing of my statement.)
(It is. Even if you find it unpalatable to accept it.)

I have nothing more to add to this discussion.
Do you ever? Always a pleasure.
Just curious how my seeding should work.

Imagine a pearl necklace. A long one. Each pearl has a number. If you do read consecutive pearls, you will get a pseudo-random sequence. You have a finger on one pearl. You always do.

What does the rand() do? It does two things:
* Read number from pearl
* Move finger to next pearl

What does the srand() do? It moves the finger to a specific pearl.

You seed with time. Time has some resolution. Say one millisecond. How many times can your program call srand() within one millisecond? I bet many times.

Therefore, the time remains same on all those calls to srand(). Seed is same.
The srand() will move the finger to same pearl on all those calls.
All those rand() will read the same pearl, the same number.


I've heard anecdote on how rand() was "working fine" until a new computer was purchased. There was only one call to srand(), but the program was run multiple times. The new comp was so fast that the time was same on all runs.


Take a look at http://www.cplusplus.com/reference/random/
Yes, they are more to type than the legacy rng, but supposedly more fun than
int rand() { return 42; }
Topic archived. No new replies allowed.