/********************************************/ /* Simulation of Monty Hall problem */ /* In a gameshow there are three doors. Two */ /* doors each hide a goat. Behind the third */ /* there's a car. After the candidate has */ /* picked one door (but not opened it), the */ /* quizmaster (who knows what's behind the */ /* doors) opens one of the other doors and */ /* shows a goat behind it. The candidate */ /* is then allowed to choose another door. */ /* This simulation demonstrates the chances */ /* in case the candidate changes his mind. */ /********************************************/ import java.applet.*; import java.awt.*; import java.awt.event.*; public class EngMontyHall extends Applet implements Runnable, MouseListener { int b, h, fontSize, doorWithCar, firstChoice, newChoice, stringLength, started, noOfShows, i, x, y, incr, openedByQM, noOfCarsWon, door[] = new int[4]; boolean begin; final int goat=0, car=1, maxShows=1000000; private Thread thread; Image im; Graphics gIm; public void init () { addMouseListener (this); Dimension d = getSize(); b = d.width; h = d.height; // width and height of applet window 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 (noOfShows < maxShows) { noOfShows++; /*** FIRST HIDE CAR AND TWO ***/ /*** GOATS BEHIND THREE DOORS ***/ doorWithCar = 1 + (int)(3 * Math.random()); door[doorWithCar] = car; for (i=1; i<=3; i++) if (i != doorWithCar) door[i] = goat; /*** CANDIDATE PICKS ONE DOOR ***/ firstChoice = 1 + (int)(3 * Math.random()); /*** QUIZMASTER OPENS OTHER DOOR, ***/ /*** BEHIND WHICH THERE IS A GOAT. ***/ do openedByQM = 1 + (int)(3 * Math.random()); while (door[openedByQM]==car || openedByQM==firstChoice); /*** THEN CANDATE IS GIVEN THE ***/ /*** CHANCE TO CHOOSE OTHER DOOR. ***/ for (i=1; i<=3; i++) if (i != firstChoice && i != openedByQM) newChoice = i; /*** FINALLY 1 IS ADDED TO NUMBER OF CARS ***/ /*** IF DOOR CHOSEN APPEARS TO REVEAL CAR. ***/ if (door[newChoice] == car) noOfCarsWon++; } if (noOfShows%100 == 0 || noOfShows<=1000 && noOfShows%10 == 0) { if (im == null) { im = createImage (b, h); gIm = im.getGraphics(); } String s = "Number of cars won per show:"; fontSize = bepaalFont (g, 5*b/9, s); Font f = new Font("Verdana", Font.PLAIN, fontSize); introScreen (gIm); FontMetrics fm = getFontMetrics(f); stringLength = fm.stringWidth(s); gIm.setColor (Color.yellow); gIm.setFont (new Font("Verdana", Font.BOLD, fontSize)); gIm.drawString ("The Monty Hall problem", x, y); gIm.setFont (f); gIm.drawString ("Number of shows:", x, y+incr); gIm.drawString ("Number of cars won:", x, y+2*incr); gIm.drawString (s, x, y+3*incr); gIm.setColor (Color.black); gIm.fillRect (x+stringLength+1, y+h/20, 2*b/9, 2*h/3); gIm.setFont (new Font("Verdana", Font.PLAIN, fontSize)); gIm.setColor (Color.yellow); gIm.drawString (""+noOfShows, x+stringLength+10, y+incr); gIm.drawString (""+noOfCarsWon, x+stringLength+10, y+2*incr); gIm.drawString (format((double)noOfCarsWon/noOfShows), x+stringLength+10, y+3*incr); if (noOfShows == maxShows) gIm.drawString ("== Click for new simulation ==",x,h-fontSize-10); if (im != null) g.drawImage (im, 0, 0, null); } } else { if (im == null) { im = createImage (b, h); gIm = im.getGraphics(); } introScreen(gIm); String s = "The Monty Hall problem"; fontSize = bepaalFont (g, 2*b/3, s); Font f = new Font("Verdana", Font.PLAIN, fontSize); gIm.setFont (f); gIm.setColor (Color.yellow); gIm.setFont (new Font("Verdana", Font.BOLD, fontSize)); gIm.drawString (s, x, y+incr); if (im != null) g.drawImage (im, 0, 0, null); } } void introScreen (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 fontSize = 5, stringWidth; do { fontSize++; g.setFont (new Font ("Arial",Font.PLAIN,fontSize)); fm = g.getFontMetrics(); stringWidth = fm.stringWidth(s); } while (stringWidth < breedte); return fontSize - 1; } String format (double d) { long tmp = (long)(10000 * d + 0.05); return ""+(double)tmp/10000; } public void mousePressed (MouseEvent evt) { if (noOfShows == 0 || noOfShows == maxShows) { begin = true; noOfShows = noOfCarsWon = 0; } } public void mouseReleased (MouseEvent evt){} public void mouseEntered (MouseEvent evt){} public void mouseExited (MouseEvent evt){} public void mouseClicked (MouseEvent evt){} }