I'm writing code for a rock paper scissors game, it has a random number generator between 1-3 which simulates the computer's throw, and it works totally fine. What I'm trying to do is add a score counting system, for 3 different scores:
userWins
compWins
gamesPlayed
I also have a loop which allows you to play mulitple games.
but I can't find a way for the scores to update while playing.
Any help would be greatly appreciated,
You could define a global variable:
gamesPlayed = 0
userWins = 0
compWins = 0
def playOneRound():
global gamesPlayed
global userWins
global compWins
compThrow = getCompThrow()
userThrow = getUserThrow()
result = compareThrows(userThrow, compThrow)
if result == "Win":
print("Winner Winner Chicken Dinner")
print("-------------------------------------------------")
userWins += 1
elif result == "Lose":
print("Loser Loser Chicken Loser ")
print("-------------------------------------------------")
compWins += 1
else:
print("Tie")
print("-------------------------------------------------")
gamesPlayed += 1
Second, maybe better approach:
class Scores:
def __init__(self):
self.gamesPlayed = 0
self.userWins = 0
self.compWins = 0
scores = Scores()
def playOneRound():
compThrow = getCompThrow()
userThrow = getUserThrow()
result = compareThrows(userThrow, compThrow)
if result == "Win":
print("Winner Winner Chicken Dinner")
print("-------------------------------------------------")
scores.userWins += 1
elif result == "Lose":
print("Loser Loser Chicken Loser ")
print("-------------------------------------------------")
scores.compWins += 1
else:
print("Tie")
print("-------------------------------------------------")
scores.gamesPlayed += 1
Related
I wrote a Rock, Paper and Scissor game in Python. And I want to have a function that scores the game. The only way I managed to do that was by using global variables inside the function. I know that's not a good practice and I'd like to know how can I make this function without the need for global variables.
import random
def validate_user_input(input):
"""Verify if user input is a valid."""
try:
usr_input = int(input)
except:
return 0
else:
if (usr_input >= 1) and (usr_input <= 3):
return usr_input
else:
return 0
def compare_results(player_choice):
"""Get computer choice and compare it with user choice"""
computer_option = random.randint(1,3)
result_to_word = {0:'- Draw', 1:'- You loose.', 2:'- You Win'}
if player_choice == computer_option:
result = 0
if (player_choice == 1 and computer_option == 2):
result = 1
if (player_choice == 1 and computer_option == 3):
result = 2
if (player_choice == 2 and computer_option == 1):
result = 2
if (player_choice == 2 and computer_option == 3):
result = 1
if (player_choice == 3 and computer_option == 1):
result = 1
if (player_choice == 3 and computer_option == 2):
result = 2
return (result, result_to_word[result], computer_option)
def codify_result(input):
"Transform number of choice into word"
num_to_word = {1: "Rock", 2: "Paper", 3:"Scissor"}
return num_to_word[input]
def make_score(result):
global computer_score
global player_score
if result == 1:
computer_score += 1
elif result == 2:
player_score += 1
player_score = 0
computer_score = 0
intro = "\nHello!\nLet's play 'Rock, Paper and Scissors'.\nChoose an option and wait to see the result (Press 'q' at any time to exit)"
print(intro)
while True:
user_input = input("\n1) Rock, 2) Paper os 3) Scissors?: ")
if (user_input == 'q'):
break
else:
user_choice = validate_user_input(user_input)
if user_choice == 0:
print("You have to choose a number between 1 and 3.")
else:
result = compare_results(user_choice)
print("You chose: " + codify_result(user_choice) + ".")
print("The computer chose: " + codify_result(result[2]) + '.')
print(result[1])
make_score(result[0])
print("You: " + str(player_score) + "\nComputer: " + str(computer_score))
So how could I implement this function in a better way?
A "pure functional" approach could be to change your make_score function to take the old scores as arguments, and then return the updated scores:
def make_score(result, computer_score, player_score):
if result == 1:
computer_score += 1
elif result == 2:
player_score += 1
return computer_score, player_score
When you call make_score you pass the old scores and assign the new scores:
computer_score, player_score = make_score(result[0], computer_score, player_score)
Taking a step back, though, I might suggest taking an approach that doesn't require you to have a function that translates an opaque result int value into a modification to one or another variable. Maybe put the scores in a dict:
scores = {
"computer": 0,
"player": 0,
}
and then instead of a magic result int, assign a winner that matches one of the dict keys:
if (player_choice == 1 and computer_option == 2):
winner = "computer"
and then you can get rid of the make_score function completely and just do:
scores[winner] += 1
I would recommend making a dictionary which you can then pass into make_score
score_dict = {'computer_score': 0, 'player_score': 0}
make_score(score_dict, result):
if result == 1:
score_dict['computer_score'] += 1
...
I want to make a card game simulation called 'Game of War" in Python, which can input the number of times that we want to play, for example, 3 times, the output should be like this Enter in the number of simulations for War Game: 10 Sim 1 Player 1 is the winner Sim 2 Player 1 is the winner Sim 3 The game was a draw FINAL RESULT: Player 1 won 2 times Player 2 won 0 times There were 1 draw
For now, I'm having a problems with create a function sim_num_games(sim_num) that asks the user for how many simulations they would like to run. The function must return the results for player 1, player 2 and the number of times a game was a tie. Then its must display how many times Player 1 wins, how many times Player 2 wins, and how many times the game was a tie. This is what I got so far.
deck = []
suits = ["Clubs", "Diamonds", "Hearts", "Spades"]
def create_deck():
for suit in suits:
for rank in range(2,15):
deck.append((rank,suit))
return deck
def deal_cards(the_deck):
if the_deck[0] <= 10: rank = str(the_deck[0])
if the_deck[0] == 11: rank = "Jack"
if the_deck[0] == 12: rank = "Queen"
if the_deck[0] == 13: rank = "King"
if the_deck[0] == 14: rank = "Ace"
fullname = rank + " of " + the_deck[1]
return fullname
def draw_card(player):
the_deck = deck[0]
deck.remove(deck[0])
print(player + 'has: ' + deal_cards(the_deck))
return the_deck
def play_game(p1_cards,p2_cards):
if p1_cards[0] > p2_cards[0]:
return "Player one"
if p1_cards[0] < p2_cards[0]:
return "Player two"
else:
return "DRAW!!!!!!!!"
def main():
deck = create_deck()
random.shuffle(deck)
round_play = 1
p1_score = 0
p2_score = 0
draw = 0
print("ALRIGHT, Let's Play...")
while len(deck) >= 2:
print("Hand number: ", round_play)
player_one_card = draw_card("Player 1 ")
player_two_card = draw_card("Player 2 ")
winner = play_game(player_one_card, player_two_card)
round_play += 1
if winner == "Player one": p1_score += 1
if winner == "Player two": p2_score += 1
if winner == "DRAW!!!!!!!!": draw += 1
print(f"{winner} wins")
else:
print("-"*15)
print("FINAL GAME RESULTS:","\nPlayer 1 won ", p1_score," hands" ,"\nPlayer 2 won ", p2_score," hands","\n",draw," hands were draw")
main()```
This can generate the deck and play but I cannot put the sim_num_games(sim_num) function in since it always error..
I would do something like this as your main structure.
p1_score = 0
p2_score = 0
draw = 0
ngames = int(input("How many games you want to simulate?"))
for _ in range(ngames):
winner = play_game()
if winner == 1:
p1_score += 1
elif winner == 2:
p2_score += 1
else:
draw += 1
if p1_score > p2_score:
print(f"Player 1 wins {p1_score} of {ngames} games")
elif p1_score < p2_score:
print(f"Player 2 wins {p2_score} of {ngames} games")
else:
print("draw")
Now, you have to put all the logic that initializes a game, plays it and determines a winner inside a function play_game(), which will return either 0, 1 or 2
Ideally you should create a class to have things better organized, but having functions hanging around will also work since it's a small project.
You can also make helper functions, so your main structure keeps as clean as possible. For example you can create a function update_scores() and a function determine_winner() that will take code out of the main structure and make it cleaner.
I'm really new to Python and one of the things I'm struggling with is getting my code to run properly, I want it to print the current score every round but I'm having an issue adding the score into the string (Ideally not inline but if I have to I can do).
If anyone has any ideas, even if it's not specifically about the problem but instead just making the code overall more efficient, any help would be appreciated.
from random import randint
play = 1
while play == 1:
# Get user input & choose value
player, opponentInt = input("Rock, Paper, or Scissors? (r/p/s)\n"), randint(1,3)
player = player.lower()
# Assigning player input to int value
playerInt = []
if player == 'r':
playerStr, playerInt = 'Rock', 1
elif player == 'p':
playerStr, playerInt = 'Paper', 2
elif player == 's':
playerStr, playerInt = 'Scissors', 3
# Assigning randint function input to str value
if opponentInt == 1:
opponentStr = 'Rock'
elif opponentInt == 2:
opponentStr = 'Paper'
elif opponentInt == 3:
opponentStr = 'Scissors'
# Define strings
def winStr():
print("You chose {}, and I chose {}. Congratulations! You won! (Score = {})".format(player, opponentStr, score))
def loseStr():
print("You chose {}, and I chose {}. Unfortunately, you lost. (Score = {})".format(player, opponentStr, score))
def drawStr():
print("You chose {}, and I chose {}. It was a draw. (Score = {})".format(player, opponentStr, score))
# Give result of game
score = 0
if playerInt == []:
print('Unexpected value, please play again and check spellings.')
elif playerInt == 1 and opponentInt == 3:
score = score + 1
winStr()
elif playerInt == 3 and opponentInt == 1:
score = score - 1
loseStr()
elif playerInt > opponentInt:
score = score + 1
winStr()
elif playerInt < opponentInt:
score = score - 1
loseStr()
elif playerInt == opponentInt:
drawStr()
# Ask user if they would wish to play again
play = 2
while play == 2:
playAgain = input("Would you like to play again? (y/n) ")
playAgain = playAgain.lower()
if playAgain == 'y':
play = 1
elif playAgain == 'n':
play = 0
else:
play = 2
print("Unexpected value...")
# Print score
print("Your score was {}.".format(score))
Thanks for any help.
I have tried making strings using:
str = "String here. Score = {}".format(score)
Along with my latest:
def str():
print("String here. Score = {}".format(score))
str()
You should pass these variables as arguments to your functions
def print_str(score):
print("String here. Score = {}".format(score))
print_str(5)
As an aside you could use f-strings instead of str.format
def print_str(score):
print(f'String here. Score = {score}')
I have now fixed it and thank you to #CodyKramer for the tip in assigning formatting a string. Turned out I had an issue where the loop was resetting the variable I found after the string was actually printing the score change.
play = 1
while play == 1:
...
score = 0
if ...
score += 1
print(score)
...
Where in fact it should have been:
play = 1
score = 0
while play == 1:
...
if ...
score += 1
print(score)
...
I am trying to write a program to play 100 games of Craps and print out the overall results. I have an infinite loop at the end of my code.
Does anyone see the problem?
I assume my 2nd function could be calling diceRoll again for secondRoll. Trying that now...
Specs:
The player must roll two six-side dice and add the total of both
dice.
The player will win on the first roll if they get a total of 7 or 11
The player will lose on the first roll if they get a total of 2, 3,
or 12
If they get any other result (4, 5, 6, 8, 9, 10), they must roll
again until they either match their first roll (a win) or get a
result of 7 (a loss)
Use at least two functions in your program
from random import randrange as rd
winTuple = 7, 11
lossTuple = 2, 3, 12
wins = 0
losses = 0
x = 1
def diceRoll (number, type = 6):
result = 0
for i in range(number):
result += rd(1, type +1)
return result
while x < 101:
firstRoll = diceRoll(2)
if firstRoll in winTuple:
wins += 1
elif firstRoll in lossTuple:
losses += 1
else:
secondRoll = diceRoll(2)
while secondRoll != 7 or secondRoll != firstRoll:
if secondRoll == 7:
wins += 1
elif secondRoll == firstRoll:
wins += 1
else:
secondRoll = diceRoll(2)
x += 1
print("wins: ", wins)
print("losses: ", losses)
Looks like you need to eliminate your inner loop. First, the loop conditions are in direct conflict with your conditional statements, so the loop never exits. Second, why would you want a loop here? Even if you fixed it, all it would do is keep rolling the second dice until a win is scored.
while x < 101:
firstRoll = diceRoll(2)
if firstRoll in winTuple:
wins += 1
elif firstRoll in lossTuple:
losses += 1
else:
secondRoll = diceRoll(2)
if secondRoll == 7 or secondRoll == firstRoll:
wins += 1
x += 1
In response to your comment, this is how you create your second loop. You make an infinite loop with while True and break out of it when the conditions are met.
while x < 101:
firstRoll = diceRoll(2)
if firstRoll in winTuple:
wins += 1
elif firstRoll in lossTuple:
losses += 1
else:
while True:
secondRoll = diceRoll(2)
if secondRoll == 7:
losses += 1
break
elif secondRoll == firstRoll:
wins += 1
break
x += 1
If your firstRoll != 7 (let's say firstRoll = 8) then your script cannot exit the second nested loop because either secondRoll != 7 or secondRoll = 7 and therefore firstRoll != secondRoll (7 != 8)
I am not sure how your program goes through 100 games of craps, here is an example of a program I wrote quick that goes through 100 games. Games being times you either hit or don't hit the point.
Clearly you need to understand how craps works to make something like this, so I am assuming you do. The program you were trying to write, even though you were stuck in the loop, was not actually playing a full game of craps.
You can choose the amount of games you want and the only thing it stores is if you won or lost.
You can add other statistics if you would like, for example points hit and which points they were etc.,
I added text to, also, make it user friendly if this is for a school project.
There are many different ways to do this, I used a main while loop and created two functions for whether the button is on or off.
You could obviously condense this, or write a class instead but I simply put this together quick to give you an idea and see how it goes through every loop and statement.
I am still a novice, so I apologize to anyone else reading, I know the below is not the most efficient/does not perfectly follow PEP8 especially the long if statement in the main loop.
This does perform what you wanted and feel free to change the number of games. Enjoy!
import random
wins = 0
losses = 0
gamenum = 0
#Used a list to pull the dice numbers from but not mandatory
dicenum = [2,3,4,5,6,7,8,9,10,11,12]
#Function when point is off
def roll_off():
#Random roll from list
roll = random.choice(dicenum)
if roll == 2:
print("2 craps")
elif roll == 3:
print("3 craps")
elif roll == 4:
print("Point is 4")
return(4)
elif roll == 5:
print("Point is 5")
return(5)
elif roll == 6:
print("Point is 6")
return(6)
elif roll == 7:
print("Winner 7")
elif roll == 8:
print("Point is 8")
return(8)
elif roll == 9:
print("Point is 9")
return(9)
elif roll == 10:
print("Point is 10")
return(10)
elif roll == 11:
print("Yo 11")
elif roll == 12:
print("12 craps")
#Function when point is on
def roll_on(x):
#Random roll from list
roll = random.choice(dicenum)
if roll == 2:
print("2 craps")
elif roll == 3:
print("3 craps")
elif roll == 4:
print("You rolled a 4")
elif roll == 5:
print("You rolled a 5")
elif roll == 6:
print("You rolled a 6")
elif roll == 7:
print("7 out")
elif roll == 8:
print("You rolled a 8")
elif roll == 9:
print("You rolled a 9")
elif roll == 10:
print("You rolled a 10")
elif roll == 11:
print("Yo 11")
elif roll == 12:
print("12 craps")
#Check if you hit the point
if x == 4 and roll == 4:
print("You win!")
return (True)
elif x == 5 and roll == 5:
print("You win!")
return (True)
elif x == 6 and roll == 6:
print("You win!")
return (True)
elif x == 7 and roll == 7:
print("You win!")
return (True)
elif x == 8 and roll == 8:
print("You win!")
return (True)
elif x == 9 and roll == 9:
print("You win!")
return (True)
elif x == 10 and roll == 10:
print("You win!")
return (True)
#Check if you 7'ed out
if roll == 7:
print("You lose!")
return (False)
#Main game, change the amount of games you want to play
while gamenum < 100:
diceresult = roll_off()
#If statement to check the point
if diceresult == 4 or diceresult == 5 or diceresult == 6 or diceresult == 8 or diceresult == 9 or diceresult == 10:
active = True
print("The point is on!")
while active == True:
curentstate = roll_on(diceresult)
if curentstate == False:
gamenum += 1
losses += 1
print("------------")
print("Games:", gamenum)
print("Losses:", losses)
print("Wins:", wins)
print("------------")
break
elif curentstate == True:
gamenum += 1
wins += 1
print("------------")
print("Games:", gamenum)
print("Losses:", losses)
print("Wins:", wins)
print("------------")
break
Python 3.5
I have a project for a class to create a Roulette wheel minigame and I'm having issues. I set the initial cash to $100 and let the user play roulette. After they've given their wager and it's time to tally up the cash for the next round, I'm having issues setting the new cash value. Basically, I need to add the winnings/losings to the value of cash so that it's accurately updated for the next round. I know that declaring cash as a global variable is wrong, but we haven't learned the proper way to do it and haven't had time to check it out for myself. Anyways, the issue is near the bottom. Thank you for any help! -
import math
import random
def main():
global cash
print('Welcome to Roulette! We\'ll start you with $100')
cash = 100 #set to 100 for intitial
menu()
def menu():
print('Place your bet! ',cash,'bucks!', '''
=======================================
1. Bet on Red (pays 1:1)
2. Bet on Black (pays 1:1)
3. First 12 (pays 2:1)
4. Middle 12 (pays 2:1)
5. Last 12 (pays 2:1)
6. Choose any number (pays 35:1)
7. Cash out
Please enter your choice: ''')
menuChoice = int(input())
#Add validation!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if cash > 0 and menuChoice != 7: #Determine if quit or broke
if menuChoice == 6:
number = int(input('Please choose a number from 0-36!')) #Get their specific number
while number < 0 or number > 36: #Validation
number = int(input('Please enter a number from 0-36'))
wager = int(input('How much would you like to bet? '))
#Add validation!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
print('Press any key to spin the wheel! ')
input()
print(menuChoice, wager)
##
## ball = random.randint(0,36)
ball = 19 #set to 19 for testing. REMOVE AND RESET BALL!!!!!!!!!!!!!!!!!
if ball == 0:
color = ('green')
elif ball % 2 == 0:
color = ('black')
else:
color = ('red')
print('Your ball was',ball, 'and landed on the color',color)
#Determine if winner
if menuChoice == 1 and color == 'red':
winner = True
odds = 1
elif menuChoice == 2 and color == 'black':
winner = True
odds = 2
elif menuChoice == 3 and ball >= 1 and ball <= 12 :
winner = True
odds = 2
elif menuChoice == 4 and ball >= 13 and ball <= 24:
winner = True
odds = 2
elif menuChoice == 5 and ball >= 25 and ball <= 36:
winner = True
odds = 2
elif menuChoice == 6 and ball == number:
winner = True
odds = 35
else:
winner = False
odds = 0
#End determine if winner
if odds == 0:
pass
else:
amount = wager * odds #Get amount won/lost
print(amount)
if winner == True:
cash += amount #<~~~~~~~~~~~~~Problem Area
print('Congratulations! You won', wager,'dollars!')
print('Your total is now :',cash,'dollars.')
else:
cash -= wager
print('Sorry! You lost',wager,'dollars. Better luck next time!')
print('Your total is now :',cash,'dollars.')
input('Press a key to go back to the menu!')
print('====================================================================')
#New round
menu()
else:
print('Thank you for playing! ')
exit
main()
You could create your own python class, with the methods you already have. Than you can declare cash a class variable, with the parameter self. With self.cash you can than access the variable in every method. If that does not help please comment this answer with your issue.