Monty Hall Game Show Problem in Javascript

The following problem is sometimes called “The Monty Hall Game Show
Problem.” You are a contestant on a game show and have won a shot at the
grand prize. Before you are three closed doors. Behind one door is a brand
new car. Behind the other two doors are consolation prizes. The location of
the prizes is randomly selected. The game show host asks you to select a door,
and you pick one. However, before revealing the contents behind your door,
the game show host reveals one of the other doors with a consolation prize.
At this point, the game show host asks if you would like to stick with your
original choice or switch your choice to the other closed door. What choice
should you make to optimize your chances of winning the car? Does it matter
whether you stick with your original choice or switch doors?
Write a simulation program to solve the game show problem. Your program should make 10,000 simulated runs through the problem, randomly
selecting locations for the prize, and then counting the number of times
the car was won when sticking with the original choice, and counting
the number of times the car was won when switching doors. Output the
estimated probability of winning for both strategies. Be sure that your program exactly simulates the process of selecting the door, revealing one,
and then switching. Do not make assumptions about the actual solution
(for example, simply assuming that there is a 1/3 or 1/2 chance of getting
the prize).
Can you tell me what the problem is saying without sharing any code?

I don’t get how do I start solving this problem? What are the inputs? And what’s the required output?

let switchNwin = 0;
let firstChoiceWin = 0;
for (let i = 0; i < 10000; i++) {
  let car = Math.floor(Math.random() * 3);
  console.log("car is behind door" + car);
  let goat1;
  for (let j = 0; j < 3; j++) {
    if (j != car) {
      goat1 = j;
      break;
    }
  }
  console.log("first goat is behind door" + goat1);
  let goat2;
  for (j = 0; j < 3; j++) {
    if (j != goat1 && j != car) {
      goat2 = j;
      break;
    }
  }
  console.log("second goat is behind door" + goat2);
  let choice_of_door = Math.floor(Math.random() * 3);
  console.log("User picked door" + choice_of_door);
  //what to do next?
  wanna_switch = Math.floor(Math.random() * 2);
  switch (wanna_switch) {
    case 0:
      if (choice_of_door === car) {
        firstChoiceWin++;
      }
      break;
    case 1:
      choice_of_door = Math.floor(Math.random() * 3);
      if (choice_of_door === car) {
        switchNwin++;
      }
      break;

    default:
      break;
  }
}

console.log(switchNwin);
console.log(firstChoiceWin);

This is my try but it’s not working. Can you tell why?

let switchNwin = 0;
let firstChoiceWin = 0;
let user_choosed_a_new_door;
for (let i = 0; i < 10000; i++) {
  let car = Math.floor(Math.random() * 3);
  let user_choosed_a_door = Math.floor(Math.random() * 3);
  for (let j = 0; j < 3; j++) {
    if (j != user_choosed_a_door && j != car) {
      host_reveals_a_door_with_a_goat = j;
      break;
    }
  }
  console.log("car is in door" + car);
  console.log("user choosed a door" + user_choosed_a_door);
  console.log(
    "host reveals a door with a goat door" + host_reveals_a_door_with_a_goat
  );

  wanna_switch = Math.floor(Math.random() * 2);
  switch (wanna_switch) {
    case 0:
      //no switch
      if (user_choosed_a_door === car) {
        firstChoiceWin++;
      }
      break;

    case 1:
      //switch
      for (let j = 0; j < 3; j++) {
        if (j != user_choosed_a_door && j != host_reveals_a_door_with_a_goat) {
          user_choosed_a_new_door = j;
          if (user_choosed_a_new_door === car) {
            switchNwin++;
            break;
          }
        }
      }
      break;

    default:
      break;
  }
}

console.log(switchNwin);
console.log(firstChoiceWin);

Monty is solved.

1 Like

Nicely done! :slight_smile:

1 Like

Means a lot :smiley: The best part is I didn’t follow any tutorials to do this…Programming is coming to me these days.

3 Likes

That is great to hear! :sunglasses:

1 Like
// Function to simulate the Monty Hall Game Show
function simulateMontyHall(totalGames) {
  let stayWins = 0;
  let switchWins = 0;

  for (let i = 0; i < totalGames; i++) {
    // Generate random door numbers (1, 2, or 3)
    const winningDoor = Math.floor(Math.random() * 3) + 1;
    let chosenDoor = Math.floor(Math.random() * 3) + 1;

    // Reveal a non-winning door
    let revealedDoor;
    do {
      revealedDoor = Math.floor(Math.random() * 3) + 1;
    } while (revealedDoor === winningDoor || revealedDoor === chosenDoor);

    // Switch or stay with the original choice
    const switchChoice = Math.random() < 0.5;
    if (switchChoice) {
      chosenDoor = 6 - chosenDoor - revealedDoor;
    }

    // Check if the chosen door matches the winning door
    if (chosenDoor === winningDoor) {
      if (switchChoice) {
        switchWins++;
      } else {
        stayWins++;
      }
    }
  }

  // Calculate win percentages
  const stayWinPercentage = (stayWins / totalGames) * 100;
  const switchWinPercentage = (switchWins / totalGames) * 100;

  // Output results
  console.log(`Games Played: ${totalGames}`);
  console.log(`Stay Wins: ${stayWins} (${stayWinPercentage.toFixed(2)}%)`);
  console.log(`Switch Wins: ${switchWins} (${switchWinPercentage.toFixed(2)}%)`);
}

