Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Background information The Monty Hall problem has a long and interesting history

ID: 3665581 • Letter: B

Question

Background information

The Monty Hall problem has a long and interesting history. The version we are going to use is as follows: we have three doors. Behind one of these doors is a prize, and there is nothing behind the other two doors. The player selects one of the doors and walks up to it. At this point, the game host, who knows where the prize is, stops the player and opens one of two doors that were not chosen by the player. The prize is not behind the open door. We now have two closed doors: the one selected by the player and one other one. The game host gives the player the opportunity to chose the second closed door instead of the door that was initially selected.

The question is the following: Should the player switch door?

It should be noted that the game host’s routine is part of the show, it is done every time regardless of the initial choice of door by the player. In addition, the host knows which door has the prize, and thus can always safely open another (empty) door. In other words, the host routine is not an indication that the player chose the good or the bad door.

Problem

For this assignment, you will simulate playing the Monty Hall game. Your simulation will be a fair representation of the actual game, with the probabilities of each situation respected. You will simulate both strategies: player changing door and player sticking to the original choice. By simulating a large number of games, you will see which of the two strategies is more interesting.

Implementation

The assignment has three classes, Door, MontyHall and Statistics. The class MontyHall will use the class Door and simulate a game. It will use the class Statistics to keep track of the results as it iterates through several games.

Q1: Simulating one game (25 marks)

As a first step, you will simply simulate one game when executing your program. You only need the classes Door and MontyHall for now.

One object of the class Door stores the following information about one of the door:

Does it have the prize behind it?

Is it open or closed?

Was it selected by the player?

A detailed description of the class can be found here:

DOOR.java

/**

* The class <b>Door</b> stores the information about one of the door:

* does it have the prize behind it? Is it open or closed? Was it

* selected by the player?

*

* It provides other objects access to these information through some

* <b>setters</b> and <b>getters</b>.

*

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class Door {

// ADD YOUR INSTANCE VARIABLES HERE

/**

* Creates an instance of the Door object.

* Initially, the door is closed, doesn't have a prize behind it

* and has not been chosen by the player.

*

* @param name identifier for that door

*/

