I'm writing code for a rock, paper, scissors game but the if statement in the function identify_winner is not running. The only thing that prints out is the else statement and it prints out for all outcomes, not just when it's a tie. I'm pretty sure it has something to do with the variables but I don't know what it is.
import random
ROCK = 1
PAPER = 2
SCISSORS = 3
def main():
user_choose(None)
comp_choose(None)
identify_winner()
def user_choose(weapon):
weapon = int(input('Choose Your Weapon' + '\n (Rock = 1, Paper = 2' +\
' Scissors = 3): '))
if weapon == 1:
print('You have chosen Rock')
elif weapon == 2:
print('You have chosen Paper')
elif weapon == 3:
print('You have chosen Scissors')
def comp_choose(choice):
if random.randint(1,3) == 1:
choice = 'Rock'
elif random.randint(1,3) == 2:
choice = 'Paper'
else:
choice = 'Scissors'
print('Your enemy has chosen',choice)
def identify_winner():
user = 0
comp = 0
while user == comp:
user_choose(user)
comp_choose(comp)
if (user == 1 and comp == 3) or (user ==2 and comp == 1) or (user == 3 and comp
== 2):
print('Congratulations! You have defeated the foe!')
elif (comp ==1 and user == 3) or (comp == 2 and user == 1) or (comp == 3 and
user == 2):
print('Alas, you have been defeated! Better luck next time!')
else:
print('Oh no, a tie! choose again!')
main()
First and foremost it is not a good practice to call main function directly as it was a script. If you plan to create not script program you should scope main function inside.
if __name__ == "__main__":
main()
Secondly, you don't need to call user_choose and comp_choose inside identify winner, you can just return those values in your main program and give them as arguments to your identify winner function. Also you should not generate two times a random number in your comp_choose() because in the second elif you could generate the previous number so comp choice most likely be Scissors. I give you one possible solution to your problem:
import random
ROCK = 1
PAPER = 2
SCISSORS = 3
def main():
identify_winner(user_choose(), comp_choose())
def user_choose():
weapon = int(input('Choose Your Weapon' + '\n (Rock = 1, Paper = 2' +\
' Scissors = 3): '))
if weapon == 1:
print('You have chosen Rock')
elif weapon == 2:
print('You have chosen Paper')
elif weapon == 3:
print('You have chosen Scissors')
return weapon
def comp_choose():
comp_weapon = random.randint(1,3)
if comp_weapon == 1:
choice = 'Rock'
elif comp_weapon == 2:
choice = 'Paper'
else:
choice = 'Scissors'
print('Your enemy has chosen',choice)
return comp_weapon
def identify_winner(user, comp):
if (user == 1 and comp == 3) or (user ==2 and comp == 1) or (user == 3 and comp
== 2):
print('Congratulations! You have defeated the foe!')
elif (comp ==1 and user == 3) or (comp == 2 and user == 1) or (comp == 3 and
user == 2):
print('Alas, you have been defeated! Better luck next time!')
else:
print('Oh no, a tie! choose again!')
if __name__ == "__main__":
main()
I made some little changes in your code. Commented the parts for explanation:
import random
# you never use those, so they are not needed here:
# ROCK = 1
# PAPER = 2
# SCISSORS = 3
def user_choose(): # no input argument needed since you define weapon in the next line anyway
weapon = int(input('Choose Your Weapon' + '\n (Rock = 1, Paper = 2' +\
' Scissors = 3): '))
# this part is asking for a number as long as user don't choose a valid number between 1 and 3.
# You could do even more here, check for number or letter, check if number is 0 or negative
while weapon>3:
weapon = int(input('No valid number. Please choose again: ' + '\n (Rock = 1, Paper = 2' +\
' Scissors = 3): '))
if weapon == 1:
print('You have chosen Rock')
elif weapon == 2:
print('You have chosen Paper')
elif weapon == 3:
print('You have chosen Scissors')
return weapon # you need to return the variable weapon, otherwise it is only in the local scope and your main function doesn't have access to it
def comp_choose(): # same as in the other function, no input argument needed
choice = random.randint(1,3) # in your code random.randint(1,3) executes twice and can have two different results. You want it once and then check on it
if choice == 1:
chose = 'Rock' # in the main() func you compare the numbers, but in your code user has numbers between 1 and 3 and comp has values with rock, paper, scissors.
elif choice == 2:
chose = 'Paper'
else:
choice = 3
chose = 'Scissors'
print('Your enemy has chosen',chose)
return choice # same as in the other function with 'weapon'
def main(): # identy_winner() isn't needed. two functions for user and comp with the main to select winner is enough
run = True
while run: # doing it like this you can make the user choose if he wants to continue or not (later at the 'continue_playing' part)
user = user_choose() # get access to the return value of the function
comp = comp_choose() # get access to the return value of the function
if (user == 1 and comp == 3) or (user ==2 and comp == 1) or (user == 3 and comp
== 2):
print('Congratulations! You have defeated the foe!')
elif (comp ==1 and user == 3) or (comp == 2 and user == 1) or (comp == 3 and
user == 2):
print('Alas, you have been defeated! Better luck next time!')
else:
print('Oh no, a tie! choose again!')
continue_playing = input('You want to play again? [y/n]: ')
if continue_playing == 'n':
run = False
main()
The code will crash if the user chooses a letter instead of numbers, and working poorly if he chooses numbers 0 or less. You may want to check for that.... I leave that up to you.
Related
im new to this python program and was tasked to generate a game or scissors paper stone game in python without the use of a list. i have the function here as:
def getRandomShape():
Shape = random.randint(1, 3)
if Shape == 1:
print('Scissors'.upper())
elif Shape == 2:
print('Stone'.upper())
else:
print('Paper'.upper())
getRandomShape()
but whenever i call for the function, it says its not defined.
the error occurse at the possibleHands section where im unable to call for the function but able to at the bottom for the checkForWinner function call
here's the full program.
import random
print('welcome to scissors paper stone')
cpuScore = 0
playerScore = 0
tieScore = 0
possibleHands = getRandomShape(computerHand)
def getRandomShape(computerHand):
Shape = random.randint(1, 3)
if Shape == 1:
print('Scissors'.upper())
elif Shape == 2:
print('Stone'.upper())
else:
print('Paper'.upper())
def checkForWinner(playerHand, computerHand):
if(playerHand == 'Stone' and computerHand == 'Paper'):
print('you lost')
return 'cpu'
elif(playerHand == 'Stone' and computerHand == 'Scissors'):
print('you won')
return 'player'
elif(playerHand == 'Scissors' and computerHand == 'Paper'):
print('you won')
return 'player'
elif(playerHand == 'Scissors' and computerHand == 'Stone'):
print('you lost')
return 'cpu'
elif(playerHand == 'Paper' and computerHand == 'Scissors'):
print('you lost')
return 'cpu'
elif(playerHand == 'Paper' and computerHand == 'Stone'):
print('you won')
return 'player'
else:
print('its a tie. play again')
return 'tie'
while(playerScore != 3 and cpuScore != 3):
name = input('Please enter your name: ')
while True:
playerHand = (input('Round 1: '+str(name)+ ', please choose a shape:'))
if(playerHand == 'Scissors' or playerHand == 'Paper' or playerHand == 'Stone'):
break
else:
print('invalid input, case sensitive. Try again')
computerHand = random.choice(possibleHands)
print('your Hand: ', playerHand)
print('cpu Hand: ', computerHand)
results = checkForWinner(playerHand, computerHand)
if(results == 'player'):
playerScore += 1
elif(results == 'cpu'):
cpuScore += 1
else:
tieScore += 1
print('your score: ', playerScore, 'CPU: ', cpuScore, 'Ties: ', tieScore)
print('gg game over')
got this from a youtube tutorial
You must declare the function before its usage. On line 8 getRandomShape is called before its definition, so a NameError would occur.
What you can do is to put all the code that is not in a function, other than the import statements inside a main() function. And at the end you add:
if __name__ == ‘__main__’:
main()
When the program is called it would execute the main() function, and it would not matter if you put the function before or after others. The only thing that matters is you only call functions after they are already defined.
You can learn more about it here.
There are many more problems with this code, and this only fixes the NameError
that you are currently facing.
I am looking for some input on a rock, paper, scissors program that I am making where the statements in the main() and determineWinner that use playerChoice always terminate in the else: case. Each trial will output the player chooses scissors and that the game is tied. I am not sure where I went wrong here as I've printed the input to confirm it is correct before sending to it to the other functions. I cannot figure what pare of the above to function is causing the problem, if anyone could point me in the right direction here I would be grateful.
Here is the code I have so far:
import random
# define main function
def main():
# initialize playAgain to start game, set stats to 0
playAgain = 'y'
numberTied = 0
numberPlayerWon = 0
numberComputerWon = 0
print("Let's play a game of rock, paper, scissors.")
# loop back to play again if user confirms
while playAgain == 'y' or playAgain == 'Y':
computerChoice = processComputerChoice()
playerChoice = processPlayerChoice()
# display computer choice
if computerChoice == 1:
print('The computer chooses rock.')
elif computerChoice == 2:
print('The computer chooses paper.')
else:
print('The computer chooses scissors.')
# display player choice
if playerChoice == 1:
print('You choose rock.')
elif playerChoice == 2:
print('You choose paper.')
else:
print ('You choose scissors.')
# assign who won to result and add total wins/ties to accumulator
result = determineWinner(playerChoice, computerChoice)
if result == 'computer':
numberComputerWon += 1
elif result == 'player':
numberPlayerWon += 1
else:
numberTied += 1
# ask player if they would like to play again
print('')
print
playAgain = input('Do you want to play again? (Enter y or Y to start another game)')
print('')
else:
# print accumulated wins and ties for computer and player
print('There were', numberTied, 'tie games played.')
print('The computer won', numberComputerWon, 'game(s).')
print('The player won', numberPlayerWon, 'game(s).')
print('')
# define computer choice function
def processComputerChoice():
# randomly select an option for the computer to play
randomNumber = random.randint(1,3)
print(randomNumber)
return randomNumber
# define player choice function
def processPlayerChoice():
choice = int(input(('What is your choice? Enter 1 for rock, 2 for paper, or 3 for scissors. ')))
print (choice)
# throw error if player makes invalid choice
while choice != 1 and choice != 2 and choice != 3:
print('ERROR: please input a valid choice of 1, 2, or 3')
choice = int(input('Please enter a correct choice: '))
return choice
# definition for the function to determine the winner
def determineWinner(playerChoice, computerChoice):
# determine player choice and compare to computer choice to determine the winner
if computerChoice == 1:
if playerChoice == 2:
print('Paper covers rock. You are victorious!')
winner = 'player'
elif playerChoice == 3:
print('Rock bashes scissors. The computer is victorious!')
winner = 'computer'
else:
print('The game is tied. Try again 1')
winner = 'tied'
if computerChoice == 2:
if playerChoice == 1:
print('Paper covers rock. The computer is victorious!')
winner = 'computer'
elif playerChoice == 3:
print('Scissors slice paper. You are victorious!')
winner = 'player'
else:
print('The game is tied. Try again 2')
winner = 'tied'
if computerChoice == 3:
if playerChoice == 1:
print('Rock bashes scissors. You are victorious!')
winner = 'player'
elif playerChoice == 2:
print('Scissors slice paper. The computer is victorious!')
winner = 'computer'
else:
print('The game is tied. Try again 3')
winner = 'tied'
return winner
main()
input("Press Enter to continue")
The return statement of your function processPlayerChoice has incorrect indentation. It should be out of while loop (unindent it one level)
At the moment, if player enters correct choice your function will return None.
If user enters incorrect choice, it will enter the while loop and will return whatever the second input from user is.
def processPlayerChoice():
choice = int(input(('What is your choice? Enter 1 for rock, 2 for paper, or 3 for scissors. ')))
print (choice)
# throw error if player makes invalid choice
while choice != 1 and choice != 2 and choice != 3:
print('ERROR: please input a valid choice of 1, 2, or 3')
choice = int(input('Please enter a correct choice: '))
return choice
Make sure to align your return statements with the function body. Currently in both processPlayerChoice and determineWinner they are aligned with the conditional loops, and thus will not be reached every time.
This is the largest program I've made so far my problem is that my program won't run because the variable cpu isn't defined. I've tried different approaches but still nothing. Here is my code, also is there anyway to shorten my code? I felt I made alot of repetitive lines. I suspect that my problem is in the def cpu_choice(). Also this program dosent seem to give any output after its done.
#This program will execute a Rock,Paper,Scissors Game.
import random
get = int(input('Enter a number 1 to 3 as your choice.\n'))
def cpu_choice():#This function is for the computer to get a option.
list_option = [1 , 2, 3]
cpu = random.choice(list_option)
return(random.choice(list_option))
if cpu == 1:
cpu = "Rock"
if cpu == 2:
cpu = 'Paper'
if cpu == 3:
cpu = 'Scissor'
def compare(cpu,get):
again = 'y'
while again == 'y' or again == 'Y':
if get == cpu:
print('Its a tie!')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
#Checks to see if it is a tie
elif cpu == 'Rock' and get == 'Scissor':
print('You win!')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
#Compares when CPU picks Rock.
elif cpu == 'Rock' and get == 'Paper':
print('You lose.')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
elif cpu == 'Paper' and get == 'Rock':
print('You win!')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
elif cpu == 'Paper' and get == 'Scissor':
print('You lose.')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
elif cpu == 'Scissor' and get == 'Paper':
print('You win!')
#This will decide the outcome when the computer picks paper.
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
elif cpu == 'Scissor' and get == 'Rock':
print('You lose.')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main(cpu)
if again == 'n' or 'N':
again = False
#This decides the outcome if the computer picks scissors.
def main(cpu,get):# Executes the programs and checks to see if the input is valid.
print('Rock = 1')
print('Paper = 2')
print('Scissor = 3')
again = 'y'
while get < 1:
get = int(input('Enter a valid number.'))
while get > 3:
get= int(input('Enter a valid number.'))
if get == 1:
get = "Rock"
if get == 2:
get = 'Paper'
if get == 3:
get = 'Scissor'
cpu_choice()
compare(cpu,get)
main(cpu,get)
Your cpu_choice should look like this:
def cpu_choice():#This function is for the computer to get a option.
list_option = [1 , 2, 3]
cpu = random.choice(list_option)
if cpu == 1:
cpu = "Rock"
if cpu == 2:
cpu = 'Paper'
if cpu == 3:
cpu = 'Scissor'
return cpu
This is because a return will exit the function so any code behind a return statement in a function will never be executed.
Your main function should look like this:
def main(cpu,get):# Executes the programs and checks to see if the input is valid.
print('Rock = 1')
print('Paper = 2')
print('Scissor = 3')
again = 'y'
while get < 1:
get = int(input('Enter a valid number.'))
while get > 3:
get= int(input('Enter a valid number.'))
if get == 1:
get = "Rock"
if get == 2:
get = 'Paper'
if get == 3:
get = 'Scissor'
compare(cpu,get)
You don't need to declare a cpu in your main function as you already pass a cpu to your main function.
Outside of your functions you will need this:
get = int(input('Enter a number 1 to 3 as your choice.\n'))
cpu = cpu_choice()
main(cpu,get)
Now your main function has all the parameters it needs. Note I placed get = int(input('Enter a number 1 to 3 as your choice.\n')) after the declaration of your functions. This is a common practice making understanding your code much easier.
Qua Optimisation
Pythons random can choose a random element from a list:
Or's can be used to make one elif for if you win and 1 for if you lose.
Considering that you call main() from within compare() it is best for main() to have no parameters but rather get get and cpu in the main function
A while statement can have multiple comparisons.
An optimised code would look like this:
import random
def cpu_choice():
list_option = ["Rock" , "Paper", "Scissor"]
cpu = random.choice(list_option)
return cpu
def compare(cpu,get):
if get == cpu:
print('Its a tie!')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main()
elif cpu == 'Rock' and get == 'Scissor' or cpu == 'Paper' and get == 'Rock' or cpu == 'Scissor' and get == 'Paper':
print('You lose.')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main()
elif cpu == 'Rock' and get == 'Paper' or cpu == 'Paper' and get == 'Scissor' or cpu == 'Scissor' and get == 'Rock':
print('You win!')
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again == 'y' or again == 'Y':
main()
def main():
print('Rock = 1')
print('Paper = 2')
print('Scissor = 3')
get = int(input('Enter a number 1 to 3 as your choice.\n'))
cpu = cpu_choice()
while not 4 > get > 0:
get = int(input('Enter a valid number.'))
if get == 1:
get = "Rock"
if get == 2:
get = 'Paper'
if get == 3:
get = 'Scissor'
compare(cpu,get)
main()
At the bottom, you are calling main with the parameters 'cpu', which is undefined, and 'get', which is defined by user input at the top. This program takes 1 input and prints an output - you don't need to feed the cpu parameter to main since it is generated from what the cpu_choice function returns. Just get rid of that as a parameter and write cpu = cpu_choice() before you call compare, and have cpu_choice() return the cpu value.
you should modify your cpu_choice function to return a value. In addition, your return statement should also be removed, as explained in the comment next to it:
def cpu_choice(): #This function is for the computer to get a option.
list_option = [1 , 2, 3]
cpu = random.choice(list_option)
#return(random.choice(list_option)) #This returns a number, but in your compare code you are comparing strings, so take this line out
if cpu == 1:
cpu = "Rock"
if cpu == 2:
cpu = 'Paper'
if cpu == 3:
cpu = 'Scissor'
return cpu
in your main function, you can set another variable called cpu to the return value of your function called cpu_choice
def main(cpu,get): #Executes the programs and checks to see if the input is valid.
print('Rock = 1')
print('Paper = 2')
print('Scissor = 3')
again = 'y'
while get < 1:
get = int(input('Enter a valid number.'))
while get > 3:
get= int(input('Enter a valid number.'))
if get == 1:
get = "Rock"
if get == 2:
get = 'Paper'
if get == 3:
get = 'Scissor'
cpu = cpu_choice()
compare(cpu,get)
With a few corrections it's working: (read the comments)
import random
def cpu_choice():
list_option = [1 , 2, 3]
cpu = random.choice(list_option)
if cpu == 1:
cpu = "Rock"
if cpu == 2:
cpu = 'Paper'
if cpu == 3:
cpu = 'Scissor'
return cpu # the return goes here
def compare(cpu,get):
# you are using too many checks for again
# I'm moving the again checks out of here
# Moreover, all the results (win, lose) where wrong if you are 'get'
print("You -> " + get + " - " + cpu + " <- CPU")
if get == cpu:
print('Its a tie!')
elif cpu == 'Rock' and get == 'Scissor':
print('You lose!')
elif cpu == 'Rock' and get == 'Paper':
print('You win.')
elif cpu == 'Paper' and get == 'Rock':
print('You lose!')
elif cpu == 'Paper' and get == 'Scissor':
print('You win.')
elif cpu == 'Scissor' and get == 'Paper':
print('You lose!')
elif cpu == 'Scissor' and get == 'Rock':
print('You win.')
def game(): # Don't call it main please, and no need for the arguments
print('Rock = 1')
print('Paper = 2')
print('Scissor = 3')
get = int(input('Enter a number 1 to 3 as your choice.\n'))
while (get < 1) or (get > 3): # No need for two while loops
get = int(input('Enter a valid number.'))
if get == 1:
get = "Rock"
if get == 2:
get = 'Paper'
if get == 3:
get = 'Scissor'
# Or you can use this
# symbols = ["Rock","Paper","Scissor"]
# get = symbols[get-1] # it's better if you don't call both variables 'get'
cpu = cpu_choice() # you need to assign a value to cpu here
compare(cpu,get)
# I put the again code here
again = input('Enter Y or y to play again. Enter N or n to quit.')
if again in ['y','Y']:
game()
else:
print("Bye!")
if __name__ == "__main__": # This is the main
game()
I am very new to programming.
I have to write a Rock Paper Scissors game for my Intro to Programming class. I have a great start but a few issues I don't know how to solve.
I need three different menus. The main menu should ask to 1. Start new game 2. Load game or 3. Quit. Choose 1 or 2 and you input your name then play begins. You are then asked to select 1. Rock 2. Paper 3. Scissors. My game works great but after choosing Rock paper scissors I want a NEW menu to pop up: What would you like to do? 1. Play Again 2. View Statistics 3. Quit. But I have no idea where to put this. I have tried a few different places but it just by passes it and asks for rock paper scissors again.
Then my second issue is, when user selects 1. State new game needs to ask for their name and use their name to save their games to a file. Then when user chooses 2. Load Game, their name will be used to find a file "name.rps" and load their stats to continue to play (stats, round number, name).
Any help is appreciated.
import random
import pickle
tie = 0
pcWon = 0
playerWon = 0
game_round = (tie + playerWon + pcWon) + 1
# Displays program information, starts main play loop
def main():
print("Welcome to a game of Rock, Paper, Scissors!")
print("What would you like to do?")
print ("")
welcomemenu()
playGame = True
while playGame:
playGame = play()
displayScoreBoard()
prompt = input("Press enter to exit")
def welcomemenu():
print ("[1]: Start New Game")
print ("[2]: Load Game")
print ("[3]: Quit")
print("")
menuselect = int(input("Enter choice: "))
print("")
if menuselect == 1:
name = input("What is your name? ")
print("Hello", name, ".")
print("Let's play!")
elif menuselect == 2:
name = input("What is your name? ")
print("Welcome back", name, ".")
print("Let's play!")
player_file = open('name.rps', 'wb')
pickle.dump(name, player_file)
player_file.close()
elif menuselect == 3:
exit()
return menuselect
# displays the menu for user, if input ==4, playGame in the calling function (main()) is False, terminating the program.
# Generate a random int 1-3, evaluate the user input with the computer input, update globals accordingly, returning True
# to playGame, resulting in the loop in the calling function (main()) to continue.
def play():
playerChoice = int(playerMenu())
if playerChoice == 4:
return 0
else:
pcChoice = pcGenerate()
outcome = evaluateGame(playerChoice, pcChoice)
updateScoreBoard(outcome)
return 1
# prints the menu, the player selects a menu item, the input is validated, if the input is valid, returned the input, if
# the input is not valid, continue to prompt for a valid input
# 1 - rock
# 2 - paper
# 3 - scissors
def playerMenu():
print("Select a choice: \n [1]: Rock \n [2]: Paper \n [3]: Scissors")
print("")
menuSelect = input("What will it be? ")
while not validateInput(menuSelect):
invalidChoice(menuSelect)
menuSelect = input("Enter a correct value: ")
return menuSelect
# if the user doesn't input a 1-3 then return false, resulting in prompting the user for another value. If the value
# is valid, return True
# takes 1 argument
# menuSelection - value user entered prior
def validateInput(menuSelection):
if menuSelection == "1" or menuSelection == "2" or menuSelection == "3":
return True
else:
return False
# return a random integer 1-3 to determine pc selection
# 1 - rock
# 2 - paper
# 3 - scissors
def pcGenerate():
pcChoice = random.randint(1,3)
return pcChoice
# evaluate if the winner is pc or player or tie, return value accordingly
# 0 - tie
# 1 - player won
# -1 - pc won
def evaluateGame(playerChoice, pcChoice):
if playerChoice == 1:
print("You have chosen rock.")
if pcChoice == 1:
#tie
print("Computer has chose rock as well. TIE!")
return 0
elif pcChoice == 2:
#paper covers rock - pc won
print("The computer has chosen paper. Paper covers rock. You LOSE!")
return -1
else:
#rock breaks scissors - player won
print("The computer has chosen scissors. Rock breaks scissors. You WIN!")
return 1
elif playerChoice == 2:
print("You have chosen paper.")
if pcChoice == 1:
#paper covers rock - player won
print("The computer has chosen rock. Paper covers rock. You WIN!")
return 1
elif pcChoice == 2:
#tie
print("The computer has chosen paper as well. TIE!")
return 0
else:
#scissors cut paper - pc won
print("The computer has chosen scissors. Scissors cut paper. You LOSE!")
return -1
else: #plyer choice defaults to 3
print("You have chosen scissors")
if pcChoice == 1:
#rock breaks scissors - pc won
print("The computer has chosen rock. Rock breaks scissors. You LOSE!")
return -1
elif pcChoice == 2:
#scissors cut paper - player won
print("The computer has chosen paper. Scissors cut paper. You WIN!")
return 1
else: #pc defaults to scissors
#tie
print("The computer has chosen scissors as well. TIE!")
return 0
# Update track of ties, player wins, and computer wins
def updateScoreBoard(gameStatus):
global tie, playerWon, pcWon
if gameStatus == 0:
tie +=1
elif gameStatus == 1:
playerWon += 1
else:
pcWon += 1
# If user input is invalid, let them know.
def invalidChoice(menuSelect):
print(menuSelect, "is not a valid option. Please use 1-3")
# Print the scores before terminating the program.
def displayScoreBoard():
global tie, playerWon, pcWon
print("Statistics:\nTies:", tie, "\nPlayer Wins:", playerWon, "\nComputer Wins:", pcWon)
print("Win/Loss Ratio:", playerWon/pcWon)
print("Rounds:", tie + playerWon + pcWon)
main()
def play():
playerChoice = int(playerMenu())
if playerChoice == 4:
return 0
else:
pcChoice = pcGenerate()
outcome = evaluateGame(playerChoice, pcChoice)
updateScoreBoard(outcome)
return 1
This is the method we want.
So all you need to do is call the new menu method under updateScoreBoard().
Then under the new menu method.
if(playerChoice == 1)
play();
if else(playeChoice == 2)
stats();
else
quit();
Use '%s.rsp' % name, Not 'name.rsp'. open('name.rsp', 'w') will always open 'name.rsp' evn if name = 'foo'.
I made SPOILER for you!
this code work well and helpful for you. but you have to think enough before see this code
BELOW IS SPOILER CODE
import random
import pickle
#I'll use class for easy load, easy dump.
class GameStatus():
def __init__(self, name):
self.tie = 0
self.playerWon = 0
self.pcWon = 0
self.name = name
def get_round(self):
return self.tie + self.playerWon + self.pcWon + 1
# Displays program information, starts main play loop
def main():
print "Welcome to a game of Rock, Paper, Scissors!"
print "What would you like to do?"
print ""
game_status = welcomemenu()
while True:
play(game_status)
endGameSelect(game_status)
#prompt user's choice and return GameStatus instance
def welcomemenu():
#changed a logic to handle unexpected user input.
while True:
print "[1]: Start New Game"
print "[2]: Load Game"
print "[3]: Quit"
print ""
menuselect = input("Enter choice: ")
if menuselect in [1, 2, 3]:
break
else:
print "Wrong choice. select again."
if menuselect == 1:
name = raw_input("What is your name?: ") # raw_input for string
print "Hello %s." % name
print "Let's play!"
game_status = GameStatus(name) #make a new game status
elif menuselect == 2:
while True:
name = raw_input("What is your name?: ")
try:
player_file = open('%s.rsp' % name, 'r')
except IOError:
print "There's no saved file with name %s" % name
continue
break
print "Welcome back %s." % name
print "Let's play!"
game_status = pickle.load(player_file) #load game status. not dump.
displayScoreBoard(game_status)
player_file.close()
elif menuselect == 3:
print "Bye~!"
exit()
return
return game_status
# displays the menu for user, if input == 4, playGame in the calling function (main()) is False, terminating the program.
# Generate a random int 1-3, evaluate the user input with the computer input, update globals accordingly, returning True
# to playGame, resulting in the loop in the calling function (main()) to continue.
def play(game_status):
playerChoice = int(playerMenu())
#this if statement is unnecessary. playerMenu() already checked this.
#if playerChoice == 4:
# return 0
pcChoice = pcGenerate()
outcome = evaluateGame(playerChoice, pcChoice)
updateScoreBoard(outcome, game_status)
# prints the menu, the player selects a menu item, the input is validated, if the input is valid, returned the input, if
# the input is not valid, continue to prompt for a valid input
# 1 - rock
# 2 - paper
# 3 - scissors
def playerMenu():
print "Select a choice: \n [1]: Rock \n [2]: Paper \n [3]: Scissors\n"
menuSelect = input("What will it be? ")
while not validateInput(menuSelect):
invalidChoice(menuSelect) #I think this function is un necessary. just use print.
menuSelect = input("Enter a correct value: ")
return menuSelect
# if the user doesn't input a 1-3 then return false, resulting in prompting the user for another value. If the value
# is valid, return True
# takes 1 argument
# menuSelection - value user entered prior
def validateInput(menuSelection):
if menuSelection in [1, 2, 3]: # more readable.
return True
else:
return False
# return a random integer 1-3 to determine pc selection
# 1 - rock
# 2 - paper
# 3 - scissors
def pcGenerate():
pcChoice = random.randint(1,3)
return pcChoice
# evaluate if the winner is pc or player or tie, return value accordingly
# 0 - tie
# 1 - player won
# 2 - pc won
def evaluateGame(playerChoice, pcChoice):
#more readable.
rsp = ['rock', 'paper', 'scissors']
win_statement = ['Rock breaks scissors', 'Paper covers rock', 'Scissors cut paper']
# if player win, win_status = 1 (ex. rock vs scissors -> (1 - 3 == -2) -> (-2 % 3 == 1))
# if pc win, win_status = 2
# if tie, win_status = 0
win_status = (playerChoice - pcChoice) % 3
print "You have chosen %s" % rsp[playerChoice - 1]
what_to_say = "Computer has chose %s" % rsp[pcChoice - 1]
if win_status == 0:
what_to_say += " as Well. TIE!"
elif win_status == 1:
what_to_say += ". %s. You WIN!" % win_statement[playerChoice - 1]
else:
what_to_say += ". %s. You LOSE!" % win_statement[pcChoice - 1]
print what_to_say
return win_status
# Update track of ties, player wins, and computer wins
def updateScoreBoard(outcome, game_status):
if outcome == 0:
game_status.tie += 1
elif outcome == 1:
game_status.playerWon += 1
else:
game_status.pcWon += 1
# If user input is invalid, let them know.
def invalidChoice(menuSelect):
print menuSelect, "is not a valid option. Please use 1-3"
# Print the scores before terminating the program.
def displayScoreBoard(game_status):
print ""
print "Statistics:"
print "Ties: %d" % game_status.tie
print "Player Wins: %d" % game_status.playerWon
print "Computer Wins: %d" % game_status.pcWon
if game_status.pcWon > 0:
#if you don't use float, '10 / 4' will be '2', not '2.5'.
print "Win/Loss Ratio: %f" % (float(game_status.playerWon) / game_status.pcWon)
else:
print "Win/Loss Ratio: Always Win."
print "Rounds: %d" % game_status.get_round()
def endGameSelect(game_status):
print ""
print "[1]: Play again"
print "[2]: Show Statistics"
print "[3]: Save Game"
print "[4]: Quit"
print ""
while True:
menuselect = input("Enter choice: ")
if menuselect in [1, 2, 3, 4]:
break
else:
print "Wrong input."
if menuselect == 2:
displayScoreBoard(game_status)
endGameSelect(game_status)
elif menuselect == 3:
f = open("%s.rsp" % game_status.name, 'w')
pickle.dump(game_status, f)
f.close()
print "Saved."
endGameSelect(game_status)
elif menuselect == 4:
print "Bye~!"
exit()
main()
def rps(a, b):
game = { "rp" : 1, "rr" : 0, "rs" : -1,
"ps" : 1, "pp" : 0, "pr" : -1,
"sr" : 1, "ss" : 0, "sp" : -1}
return (game[a + b])
# For example:
print (rps("r", "p"))
This question already has answers here:
Python NameError from contents of a variable
(2 answers)
Closed 8 years ago.
I'm trying to make a simple rock paper scissors game, and I get an error with in the line, guess = input. It says I need to define the function or variable before I use it in this way and I am unsure of how I can do that. This is using Python/JES programming
#import random module
import random
#main function
def main():
#intro message
print("Let's play 'Rock, Paper, Scissors'!")
#call the user's guess function
number = user_guess()
#call the computer's number function
num = computer_number()
#call the results function
results(num, number)
#computer_number function
def computer_number():
#get a random number in the range of 1 through 3
num = random.randrange(1,4)
#if/elif statement
if num == 1:
print("Computer chooses rock")
elif num == 2:
print("Computer chooses paper")
elif num == 3:
print("Computer chooses scissors")
#return the number
return num
#user_guess function
def user_guess():
guess = input ("Choose 'rock', 'paper', or 'scissors' by typing that word. ")
#while guess == 'paper' or guess == 'rock' or guess == 'scissors':
if is_valid_guess(guess):
#if/elif statement
#assign 1 to rock
if guess == 'rock':
number = 1
#assign 2 to paper
elif guess == 'paper':
number = 2
#assign 3 to scissors
elif guess == 'scissors':
number = 3
return number
else:
print('That response is invalid.')
return user_guess()
def is_valid_guess(guess):
if guess == 'rock' or guess == 'paper' or guess == 'scissors':
status = True
else:
status = False
return status
def restart():
answer = input("Would you like to play again? Enter 'y' for yes or \
'n' for no: ")
#if/elif statement
if answer == 'y':
main()
elif answer == 'n':
print("Goodbye!")
else:
print("Please enter only 'y' or 'n'!")
#call restart
restart()
#results function
def results(num, number):
#find the difference in the two numbers
difference = num - number
#if/elif statement
if difference == 0:
print("TIE!")
#call restart
restart()
elif difference % 3 == 1:
print("I'm sorry! You lost :(")
#call restart
restart()
elif difference % 3 == 2:
print("Congratulations! You won :)")
#call restart
restart()
main()
Using raw_input instead of input seems to solve the problem.
guess = raw_input ("Choose 'rock', 'paper', or 'scissors' by typing that word. ")
and also in
answer = raw_input("Would you like to play again? Enter 'y' for yes or 'n' for no: ")
I'm using Python 2.7.x