Python not finishing for loop - python

I just started learning python and I figured for fun to see if I could make a python version of the monty hall problem. Everything seems to be working on a small scale when I use 1 or 2 iterations but past that nothing is working. The for loop is not finishing the amount of iterations I want it to.
import random
def problem(tests):
wins = 0
losses = 0
doors = ["goat", "car", "goat"]
for test in range(tests):
#we shuffle the doors
random.shuffle(doors)
#the player picks a door
choice = random.choice(doors)
#monty chooses a door
montychoice = random.choice(doors)
while montychoice != 'car' or montychoice == choice:
montychoice = random.choice(doors)
#if the player's door is a car, he losses
if choice == 'car':
losses += 1
print 'goat'
elif choice == 'goat':
wins += 1
print 'car'
print "Switching wins: %d" % wins
print "Switching loses: %d" % losses
problem(100)

The problem isn't with the for-loop, but with the while loop.
In order for your while loop to break, montychoice would have to equal car AND the player's choice. But what if the player's choice isn't car, but it's goat? The while-loop will never break.
I think you want and and not or for your while loop. That way, if either condition isn't met, the loop breaks.

The problem is this loop
while montychoice != 'car' or montychoice == choice:
montychoice = random.choice(doors)
Once the player has picked the car, this says that whether monty picks a car or not a car, he has to pick another choice. So he keeps on picking forever, and you don't get any further in your script.

Related

Python Monty Hall Simulation didn't give expected answer

