-1

What I'm doing is generating a 5x5 grid filled with random buttons. The issue is, the random int I am using doesn't update frequently enough to make it truly random it will display the entire grid as one button type 95% of the time and split between 2 buttons 5% of the time. I need each cell to be randomly chosen. Here is my code

private void btnFillGrid_Click(object sender, RoutedEventArgs e) {
        stkGameBoardColumnOne.Children.Clear();
        stkGameBoardColumnTwo.Children.Clear();
        stkGameBoardColumnThree.Children.Clear();
        stkGameBoardColumnFour.Children.Clear();
        stkGameBoardColumnFive.Children.Clear();
        for (int i = 0; i < 25; i++) {
            Random rnd = new Random();
            Button btnMapCell = new Button();
            Potion cellPotion = new Potion("", 0, "");
            btnMapCell.Foreground = new SolidColorBrush(Colors.White);

            int randomPotion = rnd.Next(0, 4);
            if (randomPotion == 0) {
                //Potion cellPotion = new Potion("Small Healing Potion", 25, "green");
                cellPotion.Name = "Small Healing Potion";
                cellPotion.AffectValue = 25;
                cellPotion.Color = "green";
                btnMapCell.Background = new SolidColorBrush(Colors.Green);
            }
            else if (randomPotion == 1) {
                //Potion cellPotion = new Potion("Medium Healing Potion", 50, "blue");
                cellPotion.Name = "Medium Healing Potion";
                cellPotion.AffectValue = 50;
                cellPotion.Color = "blue";
                btnMapCell.Background = new SolidColorBrush(Colors.Blue);
            }
            else if (randomPotion == 2) {
                //Potion cellPotion = new Potion("Large Healing Potion", 100, "purple");
                cellPotion.Name = "Large Healing Potion";
                cellPotion.AffectValue = 100;
                cellPotion.Color = "purple";
                btnMapCell.Background = new SolidColorBrush(Colors.Purple);
            }
            else if (randomPotion == 3) {
                //Potion cellPotion = new Potion("Extreme Healing Potion", 200, "red");
                cellPotion.Name = "Extreme Healing Potion";
                cellPotion.AffectValue = 200;
                cellPotion.Color = "red";
                btnMapCell.Background = new SolidColorBrush(Colors.Red);
            }                
            btnMapCell.Content = "";
            btnMapCell.Width = 75;
            btnMapCell.Height = 75;
            btnMapCell.Content = cellPotion.Name + "\r\n" + "(" + cellPotion.AffectValue + ")";
            if (i >= 0 && i < 5) {
                stkGameBoardColumnOne.Children.Add(btnMapCell);
            }
            else if (i >= 5 && i < 10) {
                stkGameBoardColumnTwo.Children.Add(btnMapCell);
            }
            else if (i >= 10 && i < 15) {
                stkGameBoardColumnThree.Children.Add(btnMapCell);
            }
            else if (i >= 15 && i < 20) {
                stkGameBoardColumnFour.Children.Add(btnMapCell);
            }
            else if (i >= 20 && i < 25) {
                stkGameBoardColumnFive.Children.Add(btnMapCell);
            }
        }
    }

Here are some pictures of how it populates the grid.

https://i.stack.imgur.com/7hZYW.jpg

Irshad
  • 3,071
  • 5
  • 30
  • 51
kalenpw
  • 695
  • 3
  • 10
  • 34
  • Sorry about the duplicate I searched and couldn't find anything. I can delete the question if need be. – kalenpw Mar 08 '16 at 02:57

3 Answers3

1

Don't create the random class multiple times:

for (int i = 0; i < 25; i++) {
     Random rnd = new Random(); //don't do this

but use it multiple times:

Random rnd = new Random(); //declare this once, somewhere...

//and use it multiple times:
for (int i = 0; i < 25; i++) {
    int newrand = rnd.Next(0, upperlimit);
Ian
  • 30,182
  • 19
  • 69
  • 107
  • Yep this did the trick, thanks! – kalenpw Mar 08 '16 at 02:56
  • @kalenpw do you know that new Random use the current time as its seed value? ;) as long as the seed value does not change (because the time difference between two instances creation is small), then it will always generate the same pattern, thus you got the duplicates.. – Ian Mar 08 '16 at 02:58
1

By using the line Random rnd = new Random(); you are creating an object of the Random class. If you define it in loop each iteration will create a new object, so Define Random outside the Loop; and call rnd.Next(LowerBound,upperBound); to get the next random number;

 Random rnd = new Random();
 for (int i = 0; i < 25; i++) {
 int randomPotion = rnd.Next(0, 4);
 // Iterating content
 }

Note: Random.Next(Int32, Int32): A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.

sujith karivelil
  • 28,671
  • 6
  • 55
  • 88
0

You're initializing and seeding a new PRNG each time through the loop. System.Random() is a deterministic PRNG, and the default constructor seeds it with a time-based value. Since the system clock is not advancing enough between reseeds, you are ending up with the same value.

From the documentation of System.Random..ctor() :

The default seed value is derived from the system clock and has finite resolution. As a result, different Random objects that are created in close succession by a call to the default constructor will have identical default seed values and, therefore, will produce identical sets of random numbers. This problem can be avoided by using a single Random object to generate all random numbers. You can also work around it by modifying the seed value returned by the system clock and then explicitly providing this new seed value to the Random(Int32) constructor. For more information, see the Random(Int32) constructor.

You need to create one instance and reuse it:

Random rnd = new Random();

for (int i = 0; i < 25; i++) 
{
    //...
    int randomPotion = rnd.Next(0, 4);
    //...
}
lc.
  • 113,939
  • 20
  • 158
  • 187