Si vous utilisez Random.Range()
pour générer des valeurs, existe-t-il un moyen d'exclure certaines valeurs de la plage (par exemple: choisissez un nombre compris entre 1 et 20, mais pas entre 6 et 8)?
La meilleure façon de faire est d’utiliser votre générateur préféré pour générer un entier n
compris entre 1 et 17 puis le transformer en utilisant
if (n > 5){
n += 3;
}
Si vous échantillonnez entre 1 et 20, puis éliminez les valeurs, vous pouvez introduire des anomalies statistiques. (Par exemple, votre variance sera trop élevée si votre générateur de nombres aléatoires est un congruentiel linéaire: essayez-le et voyez.)
Donc, vous voulez réellement 17
(20 - 3) valeurs différentes
[1..5] U [9..20]
et vous pouvez implémenter quelque chose comme ceci:
// Simplest, not thread-safe
private static Random random = new Random();
...
int r = (r = random.Next(1, 17)) > 5
? r + 3
: r;
En général (et compliqué) cas, je suggère de générer un tableau de toutes les valeurs possibles et ensuite prendre L'élément de celui-ci:
int[] values = Enumerable
.Range(1, 100) // [1..100], but
.Where(item => item % 2 == 1) // Odd values only
.Where(item => !(item >= 5 && item <= 15)) // with [5..15] range excluded
//TODO: Add as many conditions via .Where(item => ...) as you want
.ToArray();
...
int r = values[random.Next(values.Length)];
Oui, vous utilisez simplement where
déclaration dans LINQ
var list = Enumerable.Range(1, 20).Where(a => a < 6 || a > 8).ToArray();
Autre moyen sans LINQ
public IEnumerable RangeBetween()
{
foreach (var i in Enumerable.Range(1, 20))
{
if (i < 6 || i > 8)
{
yield return i;
}
}
}
EDIT: Maintenant, je vois n’est pas une question C # stricte. Cela affecte Unity
et Random
. Mais pour une réponse complète, je vous propose que vous utilisez le code ci-dessus avec Enumerable.Range
et que vous l'utiliserez ensuite pour générer le numéro:
list[Random.Next(list.Length)];
Une autre méthode consiste à créer un tableau des valeurs de retour valides, puis à en sélectionner une au hasard:
void Main()
{
var rng = new Random();
var validValues = Enumerable.Range(1, 20).Except(new int[] {6, 7, 8}).ToArray();
for (int i = 0; i < 25; i++)
{
Console.Write(validValues[rng.Next(0, validValues.Length)]);
Console.Write(" ");
}
}
EDIT: Oups! Je viens de remarquer que c'était pour Unity3D, donc cet exemple pourrait ne pas être approprié. Cela fonctionne cependant avec la classe Random
standard.
Cela choisira un nombre aléatoire différent si r est compris entre 6 et 8 inclus.
int r = 0;
do
{
r = Random.Next(20);
} while (r >= 6 && r <= 8)