Build A Monty Hall Problem Simulation Using Python
In this article, I will show you how to create a python program that simulates a popular problem called the Monty Hall problem to show once and for all that the problem solved by Steve Selvin is indeed correct.
The Monty Hall problem is a brain teaser, in the form of a probability puzzle, loosely based on the American television game show Let’s Make a Deal and named after its original host, Monty Hall.
The problem was originally posed (and solved) in a letter by Steve Selvin to the American Statistician in 1975 (Selvin 1975a), (Selvin 1975b). It became famous as a question from a reader’s letter quoted in Marilyn vos Savant’s
“Ask Marilyn” column in Parade magazine in 1990 (vos Savant 1990a)
The Monty Hall Problem
Suppose you’re on a game show, and you’re given the choice of three doors: Behind one door is a car; behind the other two are goats. You pick a door, say №1, and the host, who knows what’s behind the doors, opens another door, say №3, which has a goat. He then says to you, “Do you want to pick door №2?” Is it to your advantage to switch your choice?
Most people would say that once one door is revealed then you have only 2 choices left and therefore your chances of winning are 1/2 or 50%, and so it wouldn’t matter if you stay or switched doors.
Spoiler Alert: You are better off switching, although surprisingly most people choose to stay.
Understanding The Statistics of the Monty Hall Problem
Let us think about the game show (Let’s Make a Deal) from the shows point of view, the show and the shows host (Monty) knows where there is a goat and where there isn’t a goat and therefore knows which door the prize is behind. So, we are given three doors (Door #1, Door #2, and Door#3). Behind the first door is a goat, behind the second door is a car (our prize) and behind the third door is another goat.
Suppose the contestant chooses Door #1, then the host reveals Door #3 (the goat), since the host knows Door #2 contains the prize car. In this case it is good for the contestant to switch. If the contestant/player switches then the contestant would win the prize. If the contestant/player did NOT switch then the contestant would lose the prize.
Suppose the contestant chooses Door #2, then the host reveals either Door #1 or Door #3. In this case it is bad to switch for the contestant. If the contestant/player switches then the contestant would lose the prize. If the contestant/player did NOT switch then the contestant would win the prize.
Suppose the contestant chooses Door #3, then the host reveals Door #1. In this case it is good for the contestant to switch. If the contestant/player switches then the contestant would win the prize. If the contestant/player did NOT switch then the contestant would lose the prize.
In the above scenario, we can easily see that if the contestant had switched , then the contestant would’ve won 2/3 or about 66.66% of the time and lost only 1/3 or about 33.33% of the time. If the contestant chose not switch, then the contestant would’ve won 1/3 or about 33.33% of the time and lost 2/3 or about 66.66% of the time
Let’s look at the probability of NEVER switching. There are three doors and 1 of the three doors contains the car, your desired prize, while 2 of the three doors contains the undesired prize (the goat). If the contestant chooses to stick with their gut feeling and choose to never switch then the probability of winning is 1/3 and their probability of losing is 2/3.
After staying with your original choice: Probability( Winning) = P(W) = 1/3
After staying with your original choice: Probability (Losing) = P(L) = 2/3
Now let’s take a look at the probability of ALWAYS switching. Let’s think about how you would win if you always switched. Fig. 1 shows three doors containing the goat, car, and goat in that order. If you picked door #1 the host will show you door #3 and you should switch, and if you picked door #3 the host will show you door #1 and you should switch. So if you picked a wrong door (a door containing a goat) and switch you always win, and if you chose the door that contained the prize and then switched, you would lose.
Let’s look at a scenario. Assume the prize is behind door #2 and goats are behind doors #1 and #3.
Scenario #1 for always switching:
1. You choose door #1
2.The host opens door #3 , because the prize is behind door #2, and asks if you want to switch.
3.You decide to switch to door #2
Scenario #2 for always switching
1.You choose door #2
2.The host opens door #3 or door #1 , because the prize is behind door # 2, and asks if you want to switch.
3.You decide to switch to door #1 or door #3
Scenario #3 for always switching
1. You choose door #3
2. The host opens door #1 , because the prize is behind door #2, and asks if you want to switch.
3. You decide to switch to door #2
4. YOU WIN!
From the possible scenarios above where the prize was behind door #2 and you opted to always switch, you would’ve won 2/3 times from switching and lost 1/3 times for switching or vice versa you would’ve won 1/3 of the time by sticking with your choice and lost 2/3 of the time for sticking with your choice.
After switching original choice: Probability ( Winning) = P(W) = 2/3
Probability (Losing) = P(L) = 1/3
By switching doors in this case, your probability of winning is 2/3 and your probability of losing is 1/3 . Another way of thinking about it is, if you choose to switch you double your chances of winning or increase your chances of winning by 1/3 or about 33.33%.
Another More Intuitive Perspective of the Monty Hall Problem:
You may not be convinced yet that switching is better (meaning it gives the player an extra 33.33% chance of winning by switching their original choice to another door for the 3 door scenario) after the host reveals a door that doesn’t have the prize.
So let’s look at a fictional scenario where there are 100 doors, and only one of them contains the prize you want and the rest contains a goat. Let’s say you choose one of the doors randomly (like the last door or Door #100). Your chance of choosing the door with the prize is 1 / 100 which is 1%. The host then reveals to you 98 other doors that contain a goat leaving just your first choice and one other unopened door, so we know one of them contains the prize and the other contains the goat.
Do you still think, given this scenario that you have only a 50% chance of winning by switching or not switching since there are two unrevealed doors left ? Do you think it would be better for you to switch or stay with your original choice ?
By switching your choice you are given an extra 98% chance of getting the prize (meaning by switching you will have a 99% chance of getting the prize) , and your first choice still has only a 1% chance of being right.
If you would like to read more about this remarkable story I suggest you read the book “The Monty Hall Problem: The Remarkable Story of Math’s Most Contentious Brain Teaser”. In this book, the author Jason Rosenhouse explores the history of the Monty Hall puzzle. He shows how the problem has fascinated philosophers, psychologists, and many others, and examines the many variations that have appeared over the years using minimum mathematics.
If you prefer not to read this article and would like a video representation of it, you can check out the YouTube Video below. It goes through everything in this article with a little more detail, and will help make it easy for you to start programming . Or you can use both as supplementary materials for learning !
The first thing that I like to do before writing any code is to put a description of the program in comments.
#Description: This program simulates the Monty Hall problem
Import the dependencies to be used throughout the program.
#Import the libraries
import matplotlib.pyplot as plt
Remember that the host knows which door the prize is behind and will only reveal a door that does not have the prize, so I need to create a function to mimic this behavior.
#The host will reveal a door that doesn't contain the prize
#Remember the host knows the door that the prize is behind
def get_non_prize_door(host, num_doors, player_choice):
i = 1
while (i == host or i== player_choice ):
i = (i+1)%(num_doors)
The host will reveal a door that does not contain the prize, and the player or contestant has the option to switch from the door that s/he originally chose, to the other unopened door.
So, I need to create a function to simulate this behavior as well, so this function will take in the door that was revealed and the door the player or contestant chose originally and switch the players choice to the other unopened door.
For example given there are only three doors, door #0 , door #1, & door #2, if the player originally chose door number ‘0’ and the host revealed door number ‘2’ , then the player will switch their choice from door number ‘0’ to door number ‘1’ which is the other unopened door.
#Have the player switch to the other unopened door
def switch_function(shown_door, num_doors, player_choice):
i = 1
while (i == shown_door or i== player_choice ):
i = (i+1)%(num_doors)
Now, let’s simulate the game with the contestant. Because this is a simulation, I want to test it with big numbers (a.k.a. a big sample sizes) to see if choosing to always switch doors after one has been revealed by the host that does not contain the prize indeed gives me about a 66.66% chance of winning.
Let’s test the simulation and input the number of games to be played and then check the win percentage from always switching.
#Play the game
x = monty_hall_game(True, 10)print('Win switch %: ', x/ x)
print('Lose switch %: ', x/ x)
print('Win No switch %: ', x/ x)
print('Lose No switch %: ', x/ x)
Okay, so it looks like the simulated contestant won 70% of the time by always switching and lost 30% of the time by always switching his/her original door, but to get a better picture of the actual probability (66.66%) we will need a much larger sample size like 2000 or 10000 test plays.
Now let’s get the data for the number of win percentages per test/played games. To graph this, we will get the percentage of wins from the simulated contestant test playing just one game to the simulated contestant test playing 2000 games.
num_tests = 
win_percentage = 
switch = True
for i in range(1,2001):
y = monty_hall_game(switch, i)
Visually show the number of test plays and percentage of wins from always choosing to switch doors.
#Visually Show The Number of Tests and the Win Percentage From Switchingplt.figure(figsize=(12.2,4.5)) #width = 12.2in, height = 4.5
plt.plot( num_tests, win_percentage )
plt.title('Monty Hall Problem')
plt.xlabel('Number of Tests',fontsize=18)
Let’s see the win percentage now after test playing 2000 games.
print('The win percentage for test playing ', y, ' games is:' ,y/ y)
After simulating and test playing 2000 games, it looks like the simulated contestant would’ve won about 65.85% of the time from always choosing to switch his/her initial door choice. This percentage is much closer to the 66.66% that we would’ve expected. I suggest trying an even bigger number like 10000 to test play the simulation and see if that number is any closer to 66.66%.
Thanks for reading this article I hope its helpful to you all ! Keep up the learning, and if you would like math, computer science, programming and algorithm analysis videos please visit and subscribe to my YouTube channels (randerson112358 & compsci112358 )