public Door(String name){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Resets the door to its initial state: closed, without a prize behind it

* and not chosen by the player.

*/

public void reset(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Sets this door open.

*/

public void open(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Checks if the door is open.

* @return true if the door is open

*/

public boolean isOpen(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Puts the prize behind this door.

*/

public void setPrize(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Checks if the door has the prize.

* @return true if the door has the prize

*/

public boolean hasPrize(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Sets this door as selected by the player.

*/

public void choose(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Checks if the door is selected by the player.

* @return true if the door is selected by the player

*/

public boolean isChosen(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* @return the door's identifier

*/

public String getName(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

}

The class MontyHall implements the game’s logic. It has a main method which simulates one Monty Hall game and prints the result.

Here are two sample runs:

> java MontyHall The prize was behind door C The player selected door C The host opened door B Switching strategy would have lost > java MontyHall The prize was behind door A The player selected door C The host opened door B Switching strategy would have won

MontyHall.java

/**

* The class <b>MontyHall</b> simulates one game. Is uses three <b>Door</b> objects

* to simulate the three doors. One game consists of the following steps

* <ol>

* <li>Resets all three doors</li>

* <li>Simulates the selection of one of the doors by the player</li>

* <li>Simulates opening of an empty door by the host</li>

* <li> provide the outcome for switching and not switching door</li>

* </ol>

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class MontyHall {

// ADD YOUR INSTANCE VARIABLES HERE

/**

* Initializes the three doors.

*/

public MontyHall(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Simulates one Monty Hall game.

* <ol>

* <li>Resets all three doors</li>

* <li>Simulates the selection of one of the doors by the player</li>

* <li>Simulates opening of an empty door by the host</li>

* <li>prints the outcome for switching and not switching door to standard output</li>

* </ol>

*/

public void oneGame(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

if(/* SWITCHING STRATEGY LOST */){

System.out.println("Switching strategy would have lost");

} else{

System.out.println("Switching strategy would have won");

}

}

/**

* Simulates a random selection of one of the three doors.

* @return the door randomly selected

*/

private Door pickADoor(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Simulates the opening of one of the other doors once the player selected one.

* It should open a door chosen randomly among the ones that don't have the prize and

* that are not selected by the player

*

* @param prizeDoor the door that hides the prize

* @param selectedDoor the door that was selected by the player

* @return the door opened

*/

private Door openOtherDoor(Door prizeDoor, Door selectedDoor){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* The main method of this program. Examples of the execution of the program

* from the command line:

* <pre>

* > java MontyHall

* The prize was behind door B

* The player selected door B

* The host opened door C

* Switching strategy would have lost

* </pre>

* <pre>

* > java MontyHall

* The prize was behind door B

* The player selected door A

* The host opened door C

* Switching strategy would have won

* </pre>

* @param args ignored for now

*/

public static void main(String[] args) {

MontyHall montyHall;

StudentInfo.display();

montyHall = new MontyHall();

montyHall.oneGame();

}

}

Q2: Simulating a series of games (25 marks)

Simulating one game at a time does not tell much about the best strategy. You are going to change the class MontyHall to simulate a large number of games. The results are going to be accumulated in an object of a class Statistics and displayed at the end of the run. The actual number of games to simulate is going to be a runtime input parameter.

An object of the class Statistics accumulates information about the results of each game. In addition to track the successes and failures of each strategy, it also keeps track of several other information (how often a door has the prize behind it, how often it is selected by the player etc.). These additional information are not important for the main question of which strategy is the best, but it will provide some reassurance that your program works properly.

A detailed description of the class can be found here:

JavaDoc Documentation

Statistics.java

The class MontyHall must be updated to take as input the number of games to simulate, and to run these games while accumulating statistics. The input can by provided from the command line, in which case the output will be displayed on the standard output. If no command line input is provided, then the user will be prompted for one (using JOptionPane.showInputDialog, and the output will also be provided in a dialog box (using JOptionPane.showMessageDialog).

An updated description of the class can be found here:

JavaDoc Documentation

MontyHall.java

Here is a sample run, with the input provided from the command line.

> java MontyHall 5 Number of games played: 5 Staying strategy won 2 games (40%)

Switching strategy won 3 games (60%) Selected doors: door 1: 1 (20%) door 2: 3 (60%) door 3: 1 (20%) Winning doors: door 1: 1 (20%) door 2: 1 (20%) door 3: 3 (60%) Open doors: door 1: 2 (40%) door 2: 2 (40%) door 3: 1 (20%)

Implement the classes and test your code. Simulate an increasing number of games and see if you can see a trend. Which strategy seems to work best? Can you understand why now?

Check that all of the statistics seem to make sense, and correct your program if you see anything wrong.

Statistics.java

/**

* The class <b>Statistics</b> accumulates information about a series of games:

* <ol>

* <li>Number of game played</li>

* <li>Number of times the switching strategy was successful</li>

* <li>Number of times the switching strategy was not successful</li>

* <li>Number of times each door has the prize behind it</li>

* <li>Number of times each door was chosen by the player</li>

* <li>Number of times each door was open by the host</li>

* </ol>

*

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class Statistics {

// ADD HERE YOUR MEMBER VARIABLES

/**

* Initializes the statistics.

*/

public Statistics(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Updates statistics after one game.

* @param door1 the first door in the game

* @param door2 the second door in the game

* @param door3 the third door in the game

*/

public void updateStatistics(Door door1, Door door2, Door door3){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Updates statistics for one single door.

* @param door the door for which statistics are updated

* @param index index of that door (0, 1 or 2)

*/

private void oneDoor(Door door, int index){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* @return Returns the complete statistics information

*/

public String toString(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

}

MontyHall.java

import javax.swing.JOptionPane;

/**

* The class <b>MontyHall</b> simulates one or several games. Is uses three <b>Door</b> objects

* to simulate the three doors. One game consists of the following steps

* <ol>

* <li>Resets all three doors</li>

* <li>Simulates the selection of one of the doors by the player</li>

* <li>Simulates opening of an empty door by the host</li>

* <li> provide the outcome for switching and not switching door</li>

* </ol>

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class MontyHall {

// ADD YOUR INSTANCE VARIABLES HERE

/**

* Initializes the three doors.

*/

public MontyHall(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Runs a series of Monty Hall games and displays the resulting statistics in a

* message dialog or on the standard output

*

* @param numberOfGames the number of games to simulate

* @param commandLine if true, sends the results to standard output, else uses a message dialog

*/

public void runGames(int numberOfGames, boolean commandLine){

Statistics stats = new Statistics();

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

if(commandLine) {

System.out.println(stats.toString());

}

else {

JOptionPane.showMessageDialog (null,stats.toString(), "Results", JOptionPane.INFORMATION_MESSAGE);

}

}

/**

* Simulates one Monty Hall game.

* <ol>

* <li>Resets all three doors</li>

* <li>Simulates the selection of one of the doors by the player</li>

* <li>Simulates opening of an empty door by the host</li>

* <li>prints the outcome for switching and not switching door to standard output</li>

* </ol>

*/

public void oneGame(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Simulates a random selection of one of the three doors.

* @return the door randomly selected

*/

private Door pickADoor(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Simulates the opening of one of the other doors once the player selected one.

* It should open a door chosen randomly among the ones that don't have the prize and

* that are not selected by the player

*

* @param prizeDoor the door that hides the prize

* @param selectedDoor the door that was selected by the player

* @return the door opened

*/

private Door openOtherDoor(Door prizeDoor, Door selectedDoor){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* The main method of this program. Examples of the execution of the program

* from the command line:

* <pre>

* > java MontyHall 5

*

* Number of games played: 5

* Staying strategy won 2 games (40%)

* Switching strategy won 3 games (60%)

* Selected doors:

* door 1: 1 (20%)

* door 2: 3 (60%)

* door 3: 1 (20%)

* Winning doors:

* door 1: 1 (20%)

* door 2: 1 (20%)

* door 3: 3 (60%)

* Open doors:

* door 1: 2 (40%)

* door 2: 2 (40%)

* door 3: 1 (20%)

*

* @param args (optional) the number of games to simulate

*/

public static void main(String[] args) {

MontyHall montyHall;

int numberOfGames;

boolean commandLine = false;

StudentInfo.display();

if (args.length == 1) {

numberOfGames = Integer.parseInt(args[0]);

commandLine = true;

} else {

numberOfGames = Integer.parseInt(JOptionPane.showInputDialog("Input the number of games to play", "1000"));

}

montyHall = new MontyHall();

montyHall.runGames(numberOfGames, commandLine);

}

}

Q3: Generating a CSV output to use in a spreadsheet (5 marks)

In order to visualize your statistics, you can generate a comma-separated values output, which you can then import into a spreadsheet such as Microsoft Excel or Google doc. Once in a spreadsheet, you can use its built-in tools to obtain various charts to visualize the statistics.

You will add a method toCSV to the class Statistics that returns a String object which has the following information (each val is replaced by the corresponding data):

Number of games,val Number of doors,3 ,Win,Loss Staying strategy,val,val Switching strategy,val,val ,Selected doors,Winning doors,Open doors Door 1,val,val,val Door 2,val,val,val Door 3,val,val,val

The first line provides the number of games played. The second line the number of doors used (at this point, always 3). The third line is a simple header. The fourth line provides the number of wins and the number of losses for the strategy that doesn’t switch door. The fifth line provides the number of wins and the number of losses for the strategy that does switch door. The sixth line is a simple header. The sevenths line provides the number of times the first door was selected by the player, the number of times it had the prize behind it and the number of times it was open by the host. Lines eight and nine provide the same information for the second and the third door.

A slightly updated description of the class can be found here:

JavaDoc Documentation

Statistics.java

/**

* The class <b>Statistics</b> accumulates information about a series of games:

* <ol>

* <li>Number of game played</li>

* <li>Number of times the switching strategy was successful</li>

* <li>Number of times the switching strategy was not successful</li>

* <li>Number of times each door has the prize behind it</li>

* <li>Number of times each door was chosen by the player</li>

* <li>Number of times each door was open by the host</li>

* </ol>

*

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class Statistics {

// ADD HERE YOUR MEMBER VARIABLES

/**

* Initializes the statistics.

*/

public Statistics(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Updates statistics after one game.

* @param door1 the first door in the game

* @param door2 the second door in the game

* @param door3 the third door in the game

*/

public void updateStatistics(Door door1, Door door2, Door door3){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Updates statistics for one single door.

* @param door the door for which statistics are updated

* @param index index of that door (0, 1 or 2)

*/

private void oneDoor(Door door, int index){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* @return Returns the complete statistics information

*/

public String toString(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* @return Returns the complete statistics information in CSV format

*/

public String toCSV(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

}

The class MontyHall must be updated to call the new toCSV method. You will call this method when the number of games to run is provided through the command line. Here is a sample run:

> java MontyHall 5 Number of games,5 Number of doors,3 ,Win,Loss Staying strategy,3,2 Switching strategy,2,3 ,Selected doors,Winning doors,Open doors Door 1,3,1,1 Door 2,0,1,2 Door 3,2,3,2

An example of an Excel spreadsheet with the corresponding charts can be found here. Import your CSV output in the Data sheet, and the Results sheet will automatically graph out the results. Alternatively you can copy this Google document, or create your own solution.

Q4: Generalizing the game (40 marks)

Although the original game only uses three doors, it can be easily generalized to n doors. In this version, the player still selects one door at random, but the hosts then opens n-2 (empty) doors before offering to player to switch door.

In this new version of your program, the user provides 2 inputs: the number of games to simulate and the number of doors to use. Previously, we had a fixed number of doors, so we could use 3 variables, one per door. This approach was not particularly great1 , but it was simple and possible. Now that we have a number of doors that changes between each run, we cannot have a set number of individual variables anymore.

The solution we are going to choose is to use an array of Door objects.

You need to update the class MontyHall to accept 2 values as input, and use a reference variable to an array of Door objects instead of the 3 instance variables. Several methods of the class must be updated accordingly. An updated description of the class can be found here (Warning: the method openOtherDoor has now been renamed openOtherDoors!):

JavaDoc Documentation

MontyHall.java

import javax.swing.JOptionPane;

/**

* The class <b>MontyHall</b> simulates one or several games. Is uses three <b>Door</b> objects

* to simulate the three doors. One game consists of the following steps

* <ol>

* <li>Resets all doors</li>

* <li>Simulates the selection of one of the doors by the player</li>

* <li>Simulates opening of all other (empty) door save one by the host</li>

* <li> provide the outcome for switching and not switching door</li>

* </ol>

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class MontyHall {

// ADD YOUR INSTANCE VARIABLES HERE

/**

* Initializes the list of doors.

*

* @param numberOfDoors number of door used in the simulation

*/

public MontyHall(int numberOfDoors){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Runs a series of Monty Hall games and displays the resulting statistics in a

* message dialog or on the standard output

*

* @param numberOfGames the number of games to simulate

* @param commandLine if true, sends the results as CSV to standard output, else uses a message dialog

*/

public void runGames(int numberOfGames, boolean commandLine){

Statistics stats = new Statistics(/* INSERT PARAMETER HERE */);

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

if(commandLine) {

System.out.println(stats.toCSV());

}

else {

JOptionPane.showMessageDialog (null,stats.toString(), "Results", JOptionPane.INFORMATION_MESSAGE);

}

}

/**

* Simulates one Monty Hall game.

* <ol>

* <li>Resets all the doors</li>

* <li>Simulates the selection of one of the doors by the player</li>

* <li>Simulates opening of an empty door by the host</li>

* <li>prints the outcome for switching and not switching door to standard output</li>

* </ol>

*/

public void oneGame(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Simulates a random selection of one of the doors.

* @return the door randomly selected

*/

private Door pickADoor(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Simulates the opening of numberOfDoors-2 doors once the player selected one.

* It should open doors chosen randomly among the ones that don't have the prize and

* that are not selected by the player

*

* @param prizeDoor the door that hides the prize

* @param selectedDoor the door that was selected by the player

*/

private void openOtherDoors(Door prizeDoor, Door selectedDoor){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* The main method of this program. Examples of the execution of the program

* from the command line:

* <pre>

* > java MontyHall 5 3

*

* Number of games played: 5

* Staying strategy won 2 games (40%)

* Switching strategy won 3 games (60%)

* Selected doors:

* door 1: 1 (20%)

* door 2: 3 (60%)

* door 3: 1 (20%)

* Winning doors:

* door 1: 1 (20%)

* door 2: 1 (20%)

* door 3: 3 (60%)

* Open doors:

* door 1: 2 (40%)

* door 2: 2 (40%)

* door 3: 1 (20%)

*

* @param args (optional) the number of games to simulate, and the number of doors to use

*/

public static void main(String[] args) {

MontyHall montyHall;

int numberOfGames;

int numberOfDoors;

boolean commandLine = false;

StudentInfo.display();

if (args.length == 2) {

numberOfGames = Integer.parseInt(args[0]);

numberOfDoors = Integer.parseInt(args[1]);

commandLine = true;

} else {

numberOfGames = Integer.parseInt(JOptionPane.showInputDialog("Input the number of games to play", "1000"));

numberOfDoors = Integer.parseInt(JOptionPane.showInputDialog("Input the number of doors", "3"));

}

montyHall = new MontyHall(numberOfDoors);

montyHall.runGames(numberOfGames, commandLine);

}

}

The class Statistics must be updated as well. Statistics must be kept for an array of Door objects. The method updateStatistics now receives a reference to the array as input. The methods toString and toCSV must also be updated to provide the statistics for all the doors. An updated description of the class can be found here:

JavaDoc Documentation

Statistics.java

/**

* The class <b>Statistics</b> accumulates information about a series of games:

* <ol>

* <li>Number of game played</li>

* <li>Number of times the switching strategy was successful</li>

* <li>Number of times the switching strategy was not successful</li>

* <li>Number of times each door has the prize behind it</li>

* <li>Number of times each door was chosen by the player</li>

* <li>Number of times each door was open by the host</li>

* </ol>

*

* @author gvj (gvj@eecs.uottawa.ca)

*

*/

public class Statistics {

// ADD HERE YOUR MEMBER VARIABLES

/**

* Initializes the statistics.

*

* @param numberOfDoors the number of doors used

*/

public Statistics(int numberOfDoors){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* Updates statistics after one game.

* @param doorArry the list of Doors used during the game

*/

public void updateStatistics(Door[] doorArray){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* @return Returns the complete statistics information

*/

public String toString(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

/**

* @return Returns the complete statistics information in CSV format

*/

public String toCSV(){

// REPLACE THE BODY OF THIS METHOD WITH YOUR OWN IMPLEMENTATION

}

}

You have to implement this new feature and experiment with the results. How are both strategies faring as the number of doors increases?

Bonus (10 marks)

There is a little trick in this assignment: when the show host opens the door, if the strategy followed is something like walking from left to right and open the first available door(s), then, in

the 3 doors version a smart player could for example choose door B and observe which door the host opens. If door C is opened, then necessarily the prize is behind door A, otherwise the host would have open door A (on the other hand, if door A is open, then we do not learn anything unexpected). The same problem occurs with the n doors version.

You can have up to 10 bonus marks if you avoid this problem in both the 3 doors and the n doors versions.

Explanation / Answer

Providing Java representation of Monty Hall problem:

Now providing C++ Source code for the problem:

You can create an experiment which iterates the same (large) number of games with an increasing number of doors and map out the evolution of the success and failure rate of both strategies as the number of doors increases. You can create a CSV output with the values, e.g. a series of lines like this:

# of Doors,# of wins switch strategy,# of losses switch strategy, # of wins stay \
                                              strategy,# of losses stay strategy

that you can then input to a spreadsheet and graph out.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote