How to alternate between players? - python

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)

Related

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

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.

Blackjack game not updating hands each time everyone draws

I'm trying to make a simple text-based Python game around blackjack. The game knows the variable 'hand' and 'd_hand' which are your hand and the dealer's hand, but won't update it after each new card is drawn. hand and d_hand are assigned to a random integer between 1 and 11 plus your current hand before it added the random number, which in theory should mean that your hand updates itself every time a new card is drawn.
Here's the code:
def draw(hand, d_hand):
x = randint(1, 11)
card = x
hand = x + hand
print("You drew...")
print(card)
y = randint(1, 11)
d_card = y
d_hand = y + d_hand
print("Dealer drew...")
print(d_card)
print("Your hand: ")
print(hand)
print("Dealer's hand: ")
print(d_hand)
ask()
And here's the output of everything:
(Note: I only am showing one function here, the game is obviously more than just this one function I'm showing.)
Press enter to begin:
You drew...
1
Dealer drew...
5
Your hand:
1
Dealer's hand:
5
Hit or stay? (h/s): h
You drew...
10
Dealer drew...
8
Your hand:
10
Dealer's hand:
8
Hit or stay? (h/s): '''
I'm not really sure what the issue is here...
By the way, I'm new to this site so I can't like any comments, so thank you to everyone who answered!
If hand and d_hand are lists (or mutable objets),
you may want to update the object itself by replacing hand = x + hand with hand.append(x).
Otherwise, your code will just create a new local list hand that will be lost when the function ends.
From the code you posted it looks like you aren't returning the new hands. So when the function returns the hands will revert to whatever value they were before the call. You can return tulples in python like return (hand,d_hand) and then do something like hand,d_hand = draw(hand,d_hand)

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.

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

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?

Categories

Resources