"Variable ___ referenced before assignment." - python

I've been having a bit of difficulty with my Python programme. It plays Rock Paper Scissors. The code is pretty large so I'll shorten it to a sample programme, but the full code can be viewed at https://github.com/Ph0enix0/doitall/blob/master/computerpungramming/rockpaperscissors.py
(count is the amount of games played)
count = 0
user_wins = 0
comp_wins = 0
def game():
comp_answer = ['rock', 'paper', 'scissors']
user_answer = input('Rock, paper, or scissors?')
if user_answer = 'rock':
count += 1
if comp_answer = 'paper':
print('Paper! I win!)
comp_wins += 1
#The rest of the comparisons are here
while 1 == 1:
game()
If I put the variables in game() they will reset every time. Help?

You need to move the variables inside the function and define scissors_wins:
def game():
'''
The actual game code. The code randomly chooses
rock, paper, or scissors. Then, it checks if the user's choice
beats the computer's. If it does, the user wins, and vice versa.
'''
#User picks rock, paper, or scissors.
user_answer = input('Rock, paper, or scissors? ')
#Tell the code that the game is not finished. Used for while loops.
game_finished = False
count = 0
user_wins = 0
comp_wins = 0
scissors_wins = 0
Your game already has a loop so unless you are doing something in your while 1 == 1 then simply call game()
And yes every time you call the function the variables will be reset to 0.
If you want the win count to persist through many runs use a dict declaring outside the function:
d = {"user":0,"comp":0,"scissor":0}
Then update at the end of each game:
d["user"] += user_wins
Or increase the count of each inside the function instead of using the variables.
You also don't seem to ever break the loop so your code will loop infinitely. I imagine you want to also ask the user more than once for input so move user_answer = input('Rock, paper, or scissors? ') inside the loop.
Something like the following:
d = {"user":0,"comp":0,"scissor":0}
d = {"user":0,"comp":0,"scissor":0}
def game():
'''
The actual game code. The code randomly chooses
rock, paper, or scissors. Then, it checks if the user's choice
beats the computer's. If it does, the user wins, and vice versa.
'''
#Tell the code that the game is not finished. Used for while loops.
game_finished = False
count = 0
user_wins = 0
comp_wins = 0
scissors_wins = 0
#Game isn't finished, so the code continues.
while not game_finished:
user_answer = input('Rock, paper, or scissors? ')
# update dict with totals when loop breaks

The game function can't change the variables outside it (count, user_wins, comp_wins). Have the function return the necessary values.
count = 0
user_wins = 0
comp_wins = 0
def game():
...
return count, user_wins, comp_wins
count, user_wins, comp_wins = game()

You're going to want to change
if comp_answer = 'paper':
to
if comp_answer == 'paper':
That's probably what's throwing the error. Change the = to == in any other places where you're checking an if condition.

Related

Returning Value from Function to Variable

So I'm currently having some trouble with working out how to basically create a "count" function work within my Rock, Paper, Scissors game. I'm new to Python and this is my first foray into the use of multiple functions to execute game logic. Here's my code...
import random
from random import choice
cpu_score = 0
player_score = 0
# dictionary from which gestures are pulled
gestures = ["rock","paper","scissors"]
n_rounds = int(input("How many rounds would you like to play? "))
while n_rounds % 2 == 0 or n_rounds <= -1:
print("Number of rounds must be an odd number! Select an odd number!")
n_rounds = input("How many rounds?")
break
print("Lets play",n_rounds,"rounds!")
rounds_to_win = ((n_rounds + 1)//2)
rounds_to_win = round(rounds_to_win)
print("You must win",rounds_to_win,"rounds to beat the game!")
def computer_choice():
"""Movement made by the computer"""
comp = random.choice(gestures)
return comp
def player_gesture():
"""Movement by player"""
player = input("Please select, rock, paper or scissors")
if player not in gestures:
print("That's not an option! Please try again.")
player = input("Please select, rock, paper or scissors")
return player
def who_won_round(comp, player):
'''Who is the winner of the round.'''
winner = 0
if ((player == "rock") and (comp == "paper")) or \
((player == "paper") and (comp == "scissors")) or \
((player == "scissors") and (comp == "rock")):
winner = 1
elif ((comp == "rock") and (player == "paper")) or \
((comp == "paper") and (player == "scissors")) or \
((comp == "scissors") and (player == "rock")):
winner = 2
else:
winner = 0
return winner
def win_counter(winner, cpu_score,player_score):
rounds = 1
if winner == 1:
player_score += 1
print("This is round",rounds)
rounds += 1
return player_score
if winner == 2:
cpu_score += 1
print("This is round",rounds)
rounds += 1
return cpu_score
def count_round(winner, player, comp, cpu_score, player_score):
if winner == 0:
print("It's a tie!")
elif winner == 1:
print("The player chose",player)
print("The computer chose",comp)
print("The computer won the round!")
print("The computer has won",cpu_score,"rounds!")
elif winner == 2:
print("The player chose",player)
print("The computer chose",comp)
print("The player won the round!")
print("The player has won",player_score,"rounds!")
def game_structure():
while rounds_to_win < n_rounds:
comp = computer_choice()
player = player_gesture()
winner = who_won_round(comp,player)
win_count = win_counter(winner, cpu_score,player_score)
count = count_round(winner, player, comp, cpu_score, player_score)
game_structure()
Basically I'm having issues returning the variables in order to keep count of the scores of the "number of rounds" and "cpu_score" and "player_score". I prefer to not declare global variables as I realise they can be messy to use, but I'm not quite sure how to avoid this.
If you must avoid the use of global variables, you should take an object oriented approach. That way you can store the variables in the object.
So basically you do something like this:
newgame = mytictactoe()
while True #infinite loop
input("wanna play?")
if input == yes:
newgame.start
else:
break
From what I see, the cpu_score and player_score are never updated. You only have the newest result in win_count, that is not assigned to cpu_score or player_score at anytime. It could be something like:
win_count = win_counter(winner, cpu_score,player_score)
if winner == 1:
cpu_score = win_count
if winner == 2:
player_score = win_count
rounds_to_win = max(player_score, cpu_score)
count_round(winner, player, comp, cpu_score, player_score)
I did not run it, but this modifications should do the trick. There are better ways of doing it; maybe using a list to keep the scores and use winner as the index, or an object approach as someone else said, but I do not want to change too much the code.
Also, bear in mind that the round variable in win_counter does nothing.

Reducing a 'player' count using an if statement

I'm trying to write a script for a game where the user has to guess a computer generated value. The aim is for the player number to be reduced until it has a value of 1 at which point it ends.
import random
import time
players = input("Let's play Five's! How many are you?:" )
#print("you are", players, "players?") #test number of players
players = int(players)
if players <=1:
print("Game Over")
else:
while players >= 1:
players = players+1
#Decide possible values than can be chosen
options = [] #Possible options
for i in range(0,players):
x = i * 5
options.append(x)
print("Your choices are", options)
#Playing the game
#Each turn
guess = random.choice(options)
print("Computer has chosen", int(guess))
count_down = 3
while (count_down):
print(count_down)
time.sleep(1)
count_down -= 1
choice = input("Guess:")
choice = int(choice)
if choice not in options: #If choice isn't a multiple of 5
input("Not allowed, choose again:")
elif choice in options and choice != guess: #Valid choice but wrong
print("Wrong") #so player is still in the
else: #game
choice = int(choice)
if choice == guess: #Correct choice so player leaves game
print("You're Out.") # this should reduce the player count
players -=1
I've included the line printing the computer generated value so I can give the correct guess but even if guess correctly it doesn't reduce the player count and so the game continues infinitely
You add a player on the first line of the while loop.
players = players+1
Then you subtract a player on the last line
players -=1
If I understand your code correctly, the number of players won't change.

Rock Paper Scissors score keeps resetting

I'm making a rock, paper, scissors game with a pointing system and it seems to always give me a value of zero every time the scores are revealed. Help is appreciated.-------------------------------------------------------------------------------------------------------------------------------------------------------------
def play():
player = input("Which will you choose? Rock, Paper or Scissors? Type 'E' to exit ")
elements = ['rock', 'paper', 'scissors']
cpu = random.choice(elements)
scoreplayer = 0
scorecpu = 0
if player.lower() == cpu:
print("This is a tie, no one scores a point")
play()
elif player.lower() == "rock":
if cpu == "paper":
print("Paper beats Rock, CPU gains 1 point")
scorecpu = scorecpu + 1
play()
elif cpu == "scissors":
print("Rock beats Scissors, you gain 1 point")
scoreplayer = scoreplayer + 1
play()
elif player.lower() == "paper":
if cpu == "scissors":
print("Scissors beats Paper, CPU gains 1 point")
scorecpu = scorecpu + 1
play()
elif cpu == "rock":
print("Paper Beats Rock, you gain 1 point")
scoreplayer = scoreplayer + 1
play()
elif player == "scissors":
if cpu == "rock":
print("Rock beats Scissors, CPU gains 1 point")
scorecpu = scorecpu + 1
play()
elif cpu == "paper":
print("Scissors beats Paper, you gain 1 point")
scoreplayer = scoreplayer + 1
play()
elif player.lower() == "e":
print("")
print("You have " + str(scoreplayer) + " points")
print("")
print("CPU has " + str(scorecpu) + " points")
sys.exit()
else:
play()
scoreplayer = 0 and the other assignment are running every time play is called, which creates new variables with values of 0 each time. Pass the current scores as arguments to play instead:
def play(scoreplayer, scorecpu):
# Get rid of these lines
# scoreplayer = 0
# scorecpu = 0
. . .
# Update the scores here
else:
play(scoreplayer, scorecpu)
play(0, 0) # Start with scores of 0
Or switch to using a loop construct like while from recursion and update the scores within the loop. In a language like Python, recursion isn't really suitable here anyways.
because you're setting your variables in your function it will by definition be reset each time it runs. like #Carcigenicate said you could pass them as arguments to it or
use a while loop but you might also want to look into the global statement.
As already mentioned, you're resetting the score every time you call the play() function.
A solution to your problem is to make your score variable a global variable
scoreplayer = 0
scorecpu = 0
def play():
player = input("Which will you choose? Rock, Paper or Scissors? Type 'E' to exit ")
elements = ['rock', 'paper', 'scissors']
cpu = random.choice(elements)
global scoreplayer
global scorecpu
# rest of your code
play()
When defining variables outside of functions we can access them by using the global keyword
You can read more about the global keyword here: https://www.programiz.com/python-programming/global-keyword

Python 3 Rock Paper Scissors with user input being stored to make it more challenging

I am working on Rock, Paper, Scissors in Python 3. I need help trying to implement where the computer keeps track of the users choices so it can tell what the player favors and have an advantage over the player. I also have the computer choosing random using an integer but I need to make the players choice a lowercase 'r' 'p' 's' and a 'q' to quit so it can check for invalid entry and display message and ask again. I don't want to use integers for the player.
Here is what I have:
import os
import random
import time
#global variable
#0 is a placeholder and will not be used
choices = [0, 'rock', 'paper', 'scissors']
player_wins = 0
computer_wins = 0
tie_count = 0
round_number = 1
keep_playing = True
# sets cls() to clear screen
def cls():
os.system('cls' if os.name == 'nt' else 'clear')
# function to display stats
def stats():
print("Current Statistics:")
print("Player Wins: {}".format(player_wins))
print("Computer Wins: {}".format(computer_wins))
print("Tied Games: {}\n".format(tie_count))
# function to check outcome
def game_outcome(player, computer):
#this makes the variables global, else you'll get error
global player_wins, tie_count, computer_wins
if computer == player:
print("It's a tie!\n\n")
tie_count += 1 # incraments tie
# checks all possible win conditions for player. and if met, declares player a winner. If not, declares compute the winner.
elif (player == "rock" and computer == "scissors") or (player == "paper" and computer == "rock") or (player == "scissors" and computer == "paper"):
print("Player wins\n\n")
player_wins += 1 # incraments player's wins
else:
print("Computer wins!\n\n")
computer_wins += 1 # incraments computer's wins
# clears screen
cls()
print("Let's play Rock Paper Scissors!")
# 3-second time out before clearing and asking for input
time.sleep(3)
while keep_playing == True:
# make computer choice random from defined list. Only selects a range of 1-3 ignoring the "0" placeholder
# this is because the user selects a number, instead of typing the weapon, and that number pulls the weapon from the list
computer = random.choice(choices[1:4])
cls()
# prints starting of round and shows stats
print("+++++++++++++[Starting Round {}]+++++++++++++\n".format(round_number))
stats()
# ask for player input
player = input("What is your choice?\n(1) Rock\n(2) Paper\n(3) Scissors?\n\nEnter the number before the weapon of choice:")
player = choices[int(player)]
cls()
print("\n\nThe player's choice: [{}]\n".format(player))
print("The computer's choice: [{}]\n\n".format(computer))
game_outcome(player, computer)
round_number += 1
# ask if player wants to play again. If not, stop
play_again = input('Would you like to play again [y/n]? ')
if play_again.lower() == 'n':
break
print("Thanks for playing!")
Try using a dictionary:
# put this with the imports at the top
import sys
# replace `choices` at the top
choices = {'r': 'rock', 'p': 'paper', 's': 'scissors', 'q': 'quit'}
# get computer choice
# replaces `computer = random.choice(choices[1:4])`
computer = random.choice(['rock', 'paper', 'scissors'])
# ask for player input
# replace these two lines of code:
# player = input("What is your choice?\n(1) Rock\n(2) Paper\n(3) Scissors?\n\nEnter the number before the weapon of choice:")
# player = choices[int(player)]
while True:
try:
player = choices[input("What is your choice?\n(r) Rock\n(p) Paper\n(s) Scissors?\n(q) to quit.\n\nEnter the letter before the weapon of choice: ")]
if player == 'quit':
sys.exit(0)
break
except KeyError:
print('Please try again.')

Scoring in Python game does not work

I am new to Python, trying to pick up the language outside of my school courses. This Rock Paper Scissors game I am working on functions correctly, although the score output does not show anything. Here is the code...
#!/usr/bin/env python2
# Extra modules used
import random
import time
# Set each move to a specific number
# Once a selection is made by the player,
# it will be equated to that specific variable.
rock = 1
paper = 2
scissors = 3
# Text representation of each move
names = { rock: "Rock", paper: "Paper", scissors: "Scissors" }
# Game Rules
rules = { rock: scissors, paper: rock, scissors: paper }
# Declare variables to be used to track scoring
player_score = 0
computer_score = 0
# Function to print a greeting and start
# a loop to allow the player to continue
#playing as many times as they wish
def start():
print ("Let's play a game of Rock, Paper, Scissors.")
while game():
pass # Allows the loop to stop when player is done
scores() # Call function when done playing
def game():
# Call move function to determine player move
player = move()
# Get computer move as random int between 1 and 3
computer = random.randint(1, 3)
# Send the move through the result function
result(player, computer)
return play_again()
# Function to obtain a move from the player
def move():
while True:
print
player = input("Rock = 1\nPaper = 2\nScissors = 3\nMake a move: ")
# Try to set the player move, or catch the error
try:
# Cast the user input as an integer
player = int(player)
# If entry is valid, set the variable
if player in (1,2,3):
return player
except ValueError:
pass
print ("Oops! I didn't understand that. Please enter 1, 2, or 3.")
# Function to determine the result of the game
# player move and computer move are passed in
def result(player, computer):
# Countdown to result display
print ("1...")
time.sleep(1)
print ("2...")
time.sleep(1)
print("3!")
time.sleep(0.5)
# Display the computer's move
# string.format() gets the text version
# of the move and inserts it where "0"
print ("Computer threw {0}!".format(names[computer]))
#Call the scores set earlier
global player_score, computer_score
# Check the results of the game
if player == computer:
print ("Tie game.")
# Check if the losing move to the player's move
# is equal to the computer's move
elif rules[player] == computer:
print ("Your victory has been assured.")
player_score += 1
else:
print ("The computer laughs as you realize you have been defeated.")
computer_score += 1
# Ask to play again
def play_again():
answer = input("Would you like to play again? y/n: ")
if answer in ("y", "Y", "yes", "Yes", "Of course!"):
return answer
else:
print ("Thank you very much for playing. See you next time!")
def scores():
global player_score, computer_score
print ("HIGH SCORES")
print ("Player: "), player_score
print ("Computer: "), computer_score
# Used to execute in command line or import
# into another Python script. This will prevent
# the code from being executed when being imported.
if __name__ == '__main__':
start()
Your print statements are a little off.
You should be including the arguments inside the print statement
print("Player: ", player_score)
Edit:
To speak a little more to printing. You could also use
print("Player: {}".format(player_score))
You need the variables inside the brackets so:
print ("Player: "), player_score
print ("Computer: "), computer_score
becomes
print ("Player: ", player_score)
print ("Computer: ", computer_score)
Alternatively,
print ("Player: {}".format(player_score))
print ("Computer: {}".format(computer_score))
Format is better to use as there is a whole lot more you can do with it (I'll let you find that out for yourself)!

Categories