Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey,
just a quick question:

I hava a button 'get Random'. If i press the button, the program sets the text of a label to this value.
sometimes, if i press the button 2 times, it returns the same number.

How can i avoid getting two same values?

What I have tried:

int newRandom = 0;
int lastRandom = 1;

private int GetRandom()
{
   Random r = new Random();
   newRandom = r.Next(0, 7);

   while (newRandom == lastRandom)
   {
      newRandom = r.Next(0, 7);
      if(newRandom != lastRandom) break;
   }
   lastRandom = newRandom;

   return newRandom;
}


label.Text = GetRandom.ToString();
Posted
Updated 11-Oct-16 5:54am
Comments
Andy Lanng 11-Oct-16 11:48am    
What you're looking for is simulated randomness. Not truly random but what a human brain would interpret as random.
In that case you're going to have to store at least the previous 1 number

Random numbers use what's known as a "seed" as the starting value to a mathematical equation that simulates randomness. If you give the random number generator the same seed you'll always get the same sequence of values, so the first number will always be the same. You can specify the seed in the constructor

Random(yourSeedHere)

In order to be truly random the seed also needs to be random...so you need a random number to get random numbers, how does that work?

When you leave off the seed as you have in your code (you use the parameterless constructor for Random)

C#
Random r = new Random();


then it uses the current time as the seed, or more accurately the current number of "ticks". So when you create two instances of Random, they are created at different times so use different seeds. However, if you run your code in a loop that fires multiple times per tick, all instances uses the same seed so generate the same number.

The solution to all of this is simple...create the Random class once and re-use it rather than creating a new one every time.

C#
Random r = new Random();
int newRandom = 0;
int lastRandom = 1;
 
private int GetRandom()
{
   newRandom = r.Next(0, 7);
 
   while (newRandom == lastRandom)
   {
      newRandom = r.Next(0, 7);
      if(newRandom != lastRandom) break;
   }
   lastRandom = newRandom;
 
   return newRandom;
}
 
Share this answer
 
Comments
Tobias Wälde 11-Oct-16 12:11pm    
thanks a lot, it works perfectly now
That is the nature of random numbers: the idea is that the next number is not dependant on the previous value, much like when you toss a coin: the chances of a head are 50:50 regardless of the value when you last tossed it. And the smaller the sample size the more likely it is that you will get duplicates. So with a choice of seven values, you have a 1:7 chance of consecutive duplicates.

So...set up an array and a variable:
C#
private List<int>values = new List<int> () { 1, 2, 3, 4, 5, 6, 7 };
private int last = -1;
private Random random = new Random();

Then use that:
C#
public int GetRandom()
    {
    if (last < 0)
        {
        int index = random.Next(0, 7);
        last = values[index];
        values.RemoveAt(index);
        }
    int result = values[random.Next(0, 6)];
    values.Remove(result);
    values.Add(last);
    last = result;
    return result;
    }

That'll give no duplicates!
 
Share this answer
 
Comments
Tobias Wälde 11-Oct-16 12:13pm    
thanks, but the other solution is better and works with variable length...
OriginalGriff 11-Oct-16 12:30pm    
The problem with the other solution is that it may "work with variable length (so does mine if you remove the "magic numbers" and load the initial list with Enumerable.Range) - but it has the disadvantage that it will take a variable (and unknown) amount of time to return a value - mine is constant.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900