Случайный, не очень случайный, со случайным классом на Windows Phone 7 - PullRequest
2 голосов
/ 05 октября 2011

Итак, вот сделка.

Я установил приложение для wp7, где есть массив с 50 кавычками.Когда пользователь нажимает кнопку, отображается случайная цитата из массива.Проблема в том, что кавычки всегда появляются в одном и том же порядке.Например, кавычки 1-50.Порядок всегда 2, 4, 20, 31, 10, ... Есть ли способ решить эту проблему?Я хочу, чтобы при каждом использовании приложения появлялись случайные и разные цитаты.

Вот код:

    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];

        });
    }

Ответы [ 8 ]

14 голосов
/ 05 октября 2011

Вы создаете свой первый экземпляр Random с Random(100), то есть постоянным начальным числом. Так что он всегда будет возвращать одну и ту же последовательность. Это, в свою очередь, означает, что начальное число вашего второго экземпляра Random также будет постоянным, и все значения, которые оно возвращает, тоже.

Просто создайте отдельный экземпляр Random с конструктором по умолчанию, т.е. new Random(). Это зависит от времени и, таким образом, вероятно, будет отличаться при разных запусках программы.

Предупреждение. Поскольку время изменяется только каждые несколько миллисекунд (1-16 мс на типичных компьютерах с Windows), если вы создадите несколько экземпляров Random с конструктором по умолчанию в быстрой последовательности, они, скорее всего, будут возвращать одну и ту же последовательность.

Другая распространенная ошибка заключается в том, что Random не является потокобезопасным. Но не похоже, что вы столкнетесь с этой проблемой.

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];

    });
}
4 голосов
/ 05 октября 2011

Вы явно указываете семя:

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

r1 всегда будет использовать одно и то же семя (100), поэтому r1.Next(0, 50) всегда будет давать одно и то же семя, поэтому r2 всегда будет использовать одно и то же семя. У вас нет реальной случайности.

Вы должны создать один экземпляр Random и использовать его повторно, при этом отметив, что Random не является потокобезопасным. (Если вы собираетесь использовать свой экземпляр только из потока пользовательского интерфейса, это нормально.)

См. Мою статью о генерации случайных чисел в .NET для получения дополнительной информации.

2 голосов
/ 05 октября 2011

Хорошо, вы инициализировали начальное число, которое всегда будет 100 на вашем рандомизаторе r1 Это, конечно, означает, что в соответствии с семенем вы всегда будете получать одинаковые номера. Это означает, что ваш r2 всегда инициализируется одним и тем же начальным числом, поэтому оба r1 и r2 всегда одинаковы.

Случайные числа невозможны для ПК, как бы странно это ни звучало. Поэтому вам нужно «случайное» число для инициализации вашего генератора случайных чисел.

Короче говоря. Удалите первый случайный объект и используйте пустой конструктор для второго.

Начальное значение по умолчанию получено из системных часов и имеет конечное разрешение

2 голосов
/ 05 октября 2011

Вы не должны заполнять генератор случайных чисел фиксированным начальным числом, если вы не хотите повторяемых последовательностей:

new Random(100);

должно быть

new Random();
1 голос
/ 05 октября 2011

Семя всегда одинаковое, даже инициализация из другого случайного числа!

Попробуйте посеять по-другому:

new Random(unchecked((int) (DateTime.Now.Ticks)));
1 голос
/ 05 октября 2011

Вы сеете это одним и тем же семенем каждый раз.Просто используйте new Random().Если это не доступно в WP7, используйте производную текущего времени в качестве начального числа.

0 голосов
/ 05 октября 2011

Просто используйте следующий код;

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 голосов
/ 05 октября 2011

У вас такое же семя.Используйте что-то вроде числа, сгенерированного из текущей даты

r1 = new Random(DateTime.Now.Year + DateTime.Now.Month + DateTime.Now.Day + DateTime.Now.Second); // etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...