0

I have searched this for hours and I'm not getting it. I don't seem to know how to return values using Fisher-Yates and many ways listed. I'm dying here.

I can get a RandomNumber, but this is reused over and over. I need it to be unique everytime when returned (or so I tend to think is possible).

I need help understanding what I should do, why each part does, and stuff for dummies. This is what works:

    private int RandomNumber(int min, int max)
    {
        Random random = new Random();
        return random.Next(min, max);
    }

And this is what I'm putting it into and it working (but not unique random numbers are used)... I only included what I felt needed to be looked at and where it is positioned:

  private void ComputersTurn()
    {
        Control.ControlCollection coll = this.Controls;
        foreach (Control c in coll)
        {
            if (...)
            {
                if (...)
                {

                    if (...)
                    {
                        if ((c.Name == "btn" + Convert.ToString(RandomNumber(1,9)) && (c.Enabled != false) )) 
                        {
                            if (...)
                            {
                                //code here
                            }
                        }


                    }
                }
            }
        }
    }

Again, RandomNumber works...but it's not unique. I wish to learn how to return a unique number (if possible).

leppie
  • 115,091
  • 17
  • 196
  • 297
  • 1
    @leppie: 20 mm above the words "many" and "times" in your comment, there is a close button. use it. – CloudyMarble Feb 21 '13 at 06:38
  • Your RandomNumber method keeps creating a random instance. Inside a loop, you are basically going to keep seeding it with the same value, which means you are going to generate the same random number (pro-tip: it's not actually *random*, but it sometimes acts like it). Move the instance outside the method and create it once. Now, if you need truly unique and not just random, then certainly revisit those FY algorithms and keep trying. – Anthony Pegram Feb 21 '13 at 06:44
  • 1
    I understand it's a very common question, but each one is catered to a different use. I tried the many ways but I cannot get it to work. I'm sorry if it's such a burden, but I wasn't learning anything through those searches and had no idea how to get a value to return correctly. – Dwelling Place Feb 21 '13 at 06:45
  • Here's a link to a FY implementation that should get you moving. http://stackoverflow.com/questions/1287567/is-using-random-and-orderby-a-good-shuffle-algorithm/1287572#1287572 – Anthony Pegram Feb 21 '13 at 06:46
  • So, what I'm seeing is, I can return and 'element' in his case which holds a value? And to read that 'element' I just place the word 'element' where I put 'RandomNumber(1,9)' in my code? – Dwelling Place Feb 21 '13 at 06:49
  • @leppie this is not a duplicate of that post - there was no uniqueness constraint. – Dr. Andrew Feb 21 '13 at 06:58
  • 1
    @DwellingPlace btw, what do you expect if `RandomNumber(1,9)` is called more than 9 times. – default locale Feb 21 '13 at 07:03
  • @defaultlocale only 9 numbers can be called before the form is closed, plus they are cleared when the form is cleared. I dont think its possible to call it more than 9 times. – Dwelling Place Feb 21 '13 at 07:32

4 Answers4

1

Are you simply trying to return all the integers from min to max with their order permuted? This is the only way it makes sense to me to want a sequence of random integers in a given range such that each random is guaranteed unique...

Assuming I'm correct, you should be able to easily find code for random permutation of an array.

Dr. Andrew
  • 2,532
  • 3
  • 26
  • 42
  • There order doesn't matter at all. It can be 1, 9 , 2, 3, 6, 5, 4...whatever just not repeats. I looked into an array, just don't know how to return the random value. ;( – Dwelling Place Feb 21 '13 at 06:42
  • 1
    My point is that what you want is exactly the same as random permutation, and I think there are a lot of questions on so that help with this. For example, consider min=0 and max=9; a random permutation may be 0,9,7,6,8,2,5,1,3,6,4. If you want 5 randoms, you just take the first 5 entries from this array. Hence, what you want to do first is randomly permute the counting array from min to max. – Dr. Andrew Feb 21 '13 at 06:54
  • Of course, I'm assuming you are aware you can't possibly take more unique random numbers than (max-min)... – Dr. Andrew Feb 21 '13 at 06:55
0

The only way to generate unique numbers by Random is to define it in your class like this:

public static class RandomGenerator
{
    private static readonly Random _random = new Random();

    public static int GenRand(int x, int y)
    {
        return _random.Next(x, y);
    }
}

In your case try to use this code this way:

private void ComputersTurn()
    {
        Control.ControlCollection coll = this.Controls;
        foreach (Control c in coll)
        {
            if (...)
            {
                if (...)
                {

                    if (...)
                    {
                        if ((c.Name == "btn" + Convert.ToString(RandomGenerator.GenRand(1, 9)) && (c.Enabled != false) )) 
                        {
                            if (...)
                            {
                                // code here
                            }
                        }


                    }
                }
            }
        }
    }
fibertech
  • 357
  • 1
  • 13
  • where would I place that and how would I implement that in the same way I'm using it now? – Dwelling Place Feb 21 '13 at 06:43
  • Random itself doesn't guarantee unique output. No matter where you define it. – default locale Feb 21 '13 at 06:44
  • @DwellingPlace Just define it after `{` in your class and use in your code `int randInt = random.Next(x, y);` – fibertech Feb 21 '13 at 06:44
  • @DwellingPlace I have just edited my post, just try to use my code – fibertech Feb 21 '13 at 06:47
  • @defaultlocale it's just a theory, @DwellingPlace wants to use `Random` so, why not to use it, there are a lot of algorithms in the web, providing unique random numbers, but it's another discussion – fibertech Feb 21 '13 at 06:50
  • @fibertech - I placed your code, how do I call it the same way I called 'Convert.ToString(RandomNumber(1,9))' ? – Dwelling Place Feb 21 '13 at 06:54
  • @fibertech OP's question is exactly about unique random numbers. Your answer is about creating a wrapper of standard class (random). I couldn't see how does it answer a question. – default locale Feb 21 '13 at 06:57
  • @fibertech - okay, I see it now and used the debugger to see what was going on. but there's a problem (which might be solved by just repeating code X amount of times I assume). It gets the random value, but after I take my turn--the computer no longer goes. Before it did though (but wouldn't show at times because the same random value was drawn) – Dwelling Place Feb 21 '13 at 07:02
  • @fibertech it's great that your code uses only one instance of `Random`. But it gives exactly the same results as OP's code in question body. – default locale Feb 21 '13 at 07:10
  • I might see the problem. It will still try to use the number if it was in use by me-- I'm guessing I have to play around with do-whiles or if-else statements to counter-act that (?). I think the unique number thing works--but I'll have to test it more to see if it ever returns the same number actually – Dwelling Place Feb 21 '13 at 07:20
  • 1
    @fibertech got it to work, thanks very much for the help. I learned what was conflicting. Your generator worked fine. :D – Dwelling Place Feb 21 '13 at 10:54
0

Instantiate the Random class only once.

private Random random = new Random();

private int RandomNumber(int min, int max)
{
    var result = this.random.Next(min, max);
    return result;
}
MilkTea027
  • 301
  • 1
  • 5
  • 24
-1

try to put declaration of your instance of Random class outside the function so that the you can get every time different number if you want to make sure that random numbers are not going to be duplicated you can use and List to store every generated number

class Classname
{
private Random random = new Random();
//your code
}
BMW
  • 590
  • 1
  • 6
  • 12
  • Using one `Random` instance is a good idea, but it has nothing to do with unique numbers and, thus, doesn't answer a question. – default locale Feb 21 '13 at 06:47
  • you can use a list and then insert each random number generated by the RandomNumber(int min, int max) and you can make a while loop to check if the number is inside that list – BMW Feb 21 '13 at 06:51