// Run the simulation with 100,000 games
simulateMontyHall(100000);

In this implementation, the simulateMontyHall function simulates the Monty Hall Game Show. The function takes a parameter totalGames that determines the number of games to be simulated.

Within the simulation, random door numbers are generated for the winning door, the initially chosen door, and the door to be revealed by the host. The player then decides whether to switch their choice or stay with the original door. Afterward, the function checks if the chosen door matches the winning door and increments the respective win count.

At the end of the simulation, the function calculates and displays the number of wins and win percentages for both staying and switching choices.

You can adjust the totalGames parameter to change the number of games you want to simulate. The more games you simulate, the closer the win percentages should align with the theoretical probabilities of the Monty Hall problem.

@polaryeti - thanks to your thread here, you reminded me to post this larger deep dive about the Monty Hall Problem that I drafted a long time ago but forgot about finishing and publishing it :stuck_out_tongue:

And here is the code so simulate the Monty Hall problem for an arbitrary number of doors:

function montyHallSimulation(doorNum, runs) {
  // Track the results
  var wins = 0;
  var losses = 0;

  // Simulate the game
  for (var i = 0; i < runs; i++) {
    // Initialize the doors
    var doors = new Array(doorNum);
    doors.fill("x");

    let chosenDoor = Math.floor(Math.random() * doors.length);
    let carDoor = Math.floor(Math.random() * doors.length);
    let montyDoor = -1;

    doors[chosenDoor] = "chosen";
    doors[carDoor] = "car";

    // The player guessed correctly with their first pick!
    if (chosenDoor === carDoor) {
      doors[chosenDoor] = "chosen + car";

      // We need to reveal some arbitrary door that isn't the 
      // same one the player has selected
      do {
        montyDoor = Math.floor(Math.random() * doors.length);
        //console.log(`${montyDoor} is Monty's pick, and chosen is ${chosenDoor}`);
      } while (montyDoor == chosenDoor);

      doors[montyDoor] = "monty pick";
    } else {
      // Monty's pick will be the door the car is behind
      montyDoor = carDoor;
      doors[carDoor] = "car + monty pick";
    }

    //
    // Tracking!
    //
    if (chosenDoor !== carDoor) {
      // Switching caused a win
      wins++;
    } else {
      // Switching caused a loss
      losses++;
    }
  }

  console.log(`${wins} are the wins and ${losses} are the losses!`);
  console.log(`Switching resulted in a ${100 * (wins / runs)}% win rate!`);
  console.log("------------------------");
}

montyHallSimulation(20, 10000);

This example uses 20 doors as in my example from the earlier article, and the win rate for switching is indeed around 95% :slight_smile:

1 Like

Sure, here’s a simple implementation of the Monty Hall problem in JavaScript:

javascriptCopy code

function montyHallGame(numSimulations, switchDoor) {
    let wins = 0;
    const numDoors = 3;

    for (let i = 0; i < numSimulations; i++) {
        // Randomly select the door with the prize
        const prizeDoor = Math.floor(Math.random() * numDoors);

        // Randomly select the contestant's initial choice
        const chosenDoor = Math.floor(Math.random() * numDoors);

        // Monty opens a door that doesn't have the prize behind it and wasn't chosen by the contestant
        let openedDoor;
        do {
            openedDoor = Math.floor(Math.random() * numDoors);
        } while (openedDoor === prizeDoor || openedDoor === chosenDoor);

        // If switchDoor is true, switch the contestant's choice
        const finalChoice = switchDoor ? (numDoors - chosenDoor - openedDoor) : chosenDoor;

        // Check if the final choice is the prize door
        if (finalChoice === prizeDoor) {
            wins++;
        }
    }

    return wins / numSimulations;
}

// Example usage:
const numSimulations = 10000;
const switchDoor = true;
const winPercentage = montyHallGame(numSimulations, switchDoor);
console.log(`Win percentage with switching doors: ${winPercentage * 100}%`);

In this implementation, the montyHallGame function takes two parameters: numSimulations (the number of simulations to run) and switchDoor (a boolean indicating whether the contestant switches doors after Monty reveals a goat). The function returns the percentage of wins.

1 Like

@kamrunruba - nicely done! :slight_smile:

If you want more of a challenge, are you up for creating three doors and visualizing this code?