简体   繁体   中英

Generate a list of (count) Random Numbers that total to a specified average value of (avg)

  1. I'm trying to make a game which randomly generates characters classes and stats

  2. The characters class effects the amount of substats they have

  3. The first stat which is randomly generated is call overall which every class has and is an integer randomly assigned a value 1-99

  4. based on this overall number, I want to create a function which randomly generates the classes substats. Each of these classes has a different number of substats. So with this function I want to pass the overall stat to serve as (avg) the average of the list. The number of substats to serve as (count) the length of the list. And a minimum and maximum value, to prevent stats from getting to high and too low.

This is a C# application and while I can figure out for myself how to create a list of y random numbers, the averaging is proving to be difficult. I've found a solution which kind of works but it doesn't average out to a true value of the overall, just gets it within the ballpark of a few numbers of the average. I've listed that function below.

public List<int> createRandomNumberList(int avg, int count, int min, int max)
        {
            var rnd = new Random();
            var numbers = new List<int>();
            for (var i = 0; i < count; i++)
            {
                var random1 = rnd.Next(min, avg + 1);
                var random2 = rnd.Next(avg + 2, max + 1);
                var randoms = new List<int>();
                randoms.AddRange(Enumerable.Repeat<int>(random2, avg - min));
                randoms.AddRange(Enumerable.Repeat<int>(random1, max - avg));

                var generatedNumber = randoms[rnd.Next(randoms.Count)];
                numbers.Add(generatedNumber);
            }
            return numbers;
        }

Any help would be appreciated

Ok, figured out a solution that works for me. I'll post it here on the off chance it helps someone else out in the future.

static public void createRandomNumberList(int avg, int count, int min, int max)
        {
            var rnd = new Random();
            var numbers = new List<int>();
            
            for (int i = 0; i < count; i++)
            {
                // if count is 4 start at 0 random assign, 1 create value that when added to 0 and averages to avg
                if (count % 2 == 0)
                {
                    //even
                    if (i % 2 == 0)
                    {
                        //even
                        numbers.Add(rnd.Next(min, max));
                    }
                    else
                    {
                        int sum = 0;
                        //odd
                        for (int x = 0; x < numbers.Count; x++)
                        {
                            sum += numbers[x];
                        }
                        int totalstats;
                        totalstats = avg * (numbers.Count + 1);
                        int y = totalstats - sum;
                        numbers.Add(y);
                    }
                }
                // if count is 3, make first number random
                // make second number average out
                // make last number in list average out as well
                else
                {
                    if (i == count -1)
                    {
                        int sum = 0;
                        //odd
                        for (int x = 0; x < numbers.Count; x++)
                        {
                            sum += numbers[x];
                        }
                        int totalstats;
                        totalstats = avg * (numbers.Count + 1);
                        int y = totalstats - sum;
                        numbers.Add(y);
                    }
                    //even
                    else if (i % 2 == 0)
                    {
                        //even
                        numbers.Add(rnd.Next(min, max));
                    }
                    else
                    {
                        int sum = 0;
                        //odd
                        for (int x = 0; x < numbers.Count; x++)
                        {
                            sum += numbers[x];
                        }
                        int totalstats;
                        totalstats = avg * (numbers.Count + 1);
                        int y = totalstats - sum;
                        numbers.Add(y);
                    }
                }
            }

basically my solution was to randomly generate every even number, and on the odd number. I calculate what number would make the list average out. When the list has an even length this works.

With an odd count this logic has to be slightly modified or else the last number in the list wont average correctly, so on the very last loop even though its an even number, we have it average like the odds are.

Hope this helps someone!

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