Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monty Hall Program Simulation (C#)

Tags:

c#

probability

I am trying to simulate the Monty Hall Problem (because I read from the book Think Statistics that a guy in particular was convinced only after seeing a computer simulation) in C#, the programming language most familiar to me. My scenario is such that the position of the prize is random (in each run), my choice is random, and the game host's choice of opening the door is random (it can't be random if I picked the non-prize).

Surprisingly though, my program achieves the result of a 50:50 chance of winning no matter whether I switch or not. Here's the code to it (pardon me for the lengthiness):

class Program
{
    static void Main(string[] args)
    {
        Random rand = new Random();

        int noSwitchWins = RunGames(rand, false, 10000);
        int switchWins = RunGames(rand, true, 10000);

        Console.WriteLine(string.Format("If you don't switch, you will win {0} out of 1000 games.", noSwitchWins));
        Console.WriteLine(string.Format("If you switch, you will win {0} out of 1000 games.", switchWins));

        Console.ReadLine();
    }

    static int RunGames(Random rand, bool doSwitch, int numberOfRuns)
    {
        int counter = 0;

        for (int i = 0; i < numberOfRuns; i++)
        {
            bool isWin = RunGame(rand, doSwitch);
            if (isWin)
                counter++;
        }

        return counter;
    }

    static bool RunGame(Random rand, bool doSwitch)
    {
        int prize = rand.Next(0, 2);
        int selection = rand.Next(0, 2);

        // available choices
        List<Choice> choices = new List<Choice> { new Choice(), new Choice(), new Choice() };
        choices[prize].IsPrize = true;
        choices[selection].IsSelected = true;
        Choice selectedChoice = choices[selection];
        int randomlyDisplayedDoor = rand.Next(0, 1);

        // one of the choices are displayed
        var choicesToDisplay = choices.Where(x => !x.IsSelected && !x.IsPrize);
        var displayedChoice = choicesToDisplay.ElementAt(choicesToDisplay.Count() == 1 ? 0 : randomlyDisplayedDoor);
        choices.Remove(displayedChoice);

        // would you like to switch?
        if (doSwitch)
        {
            Choice initialChoice = choices.Where(x => x.IsSelected).FirstOrDefault();
            selectedChoice = choices.Where(x => !x.IsSelected).FirstOrDefault();
            selectedChoice.IsSelected = true;
        }

        return selectedChoice.IsPrize;
    }
}

class Choice
{
    public bool IsPrize = false;
    public bool IsSelected = false;
}

This is entirely for my own interest's sake, and I wrote it in the way most familiar and comfortable to me. Do feel free to offer your own opinion and critique, thank you very much!

like image 900
matt Avatar asked Apr 25 '13 11:04

matt


People also ask

What is the answer to the Monty Hall problem?

The Monty Hall problem is deciding whether you do. The correct answer is that you do want to switch. If you do not switch, you have the expected 1/3 chance of winning the car, since no matter whether you initially picked the correct door, Monty will show you a door with a goat.

Is Monty Hall problem true?

This statistical illusion occurs because your brain's process for evaluating probabilities in the Monty Hall problem is based on a false assumption. Similar to optical illusions, the illusion can seem more real than the actual answer.

Should you switch doors on Let's Make a Deal?

Should the guest switch to the remaining closed door? Most people choose to stay with their original choice, which is wrong—switching would increase their chance of winning from 1/3 to 2/3. (There is a 1/3 chance that the guest's original pick was correct, and that does not change.)

Who Solved the Monty Hall problem?

When vos Savant politely responded to a reader's inquiry on the Monty Hall Problem, a then-relatively-unknown probability puzzle, she never could've imagined what would unfold: though her answer was correct, she received over 10,000 letters, many from noted scholars and Ph.


2 Answers

rand.Next(0,2)

only returns 0 or 1; the upper bound is exclusive. You are never picking the third door (unless you switch), and the third door never has the prize. You are modelling the wrong problem.

Try instead:

rand.Next(0,3)

Likewise:

int randomlyDisplayedDoor = rand.Next(0, 1);

only ever selects the first of the candidate doors; should be:

int randomlyDisplayedDoor = rand.Next(0, 2);

Now we get:

If you don't switch, you will win 3320 out of 1000 games.
If you switch, you will win 6639 out of 1000 games.

Note - the upper bound is inclusive when equals - i.e. rand.Next(1,1) always returns 1.

like image 105
Marc Gravell Avatar answered Oct 13 '22 02:10

Marc Gravell


See Random.Next(minValue, maxValue)

Parameters

minValue Type: System.Int32 The inclusive lower bound of the random number returned.

maxValue Type: System.Int32 The exclusive upper bound of the random number returned. maxValue must be greater than or equal to minValue.

like image 40
Sam Leach Avatar answered Oct 13 '22 00:10

Sam Leach