I get the answer 0.5 in the Monty Hall Simulation.
From the textbook: We assume the car was put behind a door by rolling a three-sided die which made all three choices equally likely. Monty knows where the car is, and always opens a door with a goat behind it. Finally, we assume that if Monty has a choice of doors (i.e., the contestant has picked the door with the car behind it),he chooses each door with probability 1/2. Marilyn clearly expected her readers to assume that the game was played in this manner.
Marilyn's answer is 0.66, and I want to simulate this answer, but I got 0.5 and don't know what's wrong with my codes.
n = 1000000
count = 0
for i in range(n):
doors = [1,2,3]
# the inital doors that monty can choose
monty_choose = [1,2,3]
# suppose the car is behind door 1
car = 1
# monty cannot choose the door that has car
monty_choose.remove(car)
ichoose = random.choice(doors)
if ichoose in monty_choose:
# monty cannot choose the door i select
monty_choose.remove(ichoose)
monty = random.choice(monty_choose)
else:
monty = random.choice(monty_choose)
# i cannot choose the door that monty chose
doors.remove(monty)
s = random.choice(doors)
if s == car:
count = count + 1
print(count/n)
Your code could work find until you get to the last bit. You are picking the door at random:
s = random.choice(doors)
if s == car:
count = count + 1
When what you want to do is to switch doors. You can do this by simply removing your first choice then indexing the list at 0.
doors.remove(ichoose)
if doors[0] == car:
count = count + 1
full code and result
import random
n = 1000000
count = 0
for i in range(n):
doors = [1,2,3]
# the inital doors that monty can choose
monty_choose = [1,2,3]
# suppose the car is behind door 1
car = 1
# monty cannot choose the door that has car
monty_choose.remove(car)
ichoose = random.choice(doors)
if ichoose in monty_choose:
# monty cannot choose the door i select
monty_choose.remove(ichoose)
monty = random.choice(monty_choose)
else:
monty = random.choice(monty_choose)
# i cannot choose the door that monty chose
doors.remove(monty)
doors.remove(ichoose)
if doors[0] == car:
count = count + 1
print(count/n)
0.667145
Your code calculates probability of 0.5 simply because s = random.choice(doors) is choosing from car or goat equally.
Your code does not reflect how the Monty Hall problem works.
If the contestant makes a choice and sticks with that choice, then the probability is obviously 0.33. You never allow ichoose to stick with their choice.
The less obvious part is that the contestant can change their choice and then the probability is 0.66. You never allow ichoose to change their choice.
doors = [1,2,3] # total doors
i_choose = [1,2,3] # the inital doors that I can choose
car = 1 # suppose the car is behind door 1
host_choose = [2,3] # the empty doors the host could show
n = 1000000
count = 0
car = 1
for i in range(n):
# you can randomize car here, but remember to change host_choose accordingly
i_choice = random.choice(doors) # I choose one door randomly
if first_choice in host_choose:
host_choose.remove(first_choice) # the host cannot open the chosen door
host_choice = random.choice(host_choose) # the host shows that a door is empty
i_choose.remove(host_choice)
i_choose.remove(first_choice)
# the goal is to show that always changing door results in 66% winrate
i_choice = random.choice(i_choose) # this is actually a one-element list
if i_choice == car:
count = count + 1
i_choose = [1,2,3]
doors = [1,2,3]
host_choose = [2,3]
print(count/n)
So basically, you're mixing up who and when does the choices:
A picks a door in [1, 2, 3]
B knows where the car is, and reveals an empty door (that A didn't pick)
A now can choose to keep their door or to change it
Your goal is to show that changing door leads to 0.66 probability of getting the car.

Determining winner in Rock Paper Scissors [python]

I'm a beginner in python trying to create a RPS game where human is playing against a computer. The game is created such that it would be played over a number of determined rounds (best of 3 rounds). A draw is considered a point for each side.
My problem is setting the while condition. Initially I did this:
while (player_count + computer_count) != winning_score : where the game ends when all round are played. However there will be instances where not all rounds needs to be played and the winner can already be determined (because of draws, each player will get a point).
How do I change the while condition such that when either players get winning_score/2 + 1, the game ends?
hi you can probably do it like this
winning_count = winning_score/2+1
while(player_count < winning_count) and (computer_count < winning_count):
...
Once either the player win or the computer win is more than the winning count, it goes to False and the loop breaks
Just in case you want to have another perspective on how to implement the game (and how to determine the winner), I exhort you to play with the following version:
import random
options = {1: 'Rock', 2: 'Scissors', 3: 'Paper'}
def play():
score = [0, 0]
while not any(wins == 3 for wins in score):
print(f'SCORE\tUser: {score[0]} - PC: {score[1]}')
user_selection = int(input('Enter your selection:{}> '.format(
''.join([f'\n{n}: {option}\n' for n, option in options.items()]))))
pc_selection = random.randint(1, 3)
print(f'{options[user_selection]} vs. {options[pc_selection]}')
if user_selection in (pc_selection - 1, pc_selection + 2):
print('User wins')
score[0] += 1
elif user_selection == pc_selection:
print('Draw')
else:
print('PC Wins')
score[1] += 1
input('\n_____ ENTER TO PROCEED _____')
winner = 'User' if score[0] == 3 else 'PC'
print(f'\n{winner} won the match!')
play()
Hopefully you will find here something useful and new for your learning process.

Beginning my while loop in the two dice pig game in python

I'm currently writing code for a dice game in Python 3.6
I understand my coding is a little off in this, however, I'm really just wondering how to start my while loop.
The instructions of the game are as follows...
A human player plays against the computer.
They take turn rolling two dice, and the totals of the dice are added together Unless a 1 is rolled.
If a one 1 is rolled, you get no score added and it's the next person's turn. If two 1's are rolled, you lose all of your points and its the next person's turn.
The first player to 100 scores, wins the game.
When I run this code, I get the same randomly generated number's over and over. I am not sure how to get different number's on each roll. I also don't understand how to keep up with each player's score at the end of their turn's.
Any help at all would be greatly appreciated.
import random
def main():
print("Welcome to the Two Dice Pig Game. You are Player 1!")
Player1 = 0
Player2 = 0
while(Player1<100 or Player2<100):
p1dice=random.randrange(1,7)
p1dice2=random.randrange(1,7)
Player1 = p1dice+p1dice2
print("Player 1 dice 1 =",p1dice)
print("Player 1 dice 2 =",p1dice2)
print("Player 1 dice total =",Player1)
print("Does player 1 want to hold?")
choose1 = input("Enter y for yes or n for no.")
if(choose1=="n"):
print("Player 1 dice 1 =",p1dice)
print("Player 1 dice 2 =",p1dice2)
print("Player 1 dice total =",Player1)
print("Does player 1 want to hold?")
choose1 = input("Enter y for yes or n for no.")
elif(choose1=="y"):
print("It's player 2's turn.")
print("Player 2 dice 2 =",p2dice)
print("Player 2 dice 2 =",p2dice2)
print("Player 2 dice total =",Player2)
print("Does player 2 want to hold?")
choose2 = input("Enter y for yes or n for no.")
main()
Try changing the line
Player1 = p1dice+p1dice2
to
Player1 += p1dice+p1dice2
The old version replaces the value of Player1 each time. The new version adds to it.
By the way, the += is a shorthand for
Player1 = Player1+p1dice+p1dice2
Many of Python's other operators have a similar "augmented assignment" notation.
So your problem is that the random numbers don't work like you want rather than something about "starting your loop"?
I really only see this happening because your system clock is messed up(random uses the current time as seed for random).
Have you tried instantiating random.Random() and calling from that?

Python Blackjack: Updating number of wins after each game

This is the function in my blackjack python program for determining the winner of a round. The counts playerScore and dealerScore are supposed to increment with each win, but when running the game multiple times they never increase past 1. I think I need another loop or function to deal with this, but how can I properly increment the wins with multiple plays?
def total(self, dealer):
# determines winner
playerScore=0
dealerScore=0
if self.hand_sum > dealer.hand_sum:
print("\nYou won the hand!")
playerScore+=1
elif self.hand_sum < dealer.hand_sum:
if dealer.hand_sum <= 21:
print("\nYou lost the hand!")
dealerScore+=1
else:
print("\nDealer busted\n")
else:
print("\nYou tied\n")
print("Dealer's hand:", dealer.cards, " Dealer's sum:", dealer.hand_sum)
print("Your hand:", self.cards, "Your sum:", self.hand_sum)
print("\n*******************\n")
print("Number of Wins:\n")
print("Player: %d")%playerScore
print("Dealer: %d")%dealerScore
print("\n*******************\n")
start()
Every time you run the total function, you reset the scores to 0. If you did that at the start of the application instead your counts wouldn't get reset. Best I can say with only this part of the code available.

Python Black Jack game variant

My Black Jack code is very basic but is running quite smoothly, however I have run into a speed bump. Thus im here. When I call "Hit" to send me another card in my While loop, for every loop the DECK instantiates the same card. The first 2 drawn and the Hit card are always different but within the While loop (which is set to end when the player says "stay" and doesnt want another card.) the Hit cards remain the same.
import random
import itertools
SUITS = 'cdhs'
RANKS = '23456789TJQKA'
DECK = tuple(''.join(card) for card in itertools.product(RANKS, SUITS))
hand = random.sample(DECK, 2)
hit = random.sample(DECK, 1)
print("Welcome to Jackpot Guesser! ")
c = input("Would you like to play Black Jack or play Slots? ")
if c == 'Black Jack':
print()
print("Welcome to Black Jack! Here are the rules: ")
print("Black Jack is a game of whit, skill with a bit of Luck. You will start with 2 card and try to achieve a total of 21 points. \n Each cards worth is equal to its number, face cards are worth 10 and the Ace can be 1 or 11 points. You decide. \n You can decide to -Stay- and take the points you have or -Hit- to get another card. If you get 21 its Black Jack and you win. \n If no one gets 21, the highest points win, but if you go over 21 you -Bomb- and lose everything. \n Becarful not to Bomb and goodluck out there! Remember, you got to know when to Hit, when to Stay and when to walk away! \n")
print(hand)
print()
g = 'swag'
while g != 'Stay':
g = input(("What would you like to do, Stay or Hit: "))
if g == 'Hit':
print(hit)
elif g == 'Stay':
print("Lets see how you did!")
else:
print("test3")
elif c == 'Slots':
print("test")
else:
print("test2")
EX: Hand: Td(two diamonds), 3c(3 club)
Hit: 7s(7 spades)
hit 7s
hit 7s
hit 7s
...
stay: lets see how you did. I need the continued While loop Hits to differ, any ideas.
The problem is that you are generating the hit card only once, during the start of the program. Changing your code from
if g == 'Hit':
print(hit)
to something like
if g == 'Hit':
hit = random.sample(DECK, 1)
print(hit)
will make it outputs different cards on each hit.

Categories

Resources