I am doing a school project and I need some help communicating between functions. This is what I have got so far
def difficuilty():
level = 0
while level >=4 or level == 0:
level = int(input("Please enter the difficulty (1/2/3)"))
if level == 1:
yesNo = input("you have chosen difficulty 1, is this correct? ")
if yesNo.upper() == 'Y':
level = 1
elif yesNo.upper() == 'N':
level = 4
else:
print ("You have entered the wrong thing")
elif level == 2:
yesNo = input("you have chosen difficulity 2, is this correct? ")
if yesNo.upper() == 'Y':
level = 2
elif yesNo.upper() == 'N':
level = 4
else:
print ("You have entered the wrong thing")
elif level == 3:
yesNo = input("you have chosen difficulity 3, is this correct? ")
if yesNo.upper() == 'Y':
level = 3
elif yesNo.upper() == 'N':
level = 4
else:
print ("You have entered the wrong thing")
return level
def question(level):
if level == 1:
print ("hi")
def main():
getName()
difficulty()
question(level)
I am trying to get the variable 'level' from the difficulty function to go into the question function so I can use it, when I run the program, it gives me an error which says 'NameError: Name 'level is not defined'. Can someone please help me. Thanks
The variable level is only defined within the scope of your two functions, but not at the scope of main(). You have to define a variable (called level) within the scope of main() in order to access it. Try:
def main():
getName()
level = difficulty()
question(level)
This way, the variable that is returned from difficulty() (named level within difficulty()) is accessible to main().
Also, is this your actual code? I notice some mistakes, like difficulty() being spelled two different ways, and a lack of indentation within difficuilty(), that will have unexpected results if you run this. Please post your verbatim code if you have it so that it's easier to tell what the specific problem is.
You need to retrieve the value of level that is returned from your difficult function
def main():
getName()
level = difficulty()
question(level)
I believe the global method does just that, it turns the local arg used within a function to a global one callable by all means.
def difficuilty():
level = 0
while level >=4 or level == 0:
level = int(input("Please enter the difficulty (1/2/3)"))
global level
That way (level) will be callable. One last thing, given your application I would go with Milo's answer, because using global method can have its cons.
Related
No matter how many times I google variations of my question, I cannot seem to find a solution. I am a beginner programmer, trying to build a game that randomly generates events as you progress through the stages. The problem I am running into are return statements, and passing the values between different modules. Each method for each file are inside of classes. They are all static methods, and calling these methods is not my problem. It is transferring the value of the variables. I'm not sure where I am going wrong, whether it is how I am structuring it, or if I just don't understand how these return statements work.
This is the first File I am starting from. Print statements will be filled out after everything functions properly.
def story():
print("---Intro Story Text here--- ... we will need your name, Traveler. What might it be?")
user_prompt = Introduction.PlayerIntroduction
name = user_prompt.player_info(1)
print(f"Welcome {name}!")
print(f"----After name is received, more story... how old might you be, {name}?")
age = user_prompt.player_info(2)
This is the file I am trying to get the values from. File: Introduction, Class: PlayerIntroduction
#staticmethod
def player_info(funct_select):
if funct_select == 1:
name = PlayerIntroduction.get_player_name()
player_name = name
elif funct_select == 2:
age = PlayerIntroduction.get_player_age()
player_age = age
return player_name, player_age
#staticmethod
def get_player_name():
print("\n\n\nWhat is your name?")
players_name = input("Name: ")
while True:
print(f"Your name is {players_name}?")
name_response = input("Yes/No: ")
if name_response == "Yes" or name_response == "yes":
name = "Traveler " + players_name
break
elif name_response == "No" or name_response == "no":
print("Let's fix that.")
PlayerIntroduction.get_player_name()
else:
print("Please respond with 'Yes' or 'No'.")
return name
#staticmethod
def get_player_age():
print("\n\n\nHow old are you?")
age = input("Age: ")
while True:
print(f"Your age is {age}?")
age_response = input("Yes/No: ")
if age_response == "Yes" or age_response == "yes":
break
elif age_response == "No" or age_response == "no":
print("Let's fix that.")
PlayerIntroduction.get_player_age()
else:
print("Please respond with 'Yes' or 'No'.")
return age
I would like to use the values for "name" and "age" throughout multiple modules/multiple methods within my program. But in order to get those values, I need to assign a variable to the function call.. Resulting in prompting the user to re-enter their name/age at later stages in the game. My idea to combat this was in the first method of this module, creating a conditional statement "if 'example' == 1: 'run the name prompt' and elif == 2: run age prompt, thinking the initial run with the arguments defined would run these prompts, store the values into the variables (name, age), and finally pass the values to the new variables that are NOT assigned to the function call (p_name, p_age), avoiding triggering the user prompt over and over. Ultimately, this failed, and as the code sits now I am getting:
UnboundLocalError: local variable 'player_age' referenced before assignment
Why is this? The only instance 'player_age' is called that is reachable at this point is in the return statement, indented in-line with the conditional statement. The code should read (If I understand incorrectly, please explain) from top to bottom, executing in that order. The 'if' condition is met, so it should run that. If I were to define 'player_name' and 'player_age' as null at the top of this method to avoid this error, then every time I would need to reference these values initially entered by the user, they would be re-assigned to 'null', negating everything I am trying to do.
Thank you all for your patience, I tried to explain what I was doing and my thought process the best I could. Any feedback, criticism, and flaws within my code or this post are GREATLY appreciated. Everything helps me become a better programmer!! (:
Im making a "game" for practice. Its a basic guess game, but i wanted to make the game only with functions. This is my problem (for ex.):
function 1:
variablaA
#some other code
function 2:
variableB
variableC = varibleA + variableB
#some other code
I have tried too goole about objects and classes but im not sure i understand what im doing right now.
import random
import sys
min = 1
max = 99
guessed_number = random.randint(min, max)
class functions:
def __init__(game, difficulty, lifes):
game.difficulty = difficulty
game.lifes = lifes
def GameDiff(hardness):
#Setting game difficulty
print "Select difficulty : \n 1; Easy \n 2; Medium \n 3; Hard \n"
difficulty = raw_input()
if difficulty == "1":
print "Its just the beginning"
lifes = 15
elif difficulty == "2":
lifes = 10
elif difficulty == "3":
lifes = 5
else:
print "This isn't an option try again"
GameDiff(hardness)
def core(basic):
#The core of the game
print "I guessed a number..."
player_number = int(raw_input("Whats the number I thinking of?"))
constant = 1
GameTime = 1
while GameTime == constant:
if player_number < guessed_number:
print "Your number is smaller than my guessed number"
print "Try to duplicate your number (But maybe Im wrong)"
player_number = int(raw_input("Make your tip again\n"))
elif player_number > guessed_number:
print "Your number is bigger than my guessed number"
print "Try to half your number (But maybe Im wrong)"
player_number = int(raw_input("Make your tip again\n"))
else:
GameTime = 0
print "You guessed it! Congratulations"
def main(self):
#The whole game only with functions
functions.GameDiff()
functions.core()
Function = functions()
Function.main()
if you are defining function with parameters, you need to pass data(parameters) into a function when you call it
example:
def my_function(name):
print("my name is " + name)
my_function("Kevin")
in your case you define:
def GameDiff(hardness):
def core(basic):
which are expecting parameters
and when you are calling those funcitions, you are doing that on wrong way:
def main(self):
#The whole game only with functions
functions.GameDiff()
functions.core()
Function = functions()
you need to pass parameters
example:
functions.GameDiff(5)
functions.core(1)
Function = functions(1,5)
NOTE: good practice will be to use self instead of game
def __init__(self, difficulty, lifes):
self.difficulty = difficulty
self.lifes = lifes
they are just two different kinds of class elements:
Elements outside the init method are static elements; they belong
to the class. They're shared by all instances.
Elements inside the init method are elements of the
object (self); they don't belong to the class.Variables created inside init (and all other method functions) and prefaced with self. belong to the object instance.
I am a programming beginner and I am trying to build a fill-in-the-blank quiz. I am almost finished but I am stuck on 2 problems I am not able to solve, whatever I do. I would really appreciate your help with this. Thank you for helping me with this!
If you try to run the code and play the game:
1) It prints the quiz according to the difficulty(easy-insane) and quiz you want to play(apple, bond and programming quiz) which is great but afterwards it prompts you to choose difficulty again (the player_level() function keeps going even though the player/user has already chosen the difficulty level. I don't really understand why it does it? The player_level() procedure seems perfectly okay and logical to me.
2) The errors:
a) local variable blanks_index referenced before assignment
b) global name list_of_answers is not defined.
I know that it is related to the initialize_game() function but I don't know how to change the code so it refers all the variables (blanks_index, answers_index, player_lives) correctly.
It could be solved by creating global variables(I guess) but that is not a good practice so I am trying to avoid it. Formerly, the whole function initialise_game() and play_game() were one function, but as there are over 25 lines of code in one function, it is not a good practice as it is long and messy and I know that I can separate it but I don't know how.
Here is the code:
"""3 diffferent quizzes : Apple quiz, James Bond quiz, Programming quiz"""
"""Quiz and answers about Apple"""
Apple_quiz = ("The most valuable company in terms of market cap in 2016 is, ___1___."
"It was founded in ___2___. Its flagship product is called ___3___."
"___1___ has many competitors, the biggest rival is ___4___,founded by"
" nobody but the richest man on the planet,___5___ ___6___.")
list_of_answers_Apple = ["Apple", "1976", "Iphone", "Microsoft", "Bill", "Gates"]
"""Quiz and answers about Bond"""
Bond_quiz = ("James Bond is agent ___1___. He serves his country,___2___ ___3___"
" against its enemies. His car of choice is usually ___4___ ___5___."
" His favorite drink is ___6___.")
list_of_answers_Bond = ["007", "United", "Kingdom", "Aston", "Martin", "Martini"]
"""Quiz and answers about programming basics"""
Programming_quiz = ("___1___ are created with the def keyword. ___1___ are also called ___2___"
" You specify the inputs a ___1___ take by adding ___3___ separated by commas"
" between the parentheses. ___3___ can be standard data types such as string, number"
" ,dictionary, tuple, and ___4___ or can be more complicated such as ___5___"
" and ___6___ functions.")
list_of_answers_Programming = ["Functions", "procedures", "arguments", "lists", "objects", "lambda"]
blank_space = ["___1___", "___2___", "___3___", "___4___", "___5___", "___6___]"]
#List of levels with corresponding lives/guesses that player can have
quiz_list = ["Apple", "Bond", "Programming"]
level_list = ["easy", "medium", "hard", "superhard", "insane"]
lives_easy = 5
lives_medium = 4
lives_hard = 3
lives_superhard = 2
lives_insane = 1
def choose_quiz():
""" Prompts player to pick a type of quiz and loads the quiz """
#Input = player_quiz (raw input from player)
#Output = loaded quiz, player chose
while True:
player_quiz = raw_input("Please, select a quiz you want to play: "
"(Apple, Bond or Programming): ")
if player_quiz == "Apple":
return Apple_quiz
elif player_quiz == "Bond":
return Bond_quiz
elif player_quiz == "Programming":
return Programming_quiz
else:
print "We don't have such quiz, pick again!"
def answers_for_quiz():
""" Loads appropiate answers to the quiz that player has chosen"""
#Input = player quiz (raw input from player)
#Output = loaded quiz answers from the quiz player chose
player_quiz_pick = choose_quiz()
if player_quiz_pick == Apple_quiz:
return list_of_answers_Apple
elif player_quiz_pick == Bond_quiz:
return list_of_answers_Bond
elif player_quiz_pick == Programming_quiz:
return list_of_answers_Programming
def player_level():
""" Loads a difficulty that player chooses """
#Input = player_level_input (raw input of player choosing a difficulty)
#Output = corresponding number of lives:
#Easy = 5 lives, Medium = 4 lives
#Hard = 3 lives, Superhard = 2 lives
#Insane = 1 life
while True:
player_level_input = raw_input("Please type in a difficulty level: "
"(easy, medium, hard, superhard, insane): ")
if player_level_input == "easy":
return lives_easy #Easy = 5 lives
elif player_level_input == "medium":
return lives_medium #Medium = 4 lives
elif player_level_input == "hard":
return lives_hard #Hard = 3 lives
elif player_level_input == "superhard":
return lives_superhard #Superhard = 2 lives
elif player_level_input == "insane":
return lives_insane #Insane = 1 life
else:
print "We do not have such difficulty! Pick again!"
def correct_answer(player_answer, list_of_answers, answers_index):
""" Checks, whether the the answer from player matches with the answer list. """
#Input: player_answer (raw input that player enters in order to fill in the blank)
#Output: "Right answer!" or "Wrong! Try again!" this output will be later used in the game
if player_answer == list_of_answers[answers_index]:
return "Right answer!"
return "Wrong! Try again!"
def initialize_game():
"""Functions that sets up a game so we can play it """
player_quiz_pick, player_level_pick, list_of_answers = choose_quiz(), player_level(), answers_for_quiz()
print player_quiz_pick
print "\nYou will get maximum " + str(player_level_pick) + " guesses for this game. Good luck.\n"
blanks_index, answers_index, player_lives = 0, 0, 0
#for elements in blank_space:
while blanks_index < len(blank_space):
player_answer = raw_input("Please type in your answer for " + blank_space[blanks_index] + ": ")
if correct_answer(player_answer,list_of_answers,answers_index) == "Right answer!":
print "Correct answer! Keep going!\n"
player_quiz_pick = player_quiz_pick.replace(blank_space[blanks_index],player_answer)
answers_index += 1
blanks_index += 1
print player_quiz_pick
if blanks_index == len(blank_space):
print "Congratulations! You nailed it! You are the winner!"
else:
player_level_pick -= 1
if player_level_pick == 0:
print "Game over! Maybe next time!"
break
else:
print "One life less, that sucks! Have another shot!"
print "You have " + str(player_level_pick) + " guesses left."
initialize_game()
Your main problem is that you keep calling the same functions over and over again and do not save the input into variables. Here are some tips about your code and questions:
You are not doing anything with your player_level() method call, so the player doesn't actually chooses a level in a way that affects the game. You should change the function call, so the returned value will be stored.
//the call to the method:
player_level_pick = player_level()
Afterwards, you keep calling the player_level() method, and not using the actual answer that the user supplied. Change all player_level() appearences to player_level_pick - the variable you use to save the answer (as I showed above). Same goes to all other unneeded function calls such as choose_level().
You should initialize number_of_guesses, player_lives, list_of_answers, and other vars to a matching value to player_level_pick as well, so it will hold the right value according to the level. Likewise, you should change this line:
# the line that checks if game is over
# change from:
if number_of_guesses == player_lives:
# to :
if number_of_guesses == 0:
In order to return multiple values, you have to use tuples. Using multiple return statements one after the other does not work anywhere.
so, instead of:
return list_of_answers
return number_of_guesses
return blanks_index
return answers_index
return player_lives
you should use tuples, and unpack them properly:
# the return statement:
return (list_of_answers, number_of_guesses, blanks_index, answers_index, player_lives)
# and the unpacking in the calling function:
list_of_answers, number_of_guesses, blanks_index, answers_index, player_lives = initialize_game()
this way, all of the returned values go into the wanted variables in the calling function. this way, you need to call the initialize_game() from play_game(). it will be the efficient way for you.
Just saying it again, as I said in the end of (4) - you should unit initialize_game() and play_game() into a single function (because a lot of data is the same needed data), or just call initialize_game() from play_game().
Better practice then using this recursivly: return choose_level(), you should use a while True: loop, and just brake when you get a proper answer.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Im new(-ish) to python and I made a game today which after I finished I realised I'd made a big mistake :
inside the functions I had to access and edit variables which where also accessed and changed in other functions and maybe in the future outside the functions. And I don't know how to do that.
I've researched for a long time and found very few things that might solve the problem, I've tried a few, but they haven't worked and I don't understand how to use others.
Could you please try to help me with the problem and if you spot others please tell me, as Im not too good at debugging :(
Here is the code below, its quite big (I've put the variables I need to access and change in bold):
from random import randint
print ("Ghost Game v2.0")
print ("select difficulty")
score = 0
alive = True
difficulty = 0
doors = 0
ghost_door = 0
action = 0
ghost_power = 0
#define the function 'ask_difficulty'
def ask_difficulty() :
difficulty = input ("Hard, Normal, Easy")
set_difficulty()
# define the function 'set_difficulty' which sets the difficulty.
def set_difficulty() :
if difficulty == 'Hard' or 'Normal' or 'Easy' :
if difficulty == 'Hard' :
doors = 2
elif difficulty == 'Normal' :
doors = 3
elif difficulty == 'Easy' :
doors = 5
else:
print ("Invalid input, please type Hard, Normal, or Easy")
ask_difficulty()
# define the function 'ghost_door_choose' which sets the ghost door and the chosen door
def ghost_door_choose(x):
ghost_door = randint (1, x)
print (doors + " doors ahead...")
print ("A ghost behind one.")
print ("Which do you open?")
if doors == 2 :
door = int("Door number 1, or door number 2...")
if 1 or 2 in door :
ghost_or_no()
else :
print ("Invalid input")
ghost_door_choose(difficulty)
elif doors == 3 :
door = int("Door number 1, door number 2, or door number 3")
if 1 or 2 or 3 in door :
ghost_or_no()
else:
print ("Invalid input")
ghost_door_choose(difficulty)
elif doors == 5 :
print("Door number 1, door number 2, door number 3, door number 4, or door number 5.")
if 1 or 2 or 3 or 4 or 5 in door :
ghost_or_no()
else:
print ("Invalid input")
ghost_door_choose(difficulty)
# define the function 'ghost_or_no'
def ghost_or_no() :
if door == ghost_door:
print ("GHOST!!")
print ("Initiating battle...")
battle()
else:
print ("No ghost, you\'ve been lucky, but will luck remain with you...")
score = score + 1
ghost_door_choose(difficulty)
# define the function 'battle' which is the battle program
def battle() :
ghost_power = randint (1, 4) # 1 = Speed, 2 = Strength, 3 = The ghost is not friendly, 4 = The ghost is friendly
print ("You have 3 options")
print ("You can flee, but beware, the ghost may be fast (flee),")
print ("You can battle it, but beware, the ghost might be strong (fight),")
print ("Or you can aproach the ghost and be friendly, but beware, the ghost may not be friendly (aproach)...")
action = input ("What do you choose?")
if flee in action :
action = 1
elif fight in action :
action = 2
elif aproach in action :
action = 3
else :
print ("Invalid input")
battle()
if ghost_power == action :
if action == 1:
print ("Oh no, the ghost\'s power was speed!")
print ("DEFEAT")
print ("You\'r score is " + score)
alive = False
elif action == 2:
print ("Oh no, the ghost\'s power was strength!")
print ("DEFEAT")
print ("You\'r score is " + score)
alive = False
elif action == 3:
print ("Oh no, the ghost wasn\'t friendly ")
alive = False
elif ghost_power == 4 and action == 3 :
print ("Congratulations, The ghost was friendly!")
score = score + 1
ghost_door_choose(difficulty)
elif ghost_power != action and ghost_power != 4 :
if action == 1:
print ("Congratulations, the ghost wasn\'t fast!")
score = score + 1
ghost_door_choose(difficulty)
elif action == 2:
print ("Congratulations, you defeated the ghost!")
score = score +1
ghost_door_choose(difficulty)
elif ghost_power != action and ghost_power == 4 :
if action == 1:
print ("You ran away from a friendly ghost!")
print ("Because you ran away for no reason, your score is now 0")
score = 0
ghost_door_choose(difficulty)
elif action == 1:
print ("You killed a friendly ghost!")
print ("Your score is now 0 because you killed the friendly ghost")
score = 0
ghost_door_choose(difficulty)
#actual game loop
ask_difficulty()
while alive :
ghost_door_choose(doors)
Consider:
x=0
z=22
def func(x,y):
y=22
z+=1
print x,y,z
func('x','y')
When you call func you will get UnboundLocalError: local variable 'z' referenced before assignment
To fix the error in our function, do:
x=0
z=22
def func(x,y):
global z
y=22
z+=1
print x,y,z
The global keyword allows a local reference to a global defined variable to be changed.
Notice too that the local version of x is printed, not the global version. This is what you would expect. The ambiguity is if there is no local version of a value. Python treats globally defined values as read only unless you use the global keyword.
As stated in comments, a class to hold these variables would be better.
Those variables at the top of your script are global and to set them in functions, you have to declare them global in the function. As a smaller example,
score = 0
alive = True
def add_score(value):
"""Add value to score"""
global score
score += value
def kill_kill_kill():
global alive
alive = False
The next step is to create classes, which can get complicated. For instance, if you want to track score by user but a user can have multiple characters which each have their own aliveness, you would start to build classes to represent those things.
The global keyword may be what you are looking for.
For example in the following code.
some_variable = 10
def some_function():
global some_variable
some_variable = 20
This would result in some_variable (in the global scope) referring to the value of 20. Where as it would remain at 10 (in the global scope) without the use of the global keyword.
More on global and local variables here.
A function has its own variable scope - this is true for many languages. This means that once the function finishes executing, the variables cease to exist (and Python's garbage collection will clean them up).
The old-school (and generally frowned upon, not necessarily fairly) way of doing this is to use Global Variables. These are variables you declared outside the scope of the function, usually at the beginning of your source, and can be used throughout your program's various functions and classes.
There are good reasons people don't use global variables much, from performance issues through to getting them confused with locally scoped variables, but they are a quick and easy way to keep information and access it throughout your program.
To use a global, you need to declare within the function that you are using that variable, like this:
MyGlobal="This is a global variable"
def MyFunction():
global MyGlobal
MyGlobal += " and my function has changed it"
if __name__=="__main__":
print MyGlobal
MyFunction()
print MyGlobal
Having said this, the usual way to pass information to and from functions is to use arguments and return values - this is a better design methodology, and the one usually taught. This is more a design method than a change to your code; you write your program with keeping global variables down to an absolute minimum.
To take the above example, this would change our code to the following:
def MyFunction(MyArg):
MyArg+=" and my function has given me a new version of it"
return MyArg
if __name__=="__main__":
MyVariable="This is a variable"
print MyVariable
MyVariable = MyFunction(MyVariable)
print MyVariable
Note that this is much more flexible - I can use it as I have above, to change the value of MyVariable, but I could also use the same function to return the new value to a different variable, keeping the original intact.
I hope this helps, sorry if I was a tad verbose.
I am trying to write a program for an assignment where you input a specific command and you can play Rock-Paper-Scissors-Lizard-Spock against the computer.
It was done and working until I realized that the assignment instructions wanted me to make it so that you keep playing the game until one person gets five wins.
So I thought, no big deals, let's throw in a while loop and some variables to track the wins. But when I run the program, it only runs once still. I don't know what I am doing wrong - as this should work. This is my first time working with Python (version 3.3) and this IDE, so I really need some help. Usually I'd just debug but I can't figure out how to work the one in this IDE.
Here is my code. The trouble while-loop is at the way bottom. I am nearly positive everything inside the class works. I would like to note that I already tried while(computerWins < 5 and userWins < 5), so I don't think the condition is the problem.
import random
computerWins = 0
userWins = 0
print ('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\nSpock = sp')
class rockPaperScissorsLizardSpock:
#Two methods for converting from strings to numbers
#convert name to number using if/elif/else
#also converts abbreviated versions of the name
def convertName(name):
if(name == 'rock' or name == 'r'):
return 0
elif(name == 'Spock' or name == 'sp'):
return 1
elif(name == 'paper' or name == 'p'):
return 2
elif(name == 'lizard' or name == 'l'):
return 3
elif(name == 'scissors' or name == 'sc'):
return 4
else:
print ('Error: Invalid name')
#convert number to a name using if/elif/else
def convertNum(number):
if(number == 0):
return 'rock'
elif(number == 1):
return 'Spock'
elif(number == 2):
return 'paper'
elif(number == 3):
return 'lizard'
elif(number == 4):
return 'scissors'
else:
print ('Error: Invalid number')
#User selects an option, and their selection is saved in the 'choice' variable
#Using a while loop so that the user cannot input something other than one of the legal options
prompt = True
while(prompt):
i = input('\nEnter your selection: ')
if(i=='r' or i=='p' or i=='sc' or i=='l' or i=='sp'):
prompt = False
else:
print('Invalid input.')
prompt = True
#Convert the user's selection first to a number and then to its full string
userNum = convertName(i)
userChoice = convertNum(userNum)
#Generate random guess for the computer's choice using random.randrange()
compNum = random.randrange(0, 4)
#Convert the computer's choice to a string
compChoice = convertNum(compNum)
print ('You chose', userChoice)
print ('The computer has chosen', compChoice)
#Determine the difference between the players' number selections
difference = (compNum - userNum) % 5
#Use 'difference' to determine who the winner of the round is
if(difference == 1 or difference == 2):
print ('The computer wins this round.')
computerWins = computerWins+1
elif (difference == 4 or difference == 3):
print ('You win this round!')
userWins = userWins+1
elif(difference == 0):
print ('This round ended up being a tie.')
#Plays the game until someone has won five times
while(computerWins != 5 and userWins != 5):
rockPaperScissorsLizardSpock()
if(computerWins == 5 and userWins != 5):
print ('The computer wins.')
elif(computerWins != 5 and userWins == 5):
print ('You win!')
The essential problem is that rockpaperscissorslizardspock is a class, where you expect it to be a function. The code inside it runs exactly once, when the whole class definition is parsed, rather than each time you call the class as you seem to expect.
You could put the relevant code into an __init__ method - this is a fairly direct analogue of a Java constructor, and hence is is run each time you call the class. But in this case, you probably don't need it to be in a class at all - calling the class creates a new instance (like doing new MyClass() in Java), which you don't use. You would also in this case (or if you made it into a function) need to make some more modifications to make sure the game state persists properly.
The easiest actual solution is to:
delete the line class rockpaperscissorslizardspock: (and unindent everything below it)
Take all the code that was under the class but not in a function - everything from the player makes a selection to determining the winner of the round - and paste it in place of the call to rockpaperscissorslizardspock() in the bottom loop.
The first thing is that you are using a class where you should probably be using a function.
Your code initially runs because python is loading the class.
However, the line rockPaperScissorsLizardSpock() is creating new anonymous instances of your class which calls a constructor that you haven't defined so it does nothing.
One of the interesting things about python is that it allows nested functions so if you change the class to a def you're almost there.
After that, you'll run into trouble with global variables in a local context. That problem is already explained in another StackOverflow question: Using global variables in a function other than the one that created them.
Here is my suggestion for the skeleton to a more simple solution. Use some ideas from here if you like.
import random
legal_shapes = ['r', 'p', 'sc', 'sp', 'l']
scoreboard = [0, 0]
print('SELECTION KEY:\nRock = r\nPaper = p\nScissors = sc\nLizard = l\n'
'Spock = sp')
while(max(scoreboard) < 5):
print("\nScore is {}-{}".format(*scoreboard))
# pick shapes
p1_shape = input('Enter your selection: ')
if p1_shape not in legal_shapes:
print('Not legal selection!')
continue
p2_shape = random.choice(legal_shapes)
print('\np1 plays {} and p2 plays {}'.format(
p1_shape.upper(), p2_shape.upper()))
# determine int values and result indicator
p1_shape_int = legal_shapes.index(p1_shape)
p2_shape_int = legal_shapes.index(p2_shape)
res = (p1_shape_int - p2_shape_int) % 5
if res != 0:
res = abs((res % 2) - 2)
# Print winner
if res == 0:
print(' -> Draw!!')
else:
print(' -> p{} wins'.format(res))
scoreboard[res-1] += 1
print("\nThe game is over!!")
print("p{} won with score {}-{}".format(res, *scoreboard))
It outputs something like
(env)➜ tmp python3 rsp.py
SELECTION KEY:
Rock = r
Paper = p
Scissors = sc
Lizard = l
Spock = sp
Score is 0-0
Enter your selection: T
Not legal selection!
Score is 0-0
Enter your selection: l
p1 plays L and p2 plays SP
-> p2 wins
Score is 0-1
Enter your selection: l
p1 plays L and p2 plays SC
-> p2 wins
...
The game is over!!
p2 won with score 2-5