Below is an image of a Monty Hall problem simulation executing in Processing Python Mode.
It is derived from the Python 3 simulation that was previously posted. During each frame, each of the three player strategies is run 100 times, and the percentages of the wins for that frame are displayed. The percentages are also represented graphically to the right. The graphical representation is cumulative.
All are free to copy, revise, and use the code.
The code:
import random
iterations = 100
graph_x = 200
def setup():
size(320, 240)
frameRate(0.5)
background(255)
fill(0)
stroke(0)
# labels
textSize(16)
text("0%", graph_x - 8, 220)
text("100%", graph_x + 76, 220)
line(graph_x, 92, graph_x, 200)
line(graph_x + 100, 92, graph_x + 100, 200)
textSize(24)
text("Monty Hall Problem", 20, 40)
text("Wins", 20, 80)
text("Player Strategy", 96, 80)
text("Stick", 96, 120)
text("Random", 96, 160)
text("Switch", 96, 200)
def draw():
# obscure previous win percentages and frameCount
noStroke()
fill(255)
rect(0, 94, 88, height - 90)
rect(0, 210, 140, 30)
# display current win percentages
fill(0)
textSize(24)
# stick player strategy
stick_wins = 0
for i in range(iterations):
g = MontyHallGame()
g.play_stick_game()
if g.get_outcome() == "car":
stick_wins += 1
text("{}%".format(stick_wins), 20, 120)
# random player strategy
random_wins = 0
for i in range(iterations):
g = MontyHallGame()
g.play_random_game()
if g.get_outcome() == "car":
random_wins += 1
text("{}%".format(random_wins), 20, 160)
# switch player strategy
switch_wins = 0
for i in range(iterations):
g = MontyHallGame()
g.play_switch_game()
if g.get_outcome() == "car":
switch_wins += 1
text("{}%".format(switch_wins), 20, 200)
textSize(16)
text("Frame {}".format(frameCount), 10, 230)
# graph the percentages
stroke(0, 16)
line(graph_x + stick_wins, 92, graph_x + stick_wins, 120)
line(graph_x + random_wins, 132, graph_x + random_wins, 160)
line(graph_x + switch_wins, 172, graph_x + switch_wins, 200)
class MontyHallGame(object):
def __init__(self):
self.doors = ["goat", "goat", "car"]
random.shuffle(self.doors)
self.available_choices = [0, 1, 2]
self.first_user_choice = None # first door picked by user
self.host_choice = None # door opened by host
self.second_user_choice = None # second door picked by user
def set_first_user_choice(self, door):
self.first_user_choice = door
self.available_choices.remove(door)
for i in self.available_choices:
if self.doors[i] == "car":
self.available_choices.remove(i)
break
def get_first_user_choice(self):
return self.first_user_choice
def set_host_choice(self, door):
self.host_choice = door
self.available_choices = [0, 1, 2]
self.available_choices.remove(door)
def get_host_choice(self):
return self.host_choice
def set_second_user_choice(self, door):
self.second_user_choice = door
def get_second_user_choice(self):
return self.second_user_choice
def get_outcome(self):
return self.doors[self.second_user_choice]
def get_available_choices(self):
return self.available_choices
def get_doors(self):
return self.doors
# methods for the three user strategies
# the host always chooses randomly among the two other doors
# when user's first choice is the door with the car
def play_random_game(self):
# user randomly chooses from unopened doors for second choice
self.set_first_user_choice(random.choice(self.get_available_choices()))
self.set_host_choice(random.choice(self.get_available_choices()))
self.set_second_user_choice(random.choice(self.get_available_choices()))
def play_stick_game(self):
# user always repeats first choice again as second choice
self.set_first_user_choice(random.choice(self.get_available_choices()))
self.set_host_choice(random.choice(self.get_available_choices()))
self.set_second_user_choice(self.get_first_user_choice())
def play_switch_game(self):
# user always switches door for second choice
self.set_first_user_choice(random.choice(self.get_available_choices()))
self.set_host_choice(random.choice(self.get_available_choices()))
ac = self.get_available_choices()
ac.remove(self.get_first_user_choice())
self.set_second_user_choice(ac[0])