Gameshow paradox


Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?"

Source: https://en.wikipedia.org/wiki/Monty_Hall_problem



At this point, 2 doors are closed and you know one of them has the car, so you have a 50% chance of winning, whether you keep your selection or change it, right?



WRONG! When making the initial selection, you only had a 1/3 probability of guessing correctly. If you switch now, the probability of winning increases. Don't believe me? I don't blame you; it's very counter-intuitive. But play the game below to check for yourself.



Pick a random door, then the host reveals another door with a goat. Click "keep your selection". You will probably (with a probability of 2/3) lose. Repeat several times. Or let the computer play for you using the 'Automatically run 100 "keep" games'. The "keep" games wins percentage will stubbornly keep coming back to 33%.



Now try running a couple hundred "change" games and see how the probability goes up to about 67%.

There is no trick - it's pure math. The full code is below. Also, everything is logged in the console. Have fun!


<html>
<meta http-equiv="Content-Typecontent="text/htmlcharset=utf-8"/>
<style>
button {
    font-size: 80px;
     width33.33%;
}
 
div {
    white-spacepre;
    border-stylesolid;
        line-height2;
        font-size: 20px;
}
</style>
<body>
<script>
const buttons = [];
const doors = [];
const massGameCount = 100// number of games run upon clicking the "automatic" buttons
let winningDoor// number of the door with the prize (car)
let doorSelected// number of the door selected by the player
let doorRevealed// number of the door revealed by the host
let mode// user selection: keep or change
// for statistical purposed only: number of games played and corresponding wins:
let keepGames = 0;
let changeGames = 0;
let keepWins = 0;
let changeWins = 0;
 
function initGame() {
    textBar.textContent = "Choose a door";
    keepButton.hidden = true// hide all buttons
    changeButton.hidden = true;
    massKeepButton.hidden = true;
    massChangeButton.hidden = true;
    mode = "keep"; // "keep" vs "change" game mode
 
    for (let i = 0i < 3i++) { // display 3 closed doors, gray and disabled:
        buttons[i].innerHTML = "🚪";
        buttons[i].style.background = 'grey';
        buttons[i].disabled = false;
        doors[i] = "goat";
        // initially all doors have a goat
    }
    winningDoor = Math.floor(Math.random() * 3); // replace the goat behind a random door with the prize - car
    console.log('Prize door: ' + winningDoor);
}
 
function doorClick(index) {
    // player selects the first door
    console.log('Selected door: ' + index);
    doorSelected = index;
    buttons[index].style.background = 'green';
    textBar.textContent = "You selected the green door.\nThe host revealed another door with a goat.\nWould you like to change your choice (to the gray dooror keep your original choice?";
    keepButton.hidden = false;
    changeButton.hidden = false;
    // the host randomly reveals one door with a goat:
    doorRevealed = "none";    // initially no door is revealed
    let direction = -1;    // initially assume search direction from right to left
    let currentDoor = 2;    // start with the rightmost door
    if (Math.random() < 0.5) { // 50% probability of switching direction
        direction = 1// reverse the direction
        currentDoor = 0// switch to the leftmost door
    }
 
    for (let i = 0i < 3i++) {        // check each door
        buttons[i].disabled = true;
        // if not the winning door, not the door selected by user and no door has been revealed yet:
        if (currentDoor !== winningDoor && currentDoor !== doorSelected && doorRevealed == "none") {
            buttons[currentDoor].innerHTML = "🐐";  // reveal the door
            doorRevealed = currentDoor;
            console.log("Revealed door: " + doorRevealed);
        }
        currentDoor = currentDoor + direction;
        // continue searching in the same direction
    }
}
 
function listenerForI(i) {
    // add click listener to each button
    buttons[i].addEventListener('mousedown', function() {
        doorClick(i);
    }, false);
}
 
function runMassGames(massMode) {
    // automatically run multiple games
    for (let i = 0i < massGameCounti++) {
        initGame();
        doorClick(Math.floor(Math.random() * 3));
        // select random door for player
        if (massMode == "change") {
            // "change" type game
            changeButton.click();
        } else {
            keepButton.click();
            // "keep" type game
        }
    }
}
 
