Sign in to follow this  
Followers 0
Kebaan

Three gates - but only one car!

14 posts in this topic

After watching the movie 21 (about blackjack) and the serie Numb3rs, Iøve obviously seen that if there are 3 choices, and theres a car behind one of the gates and goats behind the others.

As an example I'll say you choose gate number one, so I tell you that behind gate number 2 there is a goat. The question is: "do you want to chage your guess to gate number 3?"

In these movies they say that you would have a much higher chance of winning the car if you change your guess. At first i did not understand why, so i wanted to make an experiment in autoit. So here it is.

I just wanted to show you and if I've made something in a weird way, please let me know how i should've made it =D

I know that my ASCII drawing could be made with some GUI instead, but i didn't feel like doing that yet ;)

;----------------------------------------------------------------------------------------;
; If you get the following choices:                                                      ;
;  ______   ______   ______                                                              ;
; |      | |      | |      |                                                             ;
; |  1   | |  2   | |  3   |                                                             ;
; |______| |______| |______|                                                             ;
; Youre told that on of them is a car, the other two is goats.                           ;
; If you choose 1, and the gamemaster tell you that gate number 2 is a goat.             ;
; Would you change your guess to gate number 3?                                          ;
;                                                                                        ;
; This is a simulation that shows that you would have a better chance of winning the car ;
; if you did that!                                                                       ;
; @Author: Kebaan                                                                        ;
;----------------------------------------------------------------------------------------;

Global $one, $two, $three, $prize, $car = "car", $goat = "goat", $choice, $carcount = 0, $carcount1, $percent

MsgBox(0, "Three gates - but only one car!", "You get the following choices:" & @CRLF & " ______   ______   ______" & @CRLF & "|          | |          | |          |" & @CRLF & "|    1    | |    2    | |    3    |" & @CRLF & "|______| |______| |______|" & @CRLF & @CRLF & "The 'gamemaster' tells you that there are one car and two goats behind the gates." & @CRLF & "If you choose gate number one, and the gamemaster tells you that gate number two is a goat." & @CRLF & "Would you want to change your guess to gate number three?" & @CRLF & @CRLF & "This is a simulation that shows that you would have a better chance of winning the car if you did!")
Global $NumberOfSimulations = InputBox("Times to run the simulation?", "Here you can choose how many times you want to run the simulation." & @CRLF & @CRLF & "The precision of the result depends on how many times you run the simulation.")

For $i = 1 to $NumberOfSimulations
    $prize = Random(1, 3, 1);===> Find a random gate to place the car.
    If $prize = 1 Then
        $one = $car
        $two = $goat
        $three = $goat
    ElseIf $prize = 2 Then
        $one = $goat
        $two = $car
        $three = $goat
    Else
        $one = $goat
        $two = $goat
        $three = $car
    EndIf;===> Define the gates' content.
    
    $choice = Random(1, 3, 1);===> Make a random guess.
    If $choice = 1 and $two = $goat Then
        $choice = 3
        If $three = $car Then
            $carcount = $carcount + 1
        Else
            $carcount = $carcount
        EndIf
    ElseIf $choice = 1 and $three = $goat Then
        $choice = 2
        If $two = $car then
            $carcount = $carcount + 1
        Else
            $carcount = $carcount
        EndIf
    ElseIf $choice = 2 and $one = $goat Then
        $choice = 3
        If $three = $car then
            $carcount = $carcount + 1
        Else
            $carcount = $carcount
        EndIf
    ElseIf $choice = 2 and $three = $goat Then
        $choice = 1
        If $one = $car then
            $carcount = $carcount + 1
        Else
            $carcount = $carcount
        EndIf
    ElseIf $choice = 3 and $one = $goat Then
        $choice = 2
        If $two = $car then
            $carcount = $carcount + 1
        Else
            $carcount = $carcount
        EndIf
    Else
        $choice = 2 and $three = $goat
        $choice = 1
        If $one = $car then
            $carcount = $carcount + 1
        Else
            $carcount = $carcount
        EndIf
    EndIf;===> Lots of logic, made to simulate that the guess is changed!
    
    
    
    
    $prize = Random(1, 3, 1);===> Find a random gate to place the car.
    If $prize = 1 Then
        $one = $car
        $two = $goat
        $three = $goat
    ElseIf $prize = 2 Then
        $one = $goat
        $two = $car
        $three = $goat
    Else
        $one = $goat
        $two = $goat
        $three = $car
    EndIf;===> Define the gates' content.
    
    $choice = Random(1, 3, 1);===> Make a random guess.
    If $choice = 1 Then
        If $one = $car Then
            $carcount1 = $carcount1 + 1
        Else
            $carcount1 = $carcount1
        EndIf
    ElseIf $choice = 2 Then
        If $two = $car Then
            $carcount1 = $carcount1 + 1
        Else
            $carcount1 = $carcount1
        EndIf
    Else
        $choice = 3
        If $three = $car Then
            $carcount1 = $carcount1 + 1
        Else
            $carcount1 = $carcount1
        EndIf
    EndIf;===> Lots of logic, made to simulate that you stick to your first guess!
