Tot nu toe deed je programma altijd precies hetzelfde voor dezelfde invoer. Maar
soms wil je net iets onvoorspelbaars: een dobbelsteen die rolt, een
willekeurige kleur, of een computer die een getal kiest dat jij moet raden. Voor
zulke toevalsgetallen heeft C# de klasse Random.
Om willekeurige getallen te kunnen genereren, maak je eerst een instantie van
de klasse Random. Dat doe je met het sleutelwoord new:
Random random = new Random();
Maak je
Random-object één keer aan en hergebruik het. Dit is meer dan een stijlkwestie. EenRandom-object berekent zijn getallen vanuit een startpunt, een seed. Dezelfde seed geeft altijd exact dezelfde reeks getallen. In oudere versies van C# — en in heel wat andere talen — komt die seed van de klok, en die klok tikte niet fijn genoeg: maak je in een snelle lus telkens een nieuwRandom-object aan, dan worden ze allemaal binnen dezelfde klok-tik aangemaakt en krijgen ze dus precies dezelfde seed. En met dezelfde seed levert elk object dezelfde reeks: je “toeval” geeft dan elke keer hetzelfde resultaat. In moderne .NET krijgt elkRandom-object automatisch een eigen seed, dus die valkuil merk je daar meestal niet. Toch maak je je object best één keer aan, bovenaan je programma, en hergebruik je het. Elkenew Random()maakt namelijk een nieuw object aan in het geheugen; doe je dat telkens opnieuw in een lus, dan verspil je geheugen aan objecten die je meteen weer weggooit. En één generator die je hergebruikt levert bovendien één lange, nette reeks in plaats van veel losse kleintjes. Bonus: zo blijf je meteen ook veilig in oudere code of andere talen.
Eenmaal je een random-object hebt, vraag je er een willekeurig geheel getal aan
met de functie Next. Je geeft daarbij twee grenzen mee:
getal = random.Next(1, 11);
Heel belangrijk: de ondergrens is inbegrepen, maar de bovengrens is dat
NIET. random.Next(1, 11) geeft dus een willekeurig geheel getal tussen 1 en
10 (de 11 zelf zit er niet bij). Wil je dus een getal van 1 tot en met 10,
dan schrijf je random.Next(1, 11).
| Aanroep | Mogelijke resultaten |
|---|---|
random.Next(1, 11) | 1, 2, 3, ..., 10 |
random.Next(1, 7) | 1, 2, 3, 4, 5, 6 (een dobbelsteen) |
random.Next(0, 2) | 0 of 1 (kop of munt) |
random.Next(0, 100) | 0, 1, 2, ..., 99 |
We zetten alles samen in een klein programma dat een willekeurig getal tussen 1 en 10 kiest en toont:
// variabelen declareren
int getal;
// instantie van de klasse Random (slechts 1 keer aanmaken!)
Random random = new Random();
// een willekeurig getal opvragen
// ondergrens 1 is inbegrepen, bovengrens 11 is dat NIET
getal = random.Next(1, 11);
// resultaat tonen
Console.WriteLine("gekozen getal " + getal);
Elke keer dat je dit programma uitvoert, krijg je (vermoedelijk) een ander getal te zien, bijvoorbeeld:
gekozen getal 7
en bij een volgende uitvoering:
gekozen getal 3
Omdat de uitvoer telkens anders is, kan je dit soort programma’s niet meer testen door precies te vergelijken met één verwachte uitvoer. In de oefeningen hierna lossen we dat op: soms controleren we de eigenschappen van de willekeurige uitvoer (komt ‘Juist’ ongeveer 1 keer op 10 voor?), en soms lezen we het geheime getal als invoer in plaats van het willekeurig te kiezen, zodat het spel toch te controleren valt.