2010-09-25 4 views
4

J'ai une classe qui représente une pièce, qui peut être retournée avec la méthode Coin.Flip(). Flip() utilise random.Next (2); pour obtenir un 0 ou un 1 représentant des têtes ou des queues. Cela fonctionne bien .. en quelque sorte.Problème avec C# Classe aléatoire

Pour le programme, j'ai besoin de 2 pièces, que je fais, disons coin1 et coin2.

coin2 doit toujours être retourné directement après coin1, que je peux faire avec:

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

Cela devrait fonctionner, non?

Eh bien, ce n'est pas le cas! Chaque fois que je lance ces deux lignes de code, les deux pièces finissent avec les mêmes valeurs les unes que les autres!

La valeur nominale est stockée face à l'intérieur de la classe Coin, qui est défini comme suit:

private int face; 

Je ne vois rien de mal à ce que je l'ai fait, mais chaque fois que je lance le code, ils se retrouvent identiques.

Oh, est aléatoire également définie dans la classe Coin et comme ceci:

private Random random = new Random(); 

Merci pour votre aide!

EDIT: Voici Flip(), cela fonctionne maintenant que le statique est statique.

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

Pouvez-vous montrer l'implémentation de Flip? –

+0

Note: si vous le faites statique, vous devez également le synchroniser ou le rendre spécifique au thread, car il n'est pas listé comme thread-safe –

Répondre

6

Les générateurs de nombres aléatoires ont besoin d'une valeur de départ. Les RNG avec une graine identique produiront le même flux de nombres aléatoires.

Par défaut, System.Random utilise l'heure actuelle en tant que germe. Si vous créez deux instances presque immédiatement l'une après l'autre, elles auront toutes les deux la même valeur de temps et produiront donc la même séquence de nombres aléatoires. Vous pouvez déplacer le Random vers un membre statique afin que tous les Coin partagent le même RNG, mais sachez que System.Random n'est pas documenté comme threadsafe, donc vous ne pouvez pas utiliser plusieurs Coin sur des threads différents sans une certaine synchronisation.

+0

Merci mon pote, j'y pensais juste après avoir posté. Je vais essayer. – Azz

+0

Ça s'entend mieux. Merci encore! – Azz

+0

Cela peut être une bonne idée de créer une surcharge sur votre Coin() qui vous permet également de transmettre un flux aléatoire, et le constructeur par défaut prend le flux aléatoire statique.De cette façon, vous pouvez résoudre tous les problèmes de synchronisation en créant des rng séparés pour chaque thread – cordialgerm

3

Je suppose que vous voulez probablement redéfinir votre variable random, au niveau de la classe, comme:

private static Random random = new Random(); 

Cela fera appel à tous les Flip() utilisent le même générateur, et non réensemencer en permanence. Si vous créez l'instance Random à chaque appel et que vous appelez deux fois très proches, vous pouvez obtenir la même origine, et donc les mêmes valeurs.