Next

$percent1 =  $carcount1 / $NumberOfSimulations * 100
$percent =  $carcount / $NumberOfSimulations * 100
MsgBox( 0, "Number of cars won in %", "If you stuck to your first guess you would have won " & $percent1 & "% of the times!" & @CRLF & "But if you changed your guess you would have won " & $percent & "% of the times!")

Share this post


Link to post
Share on other sites



Hi!

This problem is called the monty hall problem. Read more about it here ;)

I also made a script some time ago to prove this, it has an GUI and it deals with the problem in a different way.

Maybe you could learn a thing or two :D

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <GUIEdit.au3>
#NoTrayIcon
Global $car, $choosed, $removed, $switchedfrom
Global $switch=True
Global $totalwon=0, $totalgames=0
Global $tests=0, $start=False
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Monty Hall", 224, 276, 193, 125)
$Label1 = GUICtrlCreateLabel("Number of tests:", 8, 8, 60, 17*2)
$Input1 = GUICtrlCreateInput("10000", 72, 8, 121, 21, BitOR($ES_RIGHT,$ES_AUTOHSCROLL,$ES_NUMBER))
$Label2 = GUICtrlCreateLabel("Change door?", 8, 40, 63, 17*2)
$Combo1 = GUICtrlCreateCombo("Yes", 72, 40, 121, 25)
GUICtrlSetData(-1,"No")
$Button1 = GUICtrlCreateButton("Start!", 8, 72, 187, 25, 0)
GUICtrlSetOnEvent(-1,"_starta")
$Edit1 = GUICtrlCreateEdit("", 8, 112, 209, 153, BitOR($ES_AUTOVSCROLL,$ES_READONLY,$ES_WANTRETURN,$WS_VSCROLL))
_GUICtrlEdit_SetLimitText($Edit1,10^100)
GUICtrlSetData(-1, "")
GUISetOnEvent(-3,"close")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
While 1
    Sleep(10)
    If $start=True Then
        $start=False
        _calc()
    EndIf
    
WEnd
Func _starta()
$start=True
EndFunc
Func _calc()

If GUICtrlRead($Combo1)="Yes" Then
    $switch=True
Else
    $switch=False
EndIf
$tests=GUICtrlRead($Input1)

GUICtrlSetData($Edit1,"")

For $i=1 To $tests
    $car=Random(0,2,1)
    $choosed=Random(0,2,1)
    Do
        $removed=Random(0,2,1)
    Until $removed<>$car AND $removed<>$choosed
    If $switch Then
        For $j=0 To 2
            If $j<>$choosed And $j<>$removed Then
                $choosed=$j
                ExitLoop
            EndIf
        Next
    EndIf
    If $choosed=$car Then
        $totalwon+=1
        $totalgames+=1
        _GUICtrlEdit_AppendText($Edit1,"Victory! ("&$totalwon&" / "&$totalgames&" ("&Round(($totalwon/$totalgames)*100,2)&" %))"&@CRLF)
    Else
        $totalgames+=1
        _GUICtrlEdit_AppendText($Edit1,"Lose! ("&$totalwon&" / "&$totalgames&" ("&Round(($totalwon/$totalgames)*100,2)&" %))"&@CRLF)
    EndIf
Next

EndFunc
Func close()
    Exit
EndFunc

Ps. I think it would be better to post this in example script ;)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

Yea i thought about that, but when looking ón all the other scripts in there i thought my script was very small and too newbyish :lmao:

Your on is noce ;) but i think my one is faster?

And I've got an update for yours :D you should do this in the start of your _calc function i think?

$totalwon = 0
        $totalgames = 0

Because as it is now the %calculation is wrong if you start doing a simulation where you do not change the doors and afterwards make it while changing doors :cheer: (or the other way around of course)

But I'll try to figure out how the GUI works =) thanks for the script ;)

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I was trying to be a smart-ass and made the same simulation in just 22 lines... but it doesn't work! Does anyone see what I'm doing wrong?

Here's the code:

dim const $TESTS = 4
dim const $SIMULATIONS = 10000
$output = ""
for $j=1 to $TESTS
    $win1 = 0
    for $i=1 to $SIMULATIONS
        $car = Random(1, 3, 1)
        $choice = Random(1, 3, 1)
        if $choice == $car then $win1 += 1
    next
    $result1 = Round(($win1 / $SIMULATIONS) * 100)
    $win2 = 0
    for $i=1 to $SIMULATIONS
        $car = Random(1, 3, 1)
        $choice = Random(1, 3, 1)
        if $choice <> $car then $win2 += Random(0, 1, 1)
    next
    $result2 = Round(($win2 / $SIMULATIONS) * 100)
    if $j > 1 then $output &= @LF & @LF
    $output &= "Test " & $j & @LF & "Stick: " & $win1 & "/" & $SIMULATIONS & " (" & $result1 & "%)" & @LF & "Switch: " & $win2 & "/" & $SIMULATIONS & " (" & $result2 & "%)"
next
MsgBox(0, "", $output)

Here's the thought behind it:

- Line's 6-10 is the test for sticking with your choice. The only thing that needs to be checked is that the first choice is the same as the location of the car. This part works well (as I always get a result of approx 33%).

- Line's 13-17 is the test for switching your choice. It will first check if your first choice is not equal to the car (because if it is you will never win anyway). Otherwise you'll still have a 50% chance to win. So I simply used Random(0,1,1) to simulate this. However, something in here's goes wrong but I have no idea what.

Anyone?

Edited by SaphuA

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

I don't understand line 18-20.. but on line 16 i don't understand why you would add random 0 or 1.. If you do not get the car you should add 1 all the time? so the code should be?

dim const $TESTS = 4
dim const $SIMULATIONS = 10000
$output = ""
for $j=1 to $TESTS
    $win1 = 0
    for $i=1 to $SIMULATIONS
        $car = Random(1, 3, 1)
        $choice = Random(1, 3, 1)
        if $choice == $car then $win1 += 1
    next
    $result1 = Round(($win1 / $SIMULATIONS) * 100)
    $win2 = 0
    for $i=1 to $SIMULATIONS
        $car = Random(1, 3, 1)
        $choice = Random(1, 3, 1)
        if $choice <> $car then $win2 += 1
    next
    $result2 = Round(($win2 / $SIMULATIONS) * 100)
    if $j > 1 then $output &= @LF & @LF
    $output &= "Test " & $j & @LF & "Stick: " & $win1 & "/" & $SIMULATIONS & " (" & $result1 & "%)" & @LF & "Switch: " & $win2 & "/" & $SIMULATIONS & " (" & $result2 & "%)"
next
MsgBox(0, "", $output)

I've tested and now it works ;).. but would you please explain lin 19-21?

EDIT: nvm, i understand the lines now ;) thanks :D

Edited by Kebaan

Share this post


Link to post
Share on other sites

Funny you brought this up. I remember the lecture where I encountered this. Apparently it was a woman who solved, and explained, this kind of problem domain. The fact that she beet here male colleagues to it did not fall in good earth (as we say in Norway). They even gave here the nick name "The Goat". At least that is the story our prof. gave..;)

I just wanted to show you and if I've made something in a weird way, please let me know how i should've made it =D

Since you ask. I don't know how you should have made it. this is how I would have done it. Lesson to learn is: small testable functions. Comments in the code. Tests to verify the functions. When you know it works you can add the snazzy GUI. Or you can work on some other statistical functions to verify or contradict the results you get.

opt("MustDeclareVars", 1)
Func MontyHallGame()
    ; Chose on of three boxes. Then you get to know one loosing box
    ; With this additional information Probability theory now 
    ; indicates that you should switch your choice.
    ;
    ; Returns 1 if you win otherwise 0.
    ; @extended contains 1 if you selected the winner on the first choice
    ;
    ; Chose one of three boxes. When you have chosen 
    Local $selected, $ext=0, $winner, $knownLoser
    ; One is the winning box
    $winner = Random(0,2,1)
    ; You select one box
    sleep(random(0, 10,1))
    $selected = Random(0,2,1)
    ; If you have a winner, you dont know it. So set a flag to let us know later.       $ext = 1
    $ext =  $selected AND $winner
    ; At this point you get to know one looser box
    $knownLoser = GetAMontyHallLooser($selected, $winner)
    ; Switch selection based on previous selection and new knowledge.
    Return SetExtended($ext, $winner = SwitchMontyHallChoice($knownLoser, $selected))
EndFunc
Func GetAMontyHallLooser($selected, $winner)
    ; The participant chose  $selected
    ; The game host knows the $winner
    Local $ret
    Do 
        $ret = Random(0,2,1)
    Until $ret <> $selected AND $ret <> $winner
    Return $ret
EndFunc
func testGetAMontyHallLooser()
    ; Verify GetAMontyHallLooser function
    assert(0 = GetAMontyHallLooser(1, 2))
    assert(1 = GetAMontyHallLooser(0, 2))
    assert(2 = GetAMontyHallLooser(0, 1))
    assert(0 = GetAMontyHallLooser(2, 1))
    assert(2 = GetAMontyHallLooser(1, 0))
    assert(1 = GetAMontyHallLooser(2, 0))
EndFunc
Func SwitchMontyHallChoice($known, $select)
    If $known+$select = 1 then Return 2
    If $known+$select = 3 then Return 0
    If $known+$select = 2 then Return 1
EndFunc
Func testSwitchMontyHallChoice()
; Verify SwitchMontyHallChoice function
 assert(1 = SwitchMontyHallChoice(0, 2))
 assert(0 = SwitchMontyHallChoice(1, 2))
 assert(2 = SwitchMontyHallChoice(0, 1))
EndFunc
func assert($val, $msg="", $erl=@ScriptLineNumber, $err=@error, $ext=@extended)
    If not $val Then ConsoleWrite("(" & $erl & ") := [" & $err & "][" & $ext &  "] " & $msg & @CRLF)
EndFunc
; =========================================
; Run self tests
If not @Compiled Then 
    testAssert()
    exit
    testGetAMontyHallLooser()
    testSwitchMontyHallChoice()
EndIf
; =========================================
; === Main part

Local $i, $wins, $target
; Run test
For $r = 1 to 10
    For $i = 1 to 1000
        $wins += MontyHallGame()
        $target += @extended
    Next
    ConsoleWrite("Wins:=" & $wins & ", target:=" & $target & @crlf)
    $wins = 0
    $target = 0
next

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

No you're wrong.

In the second case, where the player always decides to pick something different, 2 things can happen:

- If the player picks the car, he can only pick a goat so he wins nothing.

- If he picks a goat, he can either pick a car or a goat, so he then has 50% chance of winning or losing.

So in my code I first check to see if the player did NOT pick the car (if he did it's over anyway).

if $choice <> $car

If that is true I increase the score with:

$win += Random(0, 1, 1)

Since it's random, there is a 50% chance that it returns 0 and 50% chance that it returns 1. So either he get's added 0 score or 1.

In theory, it sounds perfectly fine to me, yet there's still a flaw in my code.

Edited by SaphuA

Share this post


Link to post
Share on other sites

- If he picks a goat, he can either pick a car or a goat, so he then has 50% chance of winning or losing.

If that was right you had made it right - but! you forget that the gamehost will reveal one of the goats after your first choice. So if you pick a goat, he will show you the other one, and you will only have the car left ;)

@Uten, thanks for the reply. I'm learning alot of this ;) I don't understand all your code though, but i think I will when i have time to read abit up on it :D

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

SaphuA, care to elaborate where I'm wrong. I don't get it. I'm not saying I ain't. Is my understanding of the game wrong or is it the implementation?

From the wikipage:

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?" Is it to your advantage to switch your choice?

This was how I remembered it from the lecture. Just had to look at it since you made your claim.;)

Remember that the player do not get to open the first door he chose. Neither do he get the knowledge that there is a car or a donkey behind it. All he gets to know is where there is a donkey after he has made his choice!

so your analysis

- If the player picks the car, he can only pick a goat so he wins nothing.

- If he picks a goat, he can either pick a car or a goat, so he then has 50% chance of winning or losing.

does not look correct to me.

Uten

Edit: A tad late there I see.. Got to start typing faster and checking less..:D

Edited by Uten

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

It was a reply on kebaan ;)

Now that you have removed my name, it could be. When you first posted it, it was addressed to me!

EDIT: Look at my next post.

Edited by Uten

Share this post


Link to post
Share on other sites

Now that you have removed my name, it could be. When you first posted it, it was addressed to me!

Lies!

Share this post


Link to post
Share on other sites

I have to admit you that your right about the name SaphuA. Dog out the deleted mail notification from a backup and found that I have mixed up the part where notification inserts my name, with your post.

Sincerely sorry about that SaphuA.

Uten

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0