Running the Random method 'choices' for an unknown number of iterations - python

Consider the following code
import random
fruits = [0, 0]
for _ in range(1000):
if random.choices(['apple', 'orange'], weights=[0.5, 0.5])[0] == 'apple':
fruits[0] += 1
else:
fruits[1] += 1
Looks pretty standard, predictable "output" in the list fruits. But what if you instead let it run for an unknown period of time, face-offs on top of each other, and certain criterion must be met.
def game():
pts_apple = 0
pts_orange = 0
while True:
if random.choices(['apple', 'orange'], weights=[0.54, 0.46])[0] == 'apple':
pts_apple += 1
else:
pts_orange += 1
if pts_apple >= 5 and pts_apple - pts_orange >= 3: # change for bigger differences
pts_apple = 0
pts_orange = 0
fruits[0] += 1
break
elif pts_orange >= 5 and pts_orange - pts_apple >= 3:
pts_apple = 0
pts_orange = 0
fruits[1] += 1
break
What I've noticed is the disparity is more prominent when the criterion for minimum number of points increases, and the when the difference between them must be greater. So, what is going on? I have though about this for quite som time, but I'm stumped. Why would the probability of a winner change so radically? I can only think of one reason
There is som kind of "stacking" going on. So, you win one, but then you must win another, then yet another and so on, until you meet the criteria. Because 'apple' has greater odds, there is a greater chance for 'apple' to win.
Am I missing something?
Also, how would you go about minimizing the disparity, if you have to use certain numbers? You want to be able to find the probability before you do the computation, but you don't know the number of 'face-offs'! For example, if you stack them, two 'face-offs' has 'apple' at a two-win probability of .54 * .54, right? But what if there are 200 'face-offs' before you find a winner? Do you use a normal distribution?
Cheers!

It looks like the code you've provided simulates a simple game where players can choose to play as either an "apple" or an "orange". In each round of the game, a player wins a point if they choose the fruit that is chosen by the random.choices function. The game continues until one player has scored at least five points and has at least a three-point lead over the other player. When this happens, the winning player's score is added to the fruits list and the game resets.
The key difference between the first code snippet and the game() function is that the first code snippet simply counts how many times an "apple" or an "orange" is chosen by the random.choices function, while the game() function simulates a game where players can win and lose points. This means that the output of the game() function will be different from the output of the first code snippet.
One thing to note is that the game() function has a potential for an infinite loop, because it does not have any conditions for ending the game if it goes on for too long. This could potentially cause problems if the function is allowed to run for a very long time. It might be a good idea to add a maximum number of rounds or a timeout to the game to prevent this from happening.

Related

How to alternate between players?

I have to make a card game in which the starting player changes after each round or mini round (up to me to decide) but I have no clue how to alternate between the 2 players. After reading online, I tried using the cycle function from itertools but that creates further problems...
The problem is that I do not know how to alternate between the 2 players without messing up the rest of the program (displaying the player's hand and the scoring system)
To clarify in advance, the code snippets I am about to provide work perfectly as long as I do not alternate between the starting players.
Code:
print("Player 1, your cards are: ", hands[0])
print("Player 2, your cards are: ", hands[1])
In this case I want the hands index to change accordingly to the Player if i use the cycle function.
if cards.bigger_card(hands[0][play_1 - 1], hands[1][play_2 - 1], trump[0][1]) == 0:
print("Congrats Player 2! You won this mini round.")
score["score_2"] += 1
else:
print("Congrats Player 1! You won this mini round.")
score["score_1"] += 1
Here the score should update according to the Player that won the round.
I'm not sure if I've understood your question well enough. But I'll try.
To simply alternate between two index i.e. 0, 1, you can add a variable to store current turn and alternating it like this:
currentTurn = 0
def switchTurn():
return (currentTurn + 1) % 2
Usage:
print(currentTurn)
# output: 0
switchTurn()
print(currentTurn)
# output: 1
print(hands[currentTurn])
# output player 2nd's hands (or cards)

Confused over a python concept as a beginner who has only started learning cs. Any help would be really appreciated

I've been stuck with something which has really halted my learning process as someone who has just started learning cs
Suppose I get an output score every turn in an iteration and the score for every turn is a random number ranging from 1 to 15
Now for every turn I want to print whether the score jump in that respective term is the biggest score jump in ALL of the turns played yet. It won't print anything if it isn't the biggest jump in score yet
I just can't seem to wrap my head around executing something like this and it has put everything I have to learn after it to a halt
#This is the function where I try to define the highest point for the score in this function-
def highest_gain(previous_value, highest_point) :
def say(score0) :
if previous_value == 0:
print ('Biggest gain by player0 yet with',score0,'points!')
return highest_gain(score0, score0)
gain = score0 - previous_value
if gain > highest_point:
print('Biggest gain by player0 yet with',score0,'points!')
return highest_gain(score0, gain)
return say
#This is the function for updating the score every turn and then call it with below-
while n > 0:
score += random.randint(1, 15)
f = say(score)
n -= 1
return score
score0(6,0,highest_gain(0,0))
Any help on this would be really appreciated🙏 . This has been bugging me for a few days now. I just can't seem to understand why the values inside of highest_gain can't remain updated after every turn they are executed.
This does what you ask, but I suspect what you need is not what you asked for.
import random
highest = 0
def score0(n):
global highest
score = 0
for i in range(n):
bump = random.randint(1, 15)
if bump > highest:
highest = bump
print('Biggest gain by player0 yet with',bump,'points!')
score += bump
return score
score0(6)

Probability Assimilation using python

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 :)

