开发者

Random not so random, with random class on Windows Phone 7

开发者 https://www.devze.com 2023-04-11 10:58 出处:网络
So, here\'s the deal. I\'ve set up an app for wp7 where there\'s an array with 50 quotes. When the user clicks a button, a random quote from the array is showed. Problem is, the quotes always appears

So, here's the deal.

I've set up an app for wp7 where there's an array with 50 quotes. When the user clicks a button, a random quote from the array is showed. Problem is, the quotes always appears in the same order. For example, quot开发者_开发知识库es are 1-50. The order is always 2, 4, 20, 31, 10,... Is there a way to solve this? I want that a random and different quote appear every time i use the app.

Here's the code:

    string[] listaCantadas;
    Random r1, r2;

    public MainPage()
    {
        InitializeComponent();

        listaCantadas = new string[]
        {"//set of quotes
        };

        r1 = new Random(100);
        r2 = new Random(r1.Next(0, 50));
    }

    //click event for display a random quote

            int Cantada = r2.Next(0, listaCantadas.Length - 1);
            txtBlockCantada.Text = listaCantadas[Cantada];

        });
    }


You create your first instance of Random with Random(100) i.e. a constant seed. So it will always return the same sequence. Which in turn means that the seed of your second instance of Random will be constant too, and all the values it returns too.

Just create a single instance of Random with the default constructor, i.e. new Random(). This is seeded with the time, and thus will be likely different between different runs of the program.

Warning: Since the time only changes every few milliseconds (1-16ms on typical windows computers) if you create several instances of Random with the default constructor in quick succession they will most likely all return the same sequence.

Another common pitfall is that Random isn't thread-safe. But it doesn't look like you will hit this problem.

string[] listaCantadas;
Random r;//No need for more than one instance

public MainPage()
{
    InitializeComponent();

    listaCantadas = new string[]
    {"//set of quotes
    };

    r = new Random();
}

//click event for display a random quote

        int Cantada = r.Next(0, listaCantadas.Length - 1);
        txtBlockCantada.Text = listaCantadas[Cantada];

    });
}


You're explicitly stating the seed:

r1 = new Random(100);
r2 = new Random(r1.Next(0, 50));

r1 will always use the same seed (100), so r1.Next(0, 50) will always give the same seed, so r2 will always use the same seed. You have no real randomness.

You should be creating a single instance of Random and reusing it - whilst noting that Random is not thread-safe. (If you're only going to use your instance from the UI thread, that's fine.)

See my article on random number generation in .NET for more information.


You shouldn't seed the random generator with a fixed seed unless you wanted repeatable sequences:

new Random(100);

should be

new Random();


Well you initialized the seed to always be 100 on your r1 randomizer. That of course means that acording to the seed you will get always the same numbers. Which means your r2 is always initialized with the same seed, so both r1 and r2 are always the same.

Random numbers are impossible for a PC, as strange as this sounds. So you need a "random" number to initialize your random generator.

Long story short. Remove the first random object and use the empty constructor on the second.

The default seed value is derived from the system clock and has finite resolution


You're seeding it with the same seed every time. Just use new Random(). If that's not available on WP7, use a derivative of the current time as a seed.


The seed is always the same, even initialising from another random!

Try seeding another way:

new Random(unchecked((int) (DateTime.Now.Ticks)));


You have the same seed. Use something like a number generated from the current date

r1 = new Random(DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + DateTime.Now.Second); // etc


Simply use the following code;

Random r = new Random();

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] listaCantadas = 
            {
                "q1",
                "q2",
                "q3",
                "q4",
                "q5"
            };

            //click event for display a random quote
            txtBlockCantada.Text = listaCantadas[r.Next(0, listaCantadas.Length)]; 
        }
0

精彩评论

暂无评论...
验证码 换一张
取 消