2010-09-25 3 views
4

У меня есть класс, представляющий монету, которую можно перевернуть с помощью метода Coin.Flip(). Flip() использует random.Next (2); чтобы получить либо 0, либо 1, представляющие головы или хвосты. Это работает хорошо .. вроде.Проблема с C# Случайный класс

Для программы мне нужно иметь 2 монеты, которые я делаю, скажем, coin1 и coin2.

coin2 всегда должна быть перевернута сразу после coin1, что я могу сделать с:

coin1.Flip(); 
coin2.Flip(); 

Это должно работать, не так ли?

Ну, это не так! Каждый раз, когда я запускаю эти две строки кода, обе монеты заканчиваются одинаковыми значениями друг друга!

Номинальная стоимость хранится в лице внутри класса монет, которая определяется следующим образом:

private int face; 

Я не вижу ничего плохого с тем, что я сделал, но каждый раз, когда я бегу кода, они заканчиваются одинаковыми.

Ой, а также случайная определяется в классе монет, а так:

private Random random = new Random(); 

Спасибо за вашу помощь!

EDIT: Вот Flip(), теперь он работает, но случайный статичен.

public void Flip() { 
     face = random.Next(2); 
    } 
+0

Можете ли вы продемонстрировать реализацию Flip? –

+0

Примечание: если вы статируете его, вы должны также синхронизировать его или сделать его конкретным потоком, поскольку он не указан как потокобезопасный. –

ответ

6

Генераторы случайных чисел нуждаются в начальном значении. RNG с идентичным семенем будет генерировать один и тот же поток случайных чисел.

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

Вы можете переместить Случайное в статический член, чтобы все монеты имели один и тот же RNG, но имейте в виду, что System.Random не документируется как потокобезопасный, поэтому вы не можете использовать несколько монет в разных потоках без какой-либо синхронизации.

+0

Спасибо, я подумал об этом сразу после того, как я разместил его. Сделаю это. – Azz

+0

Это кучи лучше. Еще раз спасибо! – Azz

+0

Возможно, было бы неплохо создать перегрузку для вашей Coin(), которая также позволит вам передавать случайный поток, а конструктор по умолчанию принимает статический случайный поток.Таким образом, вы можете решить любые проблемы синхронизации, создавая отдельные rng для каждого потока. – cordialgerm

3

Я думаю, что вы, вероятно, захотите пересмотреть свой random переменную, на уровне класса, как:

private static Random random = new Random(); 

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