8. Werken met random getallen

Als je een spelletje wil maken, is het wat saai als het telkens op dezelfde manier verloopt. Een goede manier om het steeds weer een beetje anders te maken krijgen we als we zogenaamde random getallen gebruiken.

In Java kun je een willekeurig getal maken met behulp van de methode random(), die hoort bij de klasse Math. Deze methode levert een willekeurig gebroken getal op dat minimaal 0 is en kleiner is dan 1. We zouden als volgt een willekeurig getal r kunnen maken:

double r = Math.random();

Hierna zou r bijvoorbeeld de volgende waarde kunnen hebben: 0.4303072576758019

Vaak wil je echter geen gebroken getallen hebben, maar bijvoorbeeld een soort dobbelsteen (dus een heel getal van 1 t/m 6). Laten we eens proberen een dobbelsteen te imiteren.

We kunnen bovenstaande expressie eerst met 6 vermenigvuldigen:

double r = 6 * Math.random();

Het geproduceerde getal r is nog steeds een gebroken getal en het minimum is nog altijd 0, maar het maximum is nu bijna 6.

Het is mogelijk het breukdeel van dit getal af te kappen met een zogenaamde cast. Een cast ziet eruit als een type tussen haakjes, bijvoorbeeld iets als (char)a of (int)b en verandert het ene type in het andere. Dat kan zo:

int r = (int)(6*Math.random());

We houden nu een heel getal over dat minimaal 0 is en maximaal 5. Een dobbelsteen moet echter minimaal 1 en maximaal 6 zijn. Dit kunnen we makkelijk verkrijgen door er 1 bij op te tellen, dus zo:

int dobbelsteen = (int)(6*Math.random()) + 1;

Nu we een manier kennen om willekeurige getallen te maken, zouden we ook een eenvoudig spelletje in elkaar kunnen zetten. Het spel dat we gaan maken werkt zo: het programma "bedenkt" een willekeurig getal van 1 t/m 100, en de speler mag het proberen te raden.

Het programma kent een aantal stadia, zoals:

  1. uitleg van het spel
  2. het raden waarbij het programma antwoordt dat het getal te klein / te groot is
  3. getal geraden; spel kan opnieuw beginnen
Om deze stadia bij te houden zullen we de variabele stadium gebruiken, die we telkens gaan verhogen. We zouden de waarde van stadium als volgt kunnen controleren:

if (stadium == 1)
   tekst = "Dit is stadium 1";
else if (stadium == 2)
   tekst = " Dit is stadium 2";
else
   tekst = "Overige stadia";

Java heeft voor dit soort gevallen een constructie die korter is en ook overzichtelijker oogt. Deze ziet er als volgt uit:

switch (stadium) {
   case 1: tekst = " Dit is stadium 1"; break;
   case 2: tekst = " Dit is stadium 2"; break;
   default: tekst = "Overige stadia"; 
}

De toevoeging break voorkomt dat na een 'hit' alle volgende regels worden uitgevoerd. De expressie default houdt alle andere waarden in, in dit geval alle andere waarden dan 1 en 2.

De speler wil misschien ook wel weten in hoeveel keer hij het getal geraden heeft. Daarvoor gebruiken we de variabele keer zodat we na afloop een mededeling kunnen doen als:

Getal geraden in 7 keer.

Als je een getal wilt gaan intikken, is het wel handig als de cursor in het tekstvak staat en de speler niet het vorige getal hoeft uit te wissen. Dat doen we met:

vak.setText("");    // een 'lege' string
vak.requestFocus(); // set cursor in tekstvak

Ten slotte zou het wel aardig zijn als we na het raden met één klik opnieuw kunnen beginnen met een getal dat niet hetzelfde is. Dat doen we aldus:

do {
geheim = 1+(int)(100*Math.random());
} while (x == geheim);

Het programma moet net zo lang een getal van 1 t/m 100 in geheim blijven stoppen tot het ongelijk is aan x (het laatst geraden getal). Meestal zullen die twee ongelijk zijn, dus die lus zal gewoonlijk niet meer dan eenmaal doorlopen worden.

De methode Integer.parseInt() om een string om te zetten in een variabele van het type int bespreken we hier even niet. Ook laten we voorlopig de methode onbesproken om fouten op te vangen (met try ... catch) -- als bijvoorbeeld een gebroken getal of zomaar een tekst wordt ingetikt. We komen daarop terug in deel 10.

En dan is hier het volledige programma:

import java.applet.*;
import java.awt.*;
public class Raden extends Applet {
   TextField vak;
   Button knop;
   String tekst="Ik bedenk 'n getal (1-100)";
   int ronde = 1, keer, x, geheim;
    public void init() {
       setBackground (Color.white);
       vak = new TextField(10);
       knop = new Button ("Klik");
       add (vak);
       add (knop);
       geheim = 1+(int)(100*Math.random());
   }
   public void paint (Graphics g) {
       g.drawString (tekst,40,100);
       g.drawString ("Klik om door te gaan",40,160);
       vak.setText("");
       vak.requestFocus();
   }
   public boolean action (Event e, Object o) {
      if (e.target == knop) {
         ronde++;
         switch(ronde) {
            case 1:
              tekst="Ik bedenk 'n getal (1-100)";break;
            case 2:
              tekst="Probeer jij het te raden."; break;
            case 3:
              tekst="Tik een getal in ..."; break;
            default:
              try {
                 String woord = vak.getText();
                 x = Integer.parseInt(woord);
              } catch(java.lang.NumberFormatException exc){
                 tekst = "geen correct getal ... ";
                 repaint();
                 return false;
                }
              keer++;
              if (x > geheim)
                 tekst=x+" is te hoog, probeer nog eens.";
              else if (x < geheim)
                 tekst=x+" is te laag, probeer nog eens.";
              else {
                 tekst=x+" geraden in " + keer + " keer.";
                 ronde = keer = 0;
                 do {
                    geheim = 1+(int)(100*Math.random());
                 } while (x == geheim);
              }
         }
         repaint();
         return true;
      }
      return false;
   }
}

   

Opdracht 8.1 

Schrijf een applet waarin na het klikken op een knop telkens het volgende van tenminste vijf spreekwoorden of gezegdes worden getoond. Na het vijfde begint het programma weer met spreekwoord 1.

Opdracht 8.2

Herschrijf de applet Raden zo dat de mens het getal bedenkt en dat de computer moet proberen het te raden. Je kunt drie knoppen maken die Hoger, Lager en Correct heten. Zorg dat het spel gestopt wordt als de mens vals speelt (zie hieronder).

         

   

(c) 2003-2008, Thomas J.H.Luif