I was doing a simple python game ( I'm new to programming, sorry if asked anything wrong ) where two players play and answer the questions.
Underlying principles of the game:
There are several possible answers that a player can guess from. Each possible answer has a certain amount of points associated with it. If the player guesses an answer that exists in the possible answers, they will be rewarded with the corresponding amount of points.
question = "Name something James Bond eats everyday"
possible_answers = [("LEMON/CITRUS", 25), ("KETCHUP/MUSTARD", 25), ("TOOTHPASTE", 19), ("ZIT/BLACKHEAD", 14), ("GLUE", 6), ("MY POOPER", 3), ("LOTION BOTTLE", 2), ("LIQUID SOAP/SHAMPOO", 2)]
# Test case 1
player answer: mustard
25
# Test case 2
player answer: mayonnaise
0
The player can continue guessing until they run out of strikes or they guess all the possible answers.
Each correct guess increases the player's score. The player loses a strike if they guess something that has already been guessed before or guess something that isn't in the set of possible answers.
# Test case 1
player answer: cry
player answer: cry some more
player answer: cry a lot
player answer: wake me at 3 am
player score: 39, player strikes left: 0
# Test case 2
player answer: cry
player answer: make mess
player answer: eat my candy
player answer: poo
player answer: fart
player answer: puke on me
player answer: pee
player answer: burp
player answer: nurse
player score: 98, player strikes left: 2
Here are the rules of the game:
First, we will assume that player 1 always gets the right to try to make the first guess.
If player 1 makes a correct first guess, they get control of the round. Otherwise, player 2 gets control of the round.
The player that has control of the round will keep guessing and collecting points until they guess all the possible answers. In this case, the round is over and the points are banked to the controlling player's account.
If the controlling player loses all their strikes before guessing all the answers, the other player gets a chance to steal the controlling player's points for the round.
If the other player makes a correct guess, all the points earned by the controlling player in the current round are banked to the other player's account.
If the other player makes an incorrect guess, all the points earned by the controlling player in the current round are banked to the controlling player's account.
Then the round ends.
When a player steals the points, they do not gain the points of their guess. They only gain the points that the controlling player collected for the current round.
Example Case:
question = "Name something a baby does that would be unacceptable in a roommate."
possible_answers = [("CRY/AT 3 A.M.", 39), ("POO/WET SELF", 28), ("PUKE/ON ME", 9), ("BURP", 8), ("MAKE MESS/TOSS FOOD", 5), ("FART", 4), ("PEE IN MY FACE", 3), ("NURSE/ON MY NIPS", 2)]
# Test case 1 - player 1 controls, gains 84 points, loses all 3 strikes, player 2 gets chance to steal but fails, player 1 wins round
player 1 answer: cry
player 1 answer: poo
player 1 answer: puke
player 1 answer: burp
player 1 answer: cry
player 1 answer: cry
player 1 answer: cry
player 2 answer: cry
player 1 score: 84, player 1 strikes left: 0, player 2 score: 0, player 2 strikes left: 3
# Test case 2 - player 1 controls, gains 84 points, loses all 3 strikes, player 2 gets chance to steal and succeeds, player 2 wins round
Here is what I already did:
question = "Name something a baby does that would be unacceptable in a roommate."
possible_answers = [("CRY/AT 3 A.M.", 39), ("POO/WET SELF", 28), ("PUKE/ON ME", 9), ("BURP", 8), ("MAKE MESS/TOSS FOOD", 5), ("FART", 4), ("PEE IN MY FACE", 3), ("NURSE/ON MY NIPS", 2)]
player_1_strikes_left = 3
player_2_strikes_left = 3
player_1_score = 0
player_2_score = 0
player_score = 0
match = False
player_1_answer = input("1: ")
player_2_answer = "000"
player_1_answer = player_1_answer.upper()
player_2_answer = player_2_answer.upper()
player_1_control = None
if player_1_answer.upper() != "ooooooooooooooooooooooo":
for item in possible_answers:
answer = item[0]
if player_1_answer in answer:
player_1_control = True
player_1_score += item[1]
possible_answers.remove(item)
match = True
break
else:
cplayer_1_control = False
else:
None
#if player_1_control != True
while player_1_score < 0 :
while player_1_control == True:
while player_1_strikes_left != 0 and len(possible_answers) != 0:
player_1_answer = input()
player_1_answer = player_1_answer.upper()
match = False
for item in possible_answers:
answer = item[0]
if player_1_answer in answer:
player_1_score += item[1]
possible_answers.remove(item)
match = True
break
#print(possible_answers)
if not match:
player_1_strikes_left -= 1
if player_1_strikes_left == 0:
player_1_control = False
else:
continue
break
while player_1_control == False :
while player_2_strikes_left != 0 and len(possible_answers) != 0:
player_2_answer = input()
player_2_answer = player_2_answer.upper()
match = False
for item in possible_answers:
answer = item[0]
if player_2_answer in answer:
player_2_score += item[1]
possible_answers.remove(item)
match = True
break
#print(possible_answers)
if not match:
player_2_strikes_left -= 1
if player_2_strikes_left == 0:
player_1_control = True
else:
continue
break
print(f'player 1 score: {player_1_score}, player 1 strikes left: {player_1_strikes_left}, player 2 score: {player_2_score}, player 2 strikes left: {player_2_strikes_left}')
I don't know why but the code runs infinitely and doesn't change the player when the other one runs out of strikes.
Thank you very much beforehand!
Related
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.
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.
I am trying to get some probability by simulating a game (assimilation) using python.
A and B play a game where they take turns to throw a coin (A starts first), and the first one to throw a head wins. But their coins are biased! A's coin has a 1 in 5 chance of coming up heads, and B's coin has a 1 in 3 chance of coming up heads.
The code should simulate it and answer this question: What is the probability of A winning if he goes first?
By solving through mathematically, I came to this solution: 3/7.
This is what I've done so far, but it doesn't give me the expected number.
import numpy as np
def P1_win_prob_weighted_coin_game(num_games, prob_heads=.5):
player_one_wins = 0
for n in range(0,num_games):
num_flips = 0
win = 0
while win == 0:
turn = np.random.uniform(0,1)
num_flips += 1
if turn <= prob_heads:
if num_flips % 2 != 0:
player_one_wins += 1
win += 1
return float(player_one_wins)/float(num_games)
What am I doing wrong?
I think I got it.
First, define a function that plays one game and tells me who the winner was.
def get_winner(prob_to_win=[1/5, 1/3]):
''' Tells who the winner was.
Params:
prob_to_win is a list with the probabilites of each player to win
Returns:
the index of the player who won (based on prob_to_win)
'''
number_of_players = len(prob_to_win)
while True:
for player in range(number_of_players):
coin_flip = np.random.uniform()
if coin_flip <= prob_to_win[player]:
return player
Next, define the names, probabilites and number of games to play (observeations)
player_names = ['A', 'B']
player_probs = [1/5, 1/3]
number_of_games = 500000
Let the games begin! (Note: for more verbosity, you can uncomment the print line)
player_win_count = [0, 0]
for i in range(number_of_games):
winner = get_winner(player_probs)
player_win_count[winner] += 1
# print(f'The winner was {player_names[winner]} ({player_win_count[winner]} wins so far)')
Finally, get and display the results.
for (player, wins) in zip(player_names, player_win_count):
chances = wins/number_of_games
print(f'Statistics (with {number_of_games} observations) tell that player {player} has {chances} chances to win against others')
Outputs:
Statistics (with 500000 observations) tell that player A has 0.427982 chances to win against others
Statistics (with 500000 observations) tell that player B has 0.572018 chances to win against others
Which is very close to the probability that you calculated 3/7.
Hope it helps! This was fun :)
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?
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.