2

In my .NET game my rand function that are determining how much damage each out of the players five characters should take, however the 1st one always seems to be at the bottom of the scale and the last one at the top. So in my Character[0] the damage is rarely more than 1 more than the minimum rand value, and for each Character on higher index the damage taken is only randomized from higher up the scale.

public int GetDamage(int low, int high)
{
    Random r = new Random();
    int rand = r.Next(low, high);
    return rand;
}

This is the randomizer I use. Then I update the health left like this:

int Damage = GetDamage(3, 10);
Characters[Target].Health = Characters[Target].Health - Damage;

In this example dmg is divided like this:

Number 1: 3-4
Number 2: 4-6
Number 3: 5-7
Number 4: 7-8
Number 5: 8-9
Carsten
  • 11,287
  • 7
  • 39
  • 62
Tom
  • 1,747
  • 5
  • 23
  • 39
  • 3
    Oh really? An non-seeded random generator is not really random? – Thorsten Dittmar Apr 11 '13 at 12:59
  • @ThorstenDittmar It is technically seeded, just 'badly'. – Grant Thomas Apr 11 '13 at 13:01
  • 1
    Related: http://stackoverflow.com/questions/1785744/how-do-i-seed-a-random-class-to-avoid-getting-duplicate-random-values – Carsten Apr 11 '13 at 13:02
  • 6
    No need for the sarcasm though. – Tom Apr 11 '13 at 13:02
  • 1
    Related: http://stackoverflow.com/a/1785821/580951 – Dustin Kingen Apr 11 '13 at 13:03
  • 1
    How would seeding make it "more" random? The real problem is, that there will be multiple instances of `Random` created, possibly with the *same* seed (Milliseconds) producing the same sequence of pseudo random numbers. Rule of Thumb: have *one* instance of `Random` for your whole application except when you know exactly why you would need more than one. – Corak Apr 11 '13 at 13:06
  • 1
    @Tom It wasn't against you or your programming skills - I just think that the `Random` class is not suited to generate real random numbers. – Thorsten Dittmar Apr 11 '13 at 13:13
  • @ThorstenDittmar. My bad then, must have misunderstood it. However it works well with Tim Schmelter/KingCronus' suggestions. – Tom Apr 11 '13 at 13:15
  • 1
    I do wish language designers would call it "PseudoRandom()" to avoid confusion sometimes. – KingCronus Apr 11 '13 at 13:26
  • @KingCronus That's redundant, as anyone programming should already know that, as an implication of the difficulties in generating random numbers, they can only be _pseudo_ at best. – Grant Thomas Apr 11 '13 at 14:57
  • 1
    @GrantThomas, I disagree. Search for related questions on here; there are plenty of programmers who don't know this. Not everybody was born a CS Major. – KingCronus Apr 11 '13 at 16:15

3 Answers3

9

You have to reuse the same random instance otherwise you won't get really random values since it is created with the current time as seed. If you call GetDamage very fast(e.g. in a loop) you will get always the same values.

So either use a field/property in the class of GetDamage or pass the random instance to the method.

private Random _rnd = new Random();
public int GetDamage(int low, int high)
{
    int rand = _rnd.Next(low, high);
    return rand;
}

MSDN

The random number generation starts from a seed value. If the same seed is used repeatedly, the same series of numbers is generated. One way to produce different sequences is to make the seed value time-dependent, thereby producing a different series with each new instance of Random. By default, the parameterless constructor of the Random class uses the system clock to generate its seed value, while its parameterized constructor can take an Int32 value based on the number of ticks in the current time. However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. This problem can be avoided by creating a single Random object rather than multiple ones.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
3

You need to make your Random instance static, this seeds it once and thereafter you will get a more random looking number.

static Random r = new Random();

public int GetDamage(int low, int high)
{
    int rand = r.Next(low, high);
    return rand;
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
2

You need to seed the random number generator.

See: How do I seed a random class to avoid getting duplicate random values

Literally hundreds of this question on here, have a look around.

Community
  • 1
  • 1
KingCronus
  • 4,509
  • 1
  • 24
  • 49