/************************************************/ /* Een simulatie van het Monty-Hall-probleem */ /* In een spelshow is achter twee deuren een */ /* geit verborgen, terwijl achter de derde */ /* een auto staat. Nadat de kandidaat een */ /* deur heeft gekozen (maar nog niet geopend) */ /* maakt de quizmaster (die weet wat er achter */ /* de deuren zit) een van twee andere deuren */ /* open en laat zien dat er een geit staat. */ /* De kandidaat mag nu nog een andere deur kie- */ /* zen. Deze simulatie laat zien hoe de kansen */ /* liggen als de kandidaat zijn keus wijzigt. */ /************************************************/ import java.applet.*; import java.awt.*; import java.awt.event.*; public class MontyHall extends Applet implements Runnable, MouseListener { int b, h, fg, deurMetAuto, eersteKeus, nieuweKeus, stringLengte, started, i, x, y, incr, doorQMgeopend, aantalGewonnen, deur[] = new int[4]; boolean begin; long aantalShows; final int geit=0, auto=1, maxShows=1000000; private Thread thread; Image im; Graphics gIm; public void init () { addMouseListener (this); Dimension d = getSize(); b = d.width; h = d.height; // breedte en hoogte van appletvenster x = b/15; y = h/6; incr = 44; setBackground (Color.black); } public void start () { if (thread == null) { thread = new Thread (this); thread.start(); } } public void stop () { if (thread != null) { thread.stop(); thread = null; } } public void paint (Graphics g) { if (begin) { if (aantalShows < maxShows) { aantalShows++; /*** EERST TWEE GEITEN EN EEN AUTO ***/ /*** ACHTER DRIE DEUREN VERSTOPPEN ***/ deurMetAuto = 1 + (int)(3 * Math.random()); deur[deurMetAuto] = auto; for (i=1; i<=3; i++) if (i != deurMetAuto) deur[i] = geit; /*** NU KIEST DE KANDIDAAT ***/ /*** EEN WILLEKEURIGE DEUR ***/ eersteKeus = 1 + (int)(3 * Math.random()); /*** HIERNA KIEST DE QUIZMASTER EEN DEUR ***/ /*** DIE NIET DOOR DE KANDIDAAT GEKOZEN ***/ /*** IS EN WAARACHTER OOK GEEN GEIT ZIT. ***/ do doorQMgeopend = 1 + (int)(3 * Math.random()); while (deur[doorQMgeopend]==auto || doorQMgeopend==eersteKeus); /*** NU LATEN WE DE KANDIDAAT ***/ /*** DE ANDERE DEUR 'KIEZEN'. ***/ for (i=1; i<=3; i++) if (i != eersteKeus && i != doorQMgeopend) nieuweKeus = i; /*** TEN SLOTTE WORDT ER 1 BIJ HET AANTAL AUTO'S OPGETELD ALS ***/ /*** ER INDERDAAD EEN AUTO ACHTER DE NIEUW GEKOZEN DEUR STAAT. ***/ if (deur[nieuweKeus] == auto) aantalGewonnen++; } if (aantalShows%100 == 0 || aantalShows<=1000 && aantalShows%10 == 0) { if (im == null) { im = createImage (b, h); gIm = im.getGraphics(); } String s = "Gewonnen auto's per show:"; fg = bepaalFont (g, 5*b/9, s); Font f = new Font("Verdana", Font.PLAIN, fg); introScherm (gIm); FontMetrics fm = getFontMetrics(f); stringLengte = fm.stringWidth(s); gIm.setColor (Color.yellow); gIm.setFont (new Font("Verdana", Font.BOLD, fg)); gIm.drawString ("Het Monty Hall probleem", x, y); gIm.setFont (f); gIm.drawString ("Aantal shows:", x, y+incr); gIm.drawString ("Aantal gewonnen auto's:", x, y+2*incr); gIm.drawString (s, x, y+3*incr); gIm.setColor (Color.black); gIm.fillRect (x+stringLengte+1, y+h/20, 2*b/9, 2*h/3); gIm.setFont (new Font("Verdana", Font.PLAIN, fg)); gIm.setColor (Color.yellow); gIm.drawString (""+aantalShows, x+stringLengte+10, y+incr); gIm.drawString (""+aantalGewonnen, x+stringLengte+10, y+2*incr); gIm.drawString (format((double)aantalGewonnen/aantalShows), x+stringLengte+10, y+3*incr); if (aantalShows == maxShows) gIm.drawString ("== klik voor nieuwe simulatie ==",x,h-fg-10); if (im != null) g.drawImage (im, 0, 0, null); } } else { if (im == null) { im = createImage (b, h); gIm = im.getGraphics(); } introScherm(gIm); String s = "Het Monty Hall probleem"; fg = bepaalFont (g, 2*b/3, s); Font f = new Font("Verdana", Font.PLAIN, fg); gIm.setFont (f); gIm.setColor (Color.yellow); gIm.setFont (new Font("Verdana", Font.BOLD, fg)); gIm.drawString (s, x, y+incr); if (im != null) g.drawImage (im, 0, 0, null); } } void introScherm (Graphics g) { g.setColor (Color.black); g.fillRect (0,0,b,h); g.setColor (Color.green); for (i=0;i<5;i++) g.drawRoundRect (i,i,b-2*i,h-2*i,5,5); } public void run () { for (;;) { repaint(); } } public void update (Graphics g) { paint(g); } int bepaalFont (Graphics g, int breedte, String s) { FontMetrics fm; int fg = 5, stringBreedte; do { fg++; g.setFont (new Font ("Arial",Font.PLAIN,fg)); fm = g.getFontMetrics(); stringBreedte = fm.stringWidth(s); } while (stringBreedte < breedte); return fg - 1; } String format (double d) { long tmp = (long)(10000 * d + 0.05); return (""+(double)tmp/10000).replace('.',','); } public void mousePressed (MouseEvent evt) { if (aantalShows == 0 || aantalShows == maxShows) { begin = true; aantalShows = aantalGewonnen = 0; } } public void mouseReleased (MouseEvent evt){} public void mouseEntered (MouseEvent evt){} public void mouseExited (MouseEvent evt){} public void mouseClicked (MouseEvent evt){} }