Monty Hall problem is a popular probability puzzle based on a television game show and named after its host, Monty Hall.
In this Monty Hall game,
- There will be three closed doors and you will be given a choice to choose one of them. Behind one of the doors, there is a car and behind the other doors, goats. The host knows about the placement of the car and goats.
- After you choose a door, the host opens one of the other two doors which has a goat.
- Now, you can either stick with your original choice of door or you can switch.
Here’s a glimpse of the game.
Let’s create an interactive version of this game with HTML, CSS, and vanilla JavaScript.
HTML: The main parts we need in the game are:
- Dialogue space for the host, where he/she interacts with the player.
- The 3 doors
- Result page
We include all possible scenarios and dialogues and later with JavaScript, we can use them when necessary.
Here, in the instructions class, we included all the dialogues of the host, and we can make this interactive with JavaScript. After the instructions class, there is the main section which contains the 3 doors. Finally, we have different scenarios based on the player’s choice.
HTML
<!DOCTYPE html> < head > < title >MontyHall</ title > < link rel = "stylesheet" href = "style.css" > </ head > < body > < div id = "body" > < header > < h1 >welcome to Montyhall game</ h1 > </ header > < div id = "instructions" class = "instructions" > < div id = "row1" class = "row1" > Please Select a door </ div > < div id = "d1" >You selected door1</ div > < div id = "d2" >You selected door2</ div > < div id = "d3" >You selected door3</ div > < div id = "row2" class = "row2" > < p >Ok, I'm opening a door</ p > < p >Do you want to switch?</ p > < div class = "buttons" > < button id = "btn-1" >Yes</ button > < button id = "btn-2" >No</ button > </ div > </ div > </ div > < main class = "door-row" > < img id = "door1" class = "door" src = "./door.png" alt = "door" > < img id = "door2" class = "door" src = "./door.png" alt = "door" > < img id = "door3" class = "door" src = "./door.png" alt = "door" > </ main > </ div > < div id = "switchAndWin" class = "result" > < p >Congratulations!!!!!</ p > < p >You made the right choice by switching</ p > < p >By switching, you increased your probability of winning to 0.67</ p > < div class = "links" > < button >< a href = target = "_blank" > Know more</ a > </ button > < button >< a href = "index.html" > Play again </ a ></ button > </ div > </ div > < div id = "switchAndLose" class = "result" > < p >You Lost!!!</ p > < p >The chances of you winning was 67% since you switched,yet you still lost </ p > < p >Play again to redefine your luck</ p > < div class = "links" > < button >< a href = target = "_blank" > Know more</ a > </ button > < button >< a href = "index.html" >Play again</ a ></ button > </ div > </ div > < div id = "NoSwitchAndWin" class = "result" > < p >Congratulations!!!!!</ p > < p >You are a very lucky person</ p > < p >The probability of you winning was only 0.33 because you didn't switch,yet you still won</ p > < div class = "links" > < button >< a href = target = "_blank" > Know more</ a > </ button > < button >< a href = "index.html" > Play again</ a > </ button > </ div > </ div > < div id = "NoSwitchAndLose" class = "result" > < p >You Lost!!!!</ p > < p >Since you didn't switch, your chances of winning was only 33%</ p > < p >Play again to redefine your luck</ p > < div class = "links" > < button >< a href = target = "_blank" > Know more</ a > </ button > < button >< a href = "index.html" >Play again</ a ></ button > </ div > </ div > < script src = "script1.js" async defer></ script > </ body > </ html > |
CSS: Let’s add a little styling to our game. It’s highly customizable and feels free to add your own stylings.
CSS
/*Basic Styling */ * { margin : 0 ; padding : 0% ; box-sizing: border-box; } body { background-color : #ffffff ; min-height : 100 vh; display : flex; align-items: center ; justify- content : center ; flex- direction : column; } header { height : 20 vh; font-family : 'Bangers' , cursive ; display : flex; justify- content : center ; align-items: center ; font-size : 30px ; text-align : center ; } .instructions { height : 15 vh; display : flex; justify- content : center ; align-items: center ; font-size : 30px ; font-family : 'McLaren' , cursive ; margin : 30px 0 ; } .door-row { text-align : center ; margin-top : 40px ; } .door { width : 200px ; height : 350px ; margin : 10px 40px ; margin-bottom : 40px ; cursor : pointer ; border : 10px solid #000 ; } .buttons { width : 300px ; height : 50px ; display : flex; justify- content : center ; align-items: center ; } button { padding : 10px 40px ; background-color : #000 ; border : none ; border-radius: 50px ; color : #f5f5f5 ; cursor : pointer ; margin : 0 20px ; font-size : 18px ; outline : none ; box-shadow: 0px 10px 13px -7px #000000 , 7px 5px 15px 5px rgba( 0 , 0 , 0 , 0 ); } button:active { transform: scale( 0.9 ); } .result p { font-size : 22px ; line-height : 40px ; text-align : center ; } .result p:first-child { font-family : 'Bangers' , cursive ; letter-spacing : 2px ; text-transform : uppercase ; font-size : 40px ; margin-bottom : 30px ; } .links { width : 100 vw; height : 10 vw; text-align : center ; margin : 40px 0 ; } .result a { color : gray ; background-color : #000 ; text-decoration : none ; } .result a:hover { color : #f5f5f5 ; } @media screen and ( max-width : 700px ) { header { margin-top : 20px ; font-size : 20px ; text-align : center ; } } |
JavaScript: The workflow of javascript is:
- Declare all the global variables.
- Hide unnecessary elements.
- Create a function for randomly shuffling the doors every time we play.
- Add Event listeners for each door when chosen.
- For every door that is clicked, show the host dialogue, open a door that contains a goat, and ask the player to choose.
Then, according to the player’s choice open the door and display the result page.
Declaring the variables:
Javascript
// Declaring global variables const body = document.getElementById( 'body' ); const instructions = document.getElementById( 'instructions' ); const row1 = document.getElementById( 'row1' ); const row2 = document.getElementById( 'row2' ); const d1 = document.getElementById( 'd1' ); const d2 = document.getElementById( 'd2' ); const d3 = document.getElementById( 'd3' ); const switchChoiceYes = document.getElementById( 'btn-1' ); const switchChoiceNo = document.getElementById( 'btn-2' ); const doorImage1 = document.getElementById( 'door1' ); const doorImage2 = document.getElementById( 'door2' ); const doorImage3 = document.getElementById( 'door3' ); const SwitchAndWin = document.getElementById( "switchAndWin" ); const SwitchAndLose = document.getElementById( "switchAndLose" ); const NoSwitchAndWin = document.getElementById( "NoSwitchAndWin" ); const NoSwitchAndLose = document.getElementById( "NoSwitchAndLose" ); // Image of Car const winPath = // Image of Goat const losePath = // Variables for shuffling the doors var openDoor1, openDoor2, openDoor3, winner; |
Hiding the unnecessary elements:
Javascript
// Hiding unnecessary elements row2.hidden = true ; SwitchAndWin.hidden = true ; SwitchAndLose.hidden = true ; NoSwitchAndWin.hidden = true ; NoSwitchAndLose.hidden = true ; d1.hidden = true ; d2.hidden = true ; d3.hidden = true ; |
Create a function for randomly shuffling the doors every time we play.
Javascript
// Function to randomly shuffle the doors function winDoorGenerator() { winner = Math.floor(Math.random() * 3); if (winner === 1) { openDoor1 = winPath; openDoor2 = losePath; openDoor3 = losePath; } else if (winner === 2) { openDoor2 = winPath; openDoor1 = losePath; openDoor3 = losePath; } else { openDoor3 = winPath; openDoor2 = losePath; openDoor1 = losePath; } } // Calling the function winDoorGenerator(); |
Event Listener for door1:
Javascript
// Event listener for door 1 doorImage1.onclick = () => { // Revealing necessary elements for dialogue row1.hidden = true ; d1.hidden = false ; setTimeout(()=>{ d1.hidden = true ; },1000); setTimeout(()=>{ row2.hidden = false ; },1000); // Opening a door which has a goat behind it. if (openDoor2 === losePath) { setTimeout(() => { doorImage2.src = openDoor2; }, 2000); } else if (openDoor3 === losePath) { setTimeout(() => { doorImage3.src = openDoor3; }, 2000); } //Event listener if the player opts to switch switchChoiceYes.onclick = () => { // If the opened door is door2, forming a // suitable dialogue. if (doorImage2.src === row2.hidden = true ; instructions.innerHTML = "You switched to door3" ; setTimeout(()=>{ instructions.innerHTML = "Revealing your chosen door......" ; },1000); // Opening the chosen door setTimeout(() => { doorImage3.src = openDoor3; }, 2500); //Conditions to display the result page if (openDoor3 === losePath) { setTimeout(() => { switchAndLose(); }, 3500) } else { setTimeout(() => { switchAndWin(); }, 3500) } } //If the opened door is door3, forming a suitable dialogue. else if (doorImage3.src === row2.hidden = true ; instructions.innerHTML = "You switched to door2" ; setTimeout(()=>{ instructions.innerHTML = "Revealing your chosen door......" ; },1000); // Opening the chosen door setTimeout(() => { doorImage2.src = openDoor2; }, 2500); //Conditions to display the result page if (openDoor2 === losePath) { setTimeout(() => { switchAndLose(); }, 3500) } else { setTimeout(() => { switchAndWin(); }, 3500) } } } //Event listener if the player does not opts to switch switchChoiceNo.onclick = () => { row2.hidden = true ; instructions.innerHTML = "Your choice is still door1" ; setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); // Opening the chosen door setTimeout(() => { doorImage1.src = openDoor1; }, 2500); // Conditions to display the result page if (openDoor1 === losePath) { setTimeout(() => { noSwitchAndLose(); }, 3500) } else { setTimeout(() => { noSwitchAndWin(); }, 3500) } } } |
The switchAndWin(), switchAndLose(), noSwitchAndWin(),noSwitchAndLose() are four functions that display the result of the player based on their choice.
Javascript
const switchAndWin = () => { body.hidden = true ; SwitchAndWin.hidden = false ; } const switchAndLose = () => { body.hidden = true ; SwitchAndLose.hidden = false ; } const noSwitchAndWin = () => { body.hidden = true ; NoSwitchAndWin.hidden = false ; } const noSwitchAndLose = () => { body.hidden = true ; NoSwitchAndLose.hidden = false ; } |
Similarly, for the door2 and door3, add Event listeners when clicked.
Javascript
doorImage2.onclick = () => { row1.hidden = true ; d2.hidden = false ; setTimeout(() => { d2.hidden = true ; }, 1000); setTimeout(() => { row2.hidden = false ; }, 1000) if (openDoor1 === losePath) { setTimeout(() => { doorImage1.src = openDoor1; }, 2000); } else if (openDoor3 === losePath) { setTimeout(() => { doorImage3.src = openDoor3; }, 2000); } switchChoiceYes.onclick = () => { if (doorImage1.src === row2.hidden = true ; instructions.innerHTML = "You switched to door3" setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); setTimeout(() => { doorImage3.src = openDoor3; }, 2500); if (openDoor3 === losePath) { setTimeout(() => { switchAndLose(); }, 3500) } else { setTimeout(() => { switchAndWin(); }, 3500) } } else if (doorImage3.src === row2.hidden = true ; instructions.innerHTML = "You switched to door1" ; setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); setTimeout(() => { doorImage1.src = openDoor1; }, 2500); if (openDoor1 === losePath) { setTimeout(() => { switchAndLose(); }, 3500) } else { setTimeout(() => { switchAndWin(); }, 3500) } } } switchChoiceNo.onclick = () => { row2.hidden = true ; instructions.innerHTML = "Your choice is still door2" setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); setTimeout(() => { doorImage2.src = openDoor2; }, 2500); if (openDoor2 === losePath) { setTimeout(() => { noSwitchAndLose(); }, 3500) } else { setTimeout(() => { noSwitchAndWin(); }, 3500) } } } doorImage3.onclick = () => { row1.hidden = true ; d3.hidden = false ; setTimeout(() => { d3.hidden = true ; }, 1000); setTimeout(() => { row2.hidden = false ; }, 1000) if (openDoor1 === losePath) { setTimeout(() => { doorImage1.src = openDoor1; }, 2000); } else if (openDoor2 === losePath) { setTimeout(() => { doorImage2.src = openDoor2; }, 2000); } switchChoiceYes.onclick = () => { if (doorImage1.src === row2.hidden = true ; instructions.innerHTML = "You switched to door2" setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); setTimeout(() => { doorImage2.src = openDoor2; }, 2500); if (openDoor2 === losePath) { setTimeout(() => { switchAndLose(); }, 3500) } else { setTimeout(() => { switchAndWin(); }, 3500) } } else if (doorImage2.src === row2.hidden = true ; instructions.innerHTML = "You switched to door1" setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); setTimeout(() => { doorImage1.src = openDoor1; }, 2500); if (openDoor1 === losePath) { setTimeout(() => { switchAndLose(); }, 3500) } else { setTimeout(() => { switchAndWin(); }, 3500) } } } switchChoiceNo.onclick = () => { row2.hidden = true ; instructions.innerHTML = "Your choice is still door3" setTimeout(() => { instructions.innerHTML = "Revealing your chosen door......" ; }, 1000); setTimeout(() => { doorImage3.src = openDoor3; }, 2500); if (openDoor3 === losePath) { setTimeout(() => { noSwitchAndLose(); }, 3500) } else { setTimeout(() => { noSwitchAndWin(); }, 3500) } } } |
Here’s the live version of the game: https://monty-hall-gfg.netlify.app/