简体   繁体   中英

Generate random numbers from 1 to 6 and stop at the last one

I have the following code :

int GetRandNumber()
{
    Random r = new Random();
    return r.Next() % 6 + 1;             
}

I am developing a windows store app. I have a textbox in which a single number from 1 to 6 is generated. For every number I have made a specific event. I need to make sure that every number is generated only once so that the events do not repeat.

Looks like you just need to shuffle numbers. I'd suggest to create an array of numbers from 1 to 6 and just shuffle the array. You can see some code here for how to shuffle an array/list.

First of all you need to be careful with this implementation, if you call GetRandomNumber() multiple times very close together it will give you the same result. A better function would be

int GetRandNumber(Random r)
{
    return r.Next(1, 7); //This does the same as "r.Next() % 6 + 1" but removes bias.
}

//used like
Random rand = new Random();
foreach(var foo in bar)
{
    //The same instance of rand is used for each call instead of a new one each time.
    foo.SomeProp = GetRandNumber(rand);
 }

However that is completely separate from what you need to do, you should not be generating random numbers between 1 though 6. What you need to do is make a list of 1 though 6 then shuffle the list, not use random numbers at all (well you will likely use them during the shuffle but that is a implementation detail)

List<int> numbers = new List<int>();
for(int i = 1; i <= 6; i++)
{
    numbers.Add(i);
}

MyShuffleListFunction(numbers);

There are plenty of examples on this site on how to make a shuffle function.

Maybe I'm wrong, but as I understand you want something like this as an output:

344213266125

To achieve this you should keep track which numbers are already generated, and stop if all has been "rolled" at least once. So let's have a bool array initialized to 6 false values, and after each random number generation (after each roll) set the array's corresponing element to true. Check if there are any false values in the array, if not then "roll again".

Also, you might consider generating the numbers according to the other answers, as they are of course right: this is not an ideal way.

Update

Okay, based on your question's update I also update my pseudocode (or maybe I should call this prose): Keep track of the already "rolled" numbers (as above). When generating a new number check if it has been already generated or not. If it's been rolled before, then roll again, until you roll a new one: then update the array accordingly. Also be sure to check if there is a valid number or all has been rolled before at the beginning of the roll...

But now it seems for me that what you really are looking for is simply a shuffle, which has been proposed in other answers.

Perhaps this will work for you. The approach is to record the random results in a List and to skip the output if the results already exists in the list.

class Program
{
    static int tmp;

    static void Main(string[] args)
    {
        List<int> alreadyFired = new List<int>();                   

        while (alreadyFired.Count != 6)
        {

            Random rng = new Random();

            int diceresult = rng.Next(1,7);

            foreach (var item in alreadyFired)
            {
                if (item == diceresult)
                {
                    tmp = item;
                }
            }

            if (!(tmp == diceresult))
            {
                alreadyFired.Add(diceresult);                 
                Console.WriteLine(diceresult);
            }
        }

        Console.WriteLine("no events left");
        Console.ReadKey();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM