简体   繁体   中英

Let's make a deal python game

I am required to code a python program that's based on the old TV show, Let's make a deal. I got the program to print out the number of games and if the user should have switched or stayed. Now I am trying to figure out how to print the percentage of the times the user should have stayed and switched altogether.

here is what the test input is:

25
7
exit

Heres what the program should output:

Game 1
Doors : [ ’G’, ’C’, ’G’ ]
Player Selects Door 1
Monty Selects Door 3
Player should switch to win.
Game 2
Doors : [ ’C’, ’G’, ’G’ ]
Player Selects Door 2
Monty Selects Door 3
Player should switch to win.
Game 3
Doors : [ ’G’, ’C’, ’G’ ]
Player Selects Door 1
Monty Selects Door 3
Player should switch to win.
Game 4
Doors : [ ’C’, ’G’, ’G’ ]
Player Selects Door 2
Monty Selects Door 3
Player should switch to win.
Game 5
Doors : [ ’G’, ’G’, ’C’ ]
Player Selects Door 3
Monty Selects Door 1
Player should stay to win.
Game 6
Doors : [ ’G’, ’C’, ’G’ ]
Player Selects Door 2
Monty Selects Door 1
Player should stay to win.
Game 7
Doors : [ ’G’, ’G’, ’C’ ]
Player Selects Door 2
Monty Selects Door 1
Player should switch to win.
Stay Won 28.6% of the time.
Switch Won 71.4% of the time.
How many tests should we run?
Thank you for using this program.

Here is what my program outputs:

Enter Random Seed:
25
Welcome to Monty Hall Analysis
Enter 'exit' to quit
How many tests should we run?
7
Game 1
Doors: ['G', 'C', 'G']
Player Selects Door 1
Monty Selects Door 3
Player should switch to win.
Game 2
Doors: ['G', 'C', 'G']
Player Selects Door 2
Monty Selects Door 1
Player should stay to win.
Game 3
Doors: ['C', 'G', 'G']
Player Selects Door 1
Monty Selects Door 3
Player should stay to win.
Game 4
Doors: ['G', 'G', 'C']
Player Selects Door 3
Monty Selects Door 2
Player should stay to win.
Game 5
Doors: ['G', 'G', 'C']
Player Selects Door 3
Monty Selects Door 2
Player should stay to win.
Game 6
Doors: ['G', 'C', 'G']
Player Selects Door 3
Monty Selects Door 1
Player should switch to win.
Game 7
Doors: ['C', 'G', 'G']
Player Selects Door 2
Monty Selects Door 3
Player should switch to win.
How many tests should we run?

Here is the code I made:

import random
import sys

try:
    randSeed = int(input('Enter Random Seed:\n'))
    random.seed(randSeed)
except ValueError:
    sys.exit("Seed is not a number!")

print('Welcome to Monty Hall Analysis')
print("Enter 'exit' to quit")

while True:
    testNum = input('How many tests should we run?\n')
    valid = False
    while not valid:
        try:
            if testNum == "exit":
                sys.exit("Thank you for using this program.")
            else:
                testNum = int(testNum)
                valid = True
        except ValueError:
            testNum = input('Please enter a number:\n')
    pStay = 0
    pChange = 0
    numGame = 0
    for numGame in range(1, testNum + 1):
        doorList = ['C', 'G', 'G']
        random.shuffle(doorList)
        print('Game', numGame)
        print('Doors:', doorList)
        playerDoor = random.randint(0,2)
        montyDoor = random.randint(0,2)
        print('Player Selects Door', playerDoor+1)
        while montyDoor == playerDoor or doorList[montyDoor] == 'C':
            montyDoor = random.randint(0,2)
        print('Monty Selects Door', montyDoor+1)
        if doorList[playerDoor] == 'C':
            var = 0
        else:
            var = 1

        if var == 0:
            pStay += 1
            print('Player should stay to win.')
            pStay += 1
        if var == 1:
            print('Player should switch to win.')

Sorry if my code does not look right or is confusing. This is my first time programming thanks.

Well, you keep track of the number of times the player should have stayed to won. So the percentage to stay is just "(pStay / float(testNum)) * 100)" then simply subtract that number from 100 to get the percentage to change (since they have to add up to 100%)

Thought I should provide some more info. The formula is taking the number of stay games out of the total number of games. You multiply by 100 to convert from a decimal value to percent.

So if you should have stayed in 1 game, and you played 10 games, it would be 1/10, which is .1, times 100, is 10%.

Since 1/10 you should have stayed, that means that 9/10 you should have changed. So you can subtract the stay percentage to get the change percentage, ie 100% - 10% = 90%

The reason I put the float() conversion in the code is because in python2 if you divide an integer by an integer, it doesn't calculate the fractional part. It just rounds down to the integer value. So 1/10 would give you 0, not .1. In python3 it does actually produce a fractional value, but since I don't know which version you are using, it is safe to cast it to a float to get the expected result

See the added comments below, you were close. However you were missing a sum count variable for pSwitch. Hope this helps.

import random
import sys

try:
    randSeed = int(input('Enter Random Seed:\n'))
    random.seed(randSeed)
except ValueError:
    sys.exit("Seed is not a number!")

print('Welcome to Monty Hall Analysis')
print("Enter 'exit' to quit")

while True:

    # Total Number of Games
    testNum = input('How many tests should we run?\n')

    valid = False
    while not valid:
        try:
            if testNum == "exit":
                sys.exit("Thank you for using this program.")
            else:
                testNum = int(testNum)
                valid = True
        except ValueError:
            testNum = input('Please enter a number:\n')
    pStay = 0
    pSwitch = 0  # Also need a running count var for switch
    numGame = 0
    for numGame in range(1, testNum + 1):
        doorList = ['C', 'G', 'G']
        random.shuffle(doorList)
        print('Game', numGame)
        print('Doors:', doorList)
        playerDoor = random.randint(0,2)
        montyDoor = random.randint(0,2)
        print('Player Selects Door', playerDoor+1)
        while montyDoor == playerDoor or doorList[montyDoor] == 'C':
            montyDoor = random.randint(0,2)
        print('Monty Selects Door', montyDoor+1)
        if doorList[playerDoor] == 'C':
            var = 0
        else:
            var = 1

        if var == 0:
            #pStay+=1  - - Not sure why you have two increments for pStay.. only need one.
            print('Player should stay to win.')
            pStay += 1
        if var == 1:
            print('Player should switch to win.')
            pSwitch += 1 # Also increment the pSwitch

    # Print out the percentages
    print('\n')    
    print("Percentage of times player should have STAYED: ",(pStay/testNum) * 100, "%")
    print("Percentage of times player should have SWITCHED: ",(pSwitch/testNum) * 100, "%")

Here is a Python 3.6 simulation of a generalized version of Make a Deal using sets. In the generalized version of Make a Deal the number of doors and doors to open can be varied. See for reference:

https://math.stackexchange.com/questions/608957/monty-hall-problem-extended

If run with doors = 3 and doors_to_open = 1, the expected result is 33% if the option is not taken to switch doors and 66% when it is.

#!/usr/bin/env python
'''  application of Make a deal statistics
     application is using sets {}
     for reference see:
https://math.stackexchange.com/questions/608957/monty-hall-problem-extended
'''
import random


def Make_a_Deal(doors, doors_to_open):
    '''  Generalised function of Make_a_Deal. Logic should be self explanatory
         Returns win_1 for the option when no change is made in the choice of
         door and win_2 when the option to change is taken.
    '''
    win_1, win_2 = False, False

    doors = set(range(1, doors+1))
    price = set(random.sample(doors, 1))
    choice1 = set(random.sample(doors, 1))
    open = set(random.sample(doors.difference(price).
               difference(choice1), doors_to_open))
    choice2 = set(random.sample(doors.difference(open).
                  difference(choice1), 1))
    win_1 = choice1.issubset(price)
    win_2 = choice2.issubset(price)

    return win_1, win_2


def main():
    '''  input:
         - throws: number of times to Make_a_Deal (must be > 0)
         - doors: number of doors to choose from (must be > 2)
         - doors_to_open: number of doors to be opened before giving the 
           option to change the initial choice (must be > 0 and <= doors-2)
    '''

    try:
        throws = int(input('how many throws: '))
        doors = int(input('how many doors: '))
        doors_to_open = int(input('how many doors to open: '))
        if (throws < 1) or (doors < 3) or \
                (doors_to_open > doors-2) or (doors_to_open < 1):
            print('invalid input')
            return

    except Exception as e:
        print('invalid input: ', e)
        return

    number_of_wins_1, number_of_wins_2, counter = 0, 0, 0

    while counter < throws:
        win_1, win_2 = Make_a_Deal(doors, doors_to_open)

        if win_1:
            number_of_wins_1 += 1
        if win_2:
            number_of_wins_2 += 1

        counter += 1
        print('completion is {:.2f}%'.
              format(100*counter/throws), end='\r')

    print('number of wins option 1 is {:.2f}%: '.
          format(100*number_of_wins_1/counter))
    print('number of wins option 2 is {:.2f}%: '.
          format(100*number_of_wins_2/counter))


if __name__ == '__main__':
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM