Random getallen genereren

Willekeurige (random) getallen genereren in je code kan leuk zijn om de gebruiker een interactievere ervaring te geven. Beeld je in dat je monsters steeds dezelfde weg zouden bewandelen of dat er steeds op hetzelfde tijdstip een orkaan op je stad neerdwaalt. Of wat de denken van een programma dat steeds dezelfde wiskunde opgaven genereert? SAAI!

Random generator

De Random-bibliotheek laat je toe om willekeurige gehele en komma-getallen te genereren. Je moet hiervoor twee zaken doen:

  1. Maak eenmalig een Random-generator object aan.
  2. Roep de Next methode aan op dit object telkens je een nieuw willekeurig getal nodig hebt.

Als volgt:

Random randomGenerator = new Random();
int mijnLeeftijd = randomGenerator.Next();

De eerste stap dien je maar 1 keer te doen. De naam die je het generatorobject geeft (hier randomGenerator) mag je kiezen. Dit is een variabele en moet dus aan de identifier regels voldoen.

Vanaf nu kan je telkens aan het generatorobject een nieuw getal vragen door middel van de Next-methode.

Volgende code toont bijvoorbeeld 3 random getallen op het scherm:

Random myGen = new Random();

int getal1 = myGen.Next();
int getal2 = myGen.Next();
int getal3 = myGen.Next();
Console.WriteLine(getal1);
Console.WriteLine(getal2);
Console.WriteLine(getal3);

Uiteraard mag dit ook

Console.WriteLine(myGen.Next());
Console.WriteLine($"Nog een getal: {myGen.Next()}");
Tip

De new Random() code is iets wat in hoofdstuk 9 en verder volledig uit de doeken zal gedaan worden. Lig er dus nog niet van wakker.1

Next mogelijkheden

Je kan de Next methode ook 2 parameters meegeven, namelijk de grenzen waarbinnen het getal moet gegenereerd worden. De tweede parameter is exclusief dit getal zelf. Wil je dus een willekeurig geheel getal tot en met 10 dan schrijf je 11, niet 10, als tweede parameter:

Enkele voorbeelden:

Random someGenerator = new Random();
int a = someGenerator.Next(0,11); //getal tussen 0 tot en met 10
int b = someGenerator.Next(55,100); //getal tussen 55 tot en met 99
int c = someGenerator.Next(0,b); //getal tussen 0 tot en met (b-1)
Belangrijk

De ondergrens telt wél mee, de bovengrens niet. Next(0, 11) geeft dus een getal van 0 tot en met 10, maar nooit 11. Onthoud de vuistregel: wil je een getal tot en met X, schrijf dan X+1 als tweede parameter.

Genereer kommagetallen met NextDouble

Met de NextDouble methode kan je kommagetallen genereren tussen 0.0 en 1.0 (1.0 zal niet gegenereerd worden).

Wil je een groter kommagetal dan zal je dit gegenereerde getal moeten vermenigvuldigen naar de range die je nodig hebt. Stel dat je een getal tussen 0.0 en 10.0 nodig hebt, dan schrijf je:

Random myRan = new Random();
double randomGetal = myRan.NextDouble() * 10.0;

Je vermenigvuldigt eenvoudigweg je gegenereerde getal met het bereik dat je wenst (10.0 in dit geval)

En wat als je een kommagetal tussen 5.0 en 12.5 wenst? Als volgt:

Random myRan = new Random();
double randomGetal = 5.0 + (myRan.NextDouble() * 7.5);

Visualisatie van hoe je het bereik van Random kan aanpassen (rechte is niet op schaal)

Visualisatie van hoe je het bereik van Random kan aanpassen (rechte is niet op schaal)

Je bereik is 7.5, namelijk 12.5 - 5.0 en vermenigvuldig je het resultaat van je generator hiermee. Vervolgens verschuif je dat bereik naar 5 en verder door er 5 bij op te tellen. Merk op dat we de volgorde van berekeningen sturen met onze ronde haakjes.

Je hebt in je programma maar één Random-generator nodig. Maak die één keer aan en vraag er daarna al je getallen aan. Een Random is een pseudo-willekeurige getallengenerator: hij rekent een reeks getallen uit die willekeurig lijkt, vertrekkend van een startwaarde, de zogenaamde seed.

In vorige edities van dit boek stond hier een grote waarschuwing: maak nooit twee generators vlak na elkaar aan, want dan krijg je twee keer dezelfde getallen. In het oude .NET Framework was dat ook echt zo. Een nieuwe Random nam de klok van de computer als seed, en die klok verspringt maar om de zoveel milliseconden. Twee generators die in hetzelfde tikje aangemaakt werden, kregen dus dezelfde seed en spuwden exact dezelfde reeks uit. Een dobbelsteen die in een lus telkens een nieuwe Random maakte, gooide zo tien keer na elkaar hetzelfde getal.

In het huidige .NET krijgt elke nieuwe Random een eigen, willekeurige seed. Die bug bestaat dus niet meer, maar in oudere code en op fora kom je de waarschuwing nog geregeld tegen.

Eén generator houdt je code eenvoudig, en je hebt het ook nodig zodra je met een vaste seed wil werken (zie verderop). Zo dus:

Random a = new Random();
Console.WriteLine(a.Next());
Console.WriteLine(a.Next());

Wil je toch dezelfde willekeurige reeks getallen na elkaar genereren telkens je je programma opstart (bijvoorbeeld om je code te testen met steeds dezelfde reeks getallen) dan kan je bij het aanmaken van je generator ook een parameter meegeven die als seed zal werken.

In het volgende voorbeeld zal generator a steeds dezelfde reeks willekeurige getallen genereren, telkens je je programma uitvoert. De waarde die je meegeeft moet uiteraard niet 666 zijn. Ieder getal dat je meegeeft is een andere seed:

Random a = new Random(666);
Console.WriteLine(a.Next());

Balatro-spelers in the house? Minecrafters misschien? Die term seed kom je in games voortdurend tegen, en dat is letterlijk deze seed. Omdat de generator vanaf een bepaalde startwaarde altijd exact dezelfde reeks getallen uitspuwt, ligt met die ene waarde je hele wereld vast: elk dorp, elke grot, elke erts-ader.

Vandaar dat je in Minecraft je seed aan iemand anders kan doorgeven, en die op zijn eigen pc precies jouw wereld terugkrijgt. Er zijn hele forums waar mensen niets anders doen dan goeie seeds uitwisselen.


  1. Sinds .NET 6 bestaat er ook Random.Shared, een kant-en-klare gedeelde generator die je zonder new kan gebruiken (bv. Random.Shared.Next(0, 11)). Dat lost meteen het probleem op van meerdere generators met dezelfde seed (zie verderop). In dit boek houden we het bij new Random() omdat we new later toch nodig hebben, maar in echte code is Random.Shared vaak de betere keuze.↩︎