for (let i = 0i < 3i++) {
    // create buttons for displaying the doors
    buttons[i] = document.createElement('button');
    document.body.appendChild(buttons[i]);
    listenerForI(i);
}
 
const textBar = document.createElement('div');
// for displaying messages to the player
document.body.appendChild(textBar);
 
const keepButton = document.createElement('div');
// div used as a button to choose the "keep" game mode
keepButton.textContent = 'Click here to keep the green door';
document.body.appendChild(keepButton);
 
const changeButton = document.createElement('div');
// div used as a button to choose the "change" game mode
changeButton.textContent = 'Click here to change to the gray door';
document.body.appendChild(changeButton);
 
const massChangeButton = document.createElement('div');
massChangeButton.textContent = 'Click here to automatically run 100 "Changegames';
document.body.appendChild(massChangeButton);
 
const massKeepButton = document.createElement('div');
massKeepButton.textContent = 'Click here to automatically run 100 "Keepgames';
document.body.appendChild(massKeepButton);
 
// define behavior of each button/div:
textBar.onclick = initGame;
 
massChangeButton.onclick = function() {
    runMassGames("change");
}
;
 
massKeepButton.onclick = function() {
    runMassGames("keep");
}
;
 
keepButton.onclick = function() {
    // player selects a "keep" game
    keepButton.hidden = true;
    changeButton.hidden = true;
    for (let i = 0i < 3i++) {
        if (i == winningDoor) {
            buttons[i].innerHTML = '🚗';
        } else {
            buttons[i].innerHTML = "🐐";
        }
    }
    if (mode == "change") {
        // update the stats
        changeGames++;
    } else {
        keepGames++;
    }
    if (doorSelected == winningDoor) {
        textBar.textContent = "You win!\nClick here to restart.";
        console.log("Win");
        if (mode == "change") {
            changeWins++;
        } else {
            keepWins++;
        }
    } else {
        textBar.textContent = "You lose!\nClick here to restart.";
        console.log("Loss");
    }
    let stats = "\n\nGames where you kept the initial door: " + keepGames;
    stats = stats + "\nKeep game wins: " + keepWins;
    if (keepGames) {
        stats = stats + "\nKeep game wins %: " + Math.floor(keepWins / keepGames * 100);
    }
    stats = stats + "\nGames where you changed to another door: " + changeGames;
    stats = stats + "\nChange game wins: " + changeWins;
    if (changeGames) {
        stats = stats + "\nChange game wins %: " + Math.floor(changeWins / changeGames * 100);
    }
    textBar.textContent = textBar.textContent + stats;
    console.log('----------------------');
    massKeepButton.hidden = false;
    massChangeButton.hidden = false;
}
;
 
changeButton.onclick = function() { // player selects a "change" game:
    mode = "change";
    buttons[doorSelected].style.background = 'gray';
    let newReveal;
    for (let i = 0i < 3i++) {
        if (i !== doorSelected && i !== doorRevealed) {  // change the selected door to the unrevealed door
            newReveal = i;
            console.log("Change to door " + newReveal);
        }
    }
    doorSelected = newReveal;
    buttons[doorSelected].style.background = 'green';
    keepButton.onclick();  // continue as if it was a "keep" game
}
;
 
initGame(); // initialize the first game
 
</script>
</body>
</html>
All the code is provided under
the MIT license

Check out these programming tutorials:

JavaScript:

Optical illusion (18 lines)

Spinning squares - visual effect (25 lines)

Oldschool fire effect (20 lines)

Fireworks (60 lines)

Animated fractal (32 lines)

Physics engine for beginners

Physics engine - interactive sandbox

Physics engine - silly contraption

Starfield (21 lines)

Yin Yang with a twist (4 circles and 20 lines)

Tile map editor (70 lines)

Sine scroller (30 lines)

Interactive animated sprites

Image transition effect (16 lines)

Your first program in JavaScript: you need 5 minutes and a notepad


Fractals in Excel

Python in Blender 3d:

Domino effect (10 lines)


Wrecking ball effect (14 lines)

3d fractal in Blender Python