Monty Hall / Let’s Make a Deal problem simulator

July 3rd, 2005 by Thomas

I found this post about the Monte Hall problem on the Singularity blog and couldn't help but writing a little simulator...

I'm not going into the details again - it's a quite fascinating statistical problem that appeared in a US game show and apparently caused quite some controversy (here's a another good explanation).

I took the opportunity to try out FAME, which worked nicely thanks to the excellent first step tutorial by Carlos Rovira's (Towards Open Source Flash Development).

It might be worth mentioning that the latest version of Flashout only works with Eclipse 3.1.

Sample swf:
[flash]http://www.blog.lessrain.com/wp-content/upload/makeadeal.swf,500,100[/flash]

-> Et voilà - we truly double our chances by switching the door!

Click here to download the source

This is the main class doing the simulation:

Actionscript:
  1. /**
  2. * @author lessrain
  3. */
  4. import lessrain.experiments.makeadeal.ScoreBoard;
  5.  
  6. class lessrain.experiments.makeadeal.MakeADeal
  7. {
  8.     static private var scoreBoard:ScoreBoard;
  9.     static private var games:Number = 1000;
  10.     static private var verbose:Boolean = false;
  11.    
  12.     public static function main():Void
  13.     {
  14.         Stage.scaleMode="noScale";
  15.         Stage.align="TL";
  16.         scoreBoard = new ScoreBoard(_root);
  17.         if (verbose) games=1;
  18.        
  19.         simulate();
  20.     }
  21.    
  22.     public static function simulate()
  23.     {
  24.         scoreBoard.reset();
  25.        
  26.         var startTime:Number = (new Date).getTime();
  27.        
  28.         var switchWins:Number=0;
  29.         var stickWins:Number=0;
  30.        
  31.         // play games by switching the door at the end and count how many times the prize has been won
  32.         if (verbose) scoreBoard.addMessage("--------------------------------------------<br><b>Switching the door</b>");
  33.         for (var i : Number = 0; i <games; i++)
  34.         {
  35.             switchWins += (new MakeADeal(true)).play();
  36.         }
  37.        
  38.         // play games by sticking with the initially selected door and count how many times the prize has been won
  39.         if (verbose) scoreBoard.addMessage("--------------------------------------------<br><b>Sticking with the initially selected door</b>");
  40.         for (var i : Number = 0; i <games; i++)
  41.         {
  42.             stickWins += (new MakeADeal(false)).play();
  43.         }
  44.        
  45.         // output the stats
  46.         if (verbose) scoreBoard.addMessage("--------------------------------------------<br><b>Results</b>");
  47.         scoreBoard.displayScore(switchWins, stickWins, games, ((new Date).getTime() - startTime));
  48.     }
  49.    
  50.    
  51.     private var switchDoor:Boolean;
  52.    
  53.     private var availableDoors:Array;
  54.     private var prizeDoor:Number;
  55.     private var choiceDoor:Number;
  56.     private var openDoor:Number;
  57.    
  58.     public function MakeADeal( switchDoor:Boolean )
  59.     {
  60.         this.switchDoor = switchDoor;
  61.         availableDoors = [ 1, 2, 3 ];
  62.        
  63.         // choose the door with the prize
  64.         prizeDoor = Math.floor(Math.random()*3)+1;
  65.         if (verbose) scoreBoard.addMessage("Prize is hidden behind door <b>"+prizeDoor+"</b>");
  66.     }
  67.    
  68.  
  69.  
  70.     // returns 1 if the prize was won, 0 if not
  71.     public function play():Number
  72.     {
  73.         // choose a door
  74.         choiceDoor = selectDoor(false);
  75.         if (verbose) scoreBoard.addMessage("Player selects door <b>"+choiceDoor+"</b>");
  76.        
  77.         // if we don't want to switch it doesn't matter what happens next so let's already check if we have a winner
  78.         if (!switchDoor) return ( choiceDoor==prizeDoor ? 1 : 0 );
  79.        
  80.         // continue if we do want to switch...
  81.        
  82.         // select (actually open) a bad door from the 2 remaining doors
  83.         openDoor = selectDoor(true);
  84.         if (verbose) scoreBoard.addMessage("Host opens bad door <b>"+openDoor+"</b>");
  85.        
  86.         // select the remaining door and check if it's a winner!
  87.         return ( selectDoor(false)==prizeDoor ? 1 : 0 );
  88.     }
  89.    
  90.     // selects a random door from all available doors stored in availableDoors and deletes it from there
  91.     // if avoidPrizeDoor is true, it'll only return a non-prize door
  92.     private function selectDoor( avoidPrizeDoor:Boolean ):Number
  93.     {
  94.         //Flashout.info("available doors: "+(availableDoors.toString()));
  95.        
  96.         // if we have to avoid the prize door, create a new array with the bad doors only
  97.         // otherwise use all doors
  98.         var doors:Array;
  99.         if (avoidPrizeDoor)
  100.         {
  101.             doors = new Array();
  102.             for (var i : Number = availableDoors.length-1; i>=0 ; i--)
  103.             {
  104.                 if (availableDoors[i]!=prizeDoor) doors.push(availableDoors[i]);
  105.             }
  106.         }
  107.         else doors=availableDoors;
  108.        
  109.         // select a random door
  110.         var door:Number = doors[Math.floor(Math.random()*doors.length)];
  111.        
  112.         // remove that door from the list of available doors
  113.         for (var i : Number = availableDoors.length-1; i>=0 ; i--)
  114.         {
  115.             if (availableDoors[i]==door)
  116.             {
  117.                 availableDoors.splice(i,1);
  118.                 break;
  119.             }
  120.         }
  121.        
  122.         // and return it
  123.         return door;
  124.     }
  125. }


3 Responses to “Monty Hall / Let’s Make a Deal problem simulator”

  1. Alexander McCabe Says:

    I think this is the condition that all the confusion turns on

    3: The host knows in advance which door contains the prize and always opens a door containing the non-desirable item before offering the choice to switch or stay.

    This condition is often not stated in the problem, and slight changes to it can change the whole problem. If that condition were

    3: The host doesn’t know where the prize is and always opens one of the the two remaining doors randomly.

    Then the whole problem changes.

    Furthermore, if you don’t know what rules the host is playing by, and if the host may actually be trying to trick you, then it becomes a really interesting exercise in Game Theory.

  2. Carsten Says:

    The mistake is simply that people think they have a fifty fifty chance with each remaining door after a mule is revealed. Obviously that’s not the case - the initally selected door keeps its 1 in 3 chance of winning from the beginning of the game.

    It is quite mind bending though…

  3. Let’s Make a Deal « The Algorithmist Says:

    […]

Leave a Reply