How to fix runtime error in Tic Tac Toe check win function

I'm writing a Tic-Tac-Toe game in python 2 for my CompSci class using SimpleGUI. I have a 2D array set so that whenever a player clicks within a certain area on the canvas, it will draw an X or an O in that area and will also write one of the array elements to be set to that letter. That works fine. I've defined a function to check each row of the array to check if the player has won, and it looks something like this:
def checkRows():
if len(set(grid[0])) == 1:
winner = grid[0][0]
if len(set(grid[1])) == 1:
winner = grid[1][0]
if len(set(grid[2])) == 1:
winner = grid[2][0]
Additionally, I have a counter that increments by one every time a square is filled and a while loop at the end that runs the checkRows function while the counter is less than 9 (because 9 is the maximum number of squares that need to be filled for one player to win). That looks something like this:
while counter < 9:
checkRows()
if winner == "X":
frame.add_label("X wins!", 100)
elif winner == "O":
frame.add_label("O Wins!", 100)
Every time I run the code it throws a runtime error, saying "TimeLimitError: Program exceeded run time limit.", sometimes on the first, sometimes on the second line of the function. Does anyone know what could be the cause of this?

modified coin toss program won't run

So I have to complete an assignment in which a coin toss is simulated and the number of flips, tails, and heads must be counted.
My first problem was that I could not get the number of heads or tails to display, fixed that, but then it was doubling(ex: I request 50 flips and the total amount of heads and tails would equate to 100), figured out that I had accidentally made it so it was counting up twice instead of once per flip, when I changed that the program just doesn't seem to run.
When I input the amount of times I would like the coin to flip and hit enter it just does nothing and goes to the next line on my terminal. I have removed all white space off my program in case of infinite looping other than that I cannot figure out what is causing this.
Thank you for any help.
You need to remove below line, otherwise it will keep on looping
count +=1
Because, at the same time you are incrementing head or tail as well.
Assuming, you provided input 1 then, it will check
head+tail < count # 0 < 1 , which is true
then assuming coin=1 then,
count+=1
head= head+1
For the next loop
head+tail < count # 1 < 2 , which is true
The issue is that you increment your count variable, alongside your head and tails counts. So you are in a while loop aiming for a moving target. I am not attempting to compete with Ravi for the accepted answer, but here is a simplified version of your code.
You needn't use a while loop, as you know how many iterations you will do. In this case a for loop is the appropriate tool.
from random import choice
heads = tails = 0
count = int(input('how many flips? '))
for _ in range(count):
if choice([True, False]):
heads += 1
else:
tails += 1
print('you flipped %d times' % count)
print('you flipped %d heads and %d tails' % (heads, tails))

Categories

Resources