Dragon game not working, says defined variable is undefined - python

I am making a game that has you choose from three caves, and each one has a dragon in it. When I run this program, it refuses to run, and says that potatocave is undefined. I am using python 3. I need to know why it will not accept potatocave as defined, what I am doing wrong, and if there is a simpler way of doing this.
EDIT: I ran it again and it says that chosenCave is undefined.
Traceback error says:
Traceback (most recent call last):
File "C:\Python33\Projects\Dragon.py", line 32, in <module>
if chosenCave == str(friendlyCave):
NameError: name 'chosenCave' is not defined
import random
import time
time.sleep (3)
def displayIntro():
print('You are in a land full of dragons. In front of you,')
print('you see three caves. In one cave, the dragon is friendly')
print('and will share his treasure with you. Another dragon')
print('is greedy and hungry, and will eat you on sight.')
print('The last dragon is a Potarian and gives free potatoes.')
def chooseCave():
cave = ''
while cave != '1' and cave != '2' and cave != '3':
print('Which cave will you go into? (1, 2 or 3)')
cave = input()
return cave
def checkCave(chosenCave):
print('You approach the cave...')
time.sleep(2)
print('It is dark and spooky...')
time.sleep(2)
print('A large dragon jumps out in front of you! He opens his jaws and...')
print()
time.sleep(2)
friendlyCave = random.randint(1, 3)
potatocave = random.randint(1, 3)
while potatocave == friendlyCave:
potatocave = random.randint(1, 3)
if chosenCave == str(friendlyCave):
print('Gives you his treasure!')
elif chosenCave == str(potatocave):
print ('Millions of potatoes rain from the sky.')
else:
print('Gobbles you down in one bite!')
playAgain = 'yes'
while playAgain == 'yes' or playAgain == 'y':
displayIntro()
caveNumber = chooseCave()
checkCave(caveNumber)
print('Do you want to play again? (yes or no)')
playAgain = input()
P.S This was not the final version, I just used a potato cave as a placeholder to figure out the concept of three caves instead of my original two.

Well, the error message says it all: you haven't defined chosenCave by the moment you are trying to compare it to str(friendlyCave), i.e. line 32.
Just imagine you're the interpreter and work through your script from the beginning. Your course of action would be:
import random, import time, sleep for 3 seconds;
as a result, random and time are now recognized names.
define functions displayIntro, chooseCave, checkCave; those are now also known names referring to the respective functions.
assign friendlyCave and potatocave. Reassign the latter in a loop.
compare chosenCave to str(friendlyCave)... wait, what chosenCave?
But, as DSM notes, if lines 28-37 were indented as part of the body of checkCave function, everything would work just fine:
def checkCave(chosenCave):
print('You approach the cave...')
time.sleep(2)
print('It is dark and spooky...')
time.sleep(2)
print('A large dragon jumps out in front of you! He opens his jaws and...')
print()
time.sleep(2)
friendlyCave = random.randint(1, 3)
potatocave = random.randint(1, 3)
while potatocave == friendlyCave:
potatocave = random.randint(1, 3)
if chosenCave == str(friendlyCave):
print('Gives you his treasure!')
elif chosenCave == str(potatocave):
print ('Millions of potatoes rain from the sky.')
else:
print('Gobbles you down in one bite!')

Related

my code is not working and it only says syntax error

i tried couple of things but does not work. the problem is in the 11th line(that's what python said). i am still 14 and do not have a big knowladge on programing. hope i can get some help
def crowbar():
print("nice, so you picked the crowbar, and now you have to get out of the car")
randomNum = random.randint(1,10)
if randomNum == [2,4,6,8,10]:
print(" shoo, those 2 people are walking away. now it's the time to get out of here")
elif randomNum == [1,3,5,7,9]:
print("they are coming at your direction. you have to do something and fast")
choise2 = int(input("""
1)hit them with the crowbar
2)pretent that you are still unconscious"""))
if choise2 == 1: #the problem has something to do with this line
print("ok")
elif choise2 == 2:
print("not ok")
I just refactored your code and fixed several things. The program should run without any problems.
I inline commented the issues and refactorings I did:
#Added the import statement to make sure code is runnable if copy&pasted
import random
def crowbar():
print("nice, so you picked the crowbar, and now you have to get out of the car")
randomNum = random.randint(1,10)
#Use the "x in list" expression as it is the most readable and pythonic way
if randomNum in [2,4,6,8,10]:
print("shoo, those 2 people are walking away. now it's the time to get out of here")
#Just use else for the second case, as this has the same behaviour without boiler plate
else:
print("they are coming at your direction. you have to do something and fast")
choice2 = 0
#Defensive programming: As long as neither 1 nor 2 was pressed, the input request will loop forever
while choice2 not in [1, 2]:
print("What do you want to do?")
choice2 = int(input("""
1)hit them with the crowbar
2)pretent that you are still unconscious\n"""))
#I had no error here to be honest as you said. It just worked.
if choice2 == 1:
print("ok")
elif choice2 == 2:
print("not ok")
if __name__ == "__main__":
crowbar()
Alright, a few things to note:
To check if a value is inside of a data structure, use is in instead of ==.
Variable names should be descriptive and follow the lower_case_with_underscores style.
Your random number generation can be simplified, since currently are you need is a 50/50 chance.
You should probably be using a solid IDE, which would alert you to the naming issues and the incorrect membership testing.
Here is your program, I refactored it quite a bit.
import random as rand
def crowbar():
print('You pick up the crowbar. Now you have to get out of the car.')
random_num = rand.random()
if random_num > 0.5:
print('Fortunately, those 2 people are walking away. You can get away safely.')
else:
print('They are moving towards you, you have to react quickly.\nYou decide to...\n(1) Hit them with the '
'crowbar.\n(2) Pretend that you are still unconscious.')
choice = input('Your choice (1 | 2): ')
if choice == '1':
print('Ok.')
elif choice == '2':
print('Not ok.')
else:
print(f'Error! Incorrect input: {choice}')
crowbar()
Explanations:
As mentioned above, I simplified the random number generation.
Variable names have been improved.
I fixed as much of the grammar, syntax and overall writing as I could.
The program now verifies the input. I also got rid of the unnecessary conversion to int.
Your indentation is incorrect and you are missing parenthesis in choice2 = ...
Also you need if randomNum in [2,4,6,8,10]: and if randomNum in [1,3,5,7,9]:
This works fine
def crowbar():
print("nice, so you picked the crowbar, and now you have to get out of the car")
randomNum = random.randint(1,10)
if randomNum in [2,4,6,8,10]: # list here
print(" shoo, those 2 people are walking away. now it's the time to get out of here")
elif randomNum in [1,3,5,7,9]: # list here
print("they are coming at your direction. you have to do something and fast")
choise2 = int(input("""
1)hit them with the crowbar
2)pretent that you are still unconcious""")) # parethesis here
if choise2 == 1: # corrected indentation here
print("ok") # corrected indentation here
elif choise2 == 2: # corrected indentation here
print("not ok") # corrected indentation here

Python not importing data structure [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm trying to create a text-based game. I've made a basic/generic intro and now it's getting long so I want to create a new file so that I can add things like armor and weapons. When I went to try to import 'my_character' it gave me an error so I went to research this problem and I found this, so I tried it. I just got an error message saying it wasn't define (similar to the error below). This is the intro part named intro:
# Date started: 3/13/2018
# Description: text based adventure game
import time
def display_intro():
print('It is the end of a 100 year war between good and evil that had\n' +
'killed more than 80% of the total human population. \n')
time.sleep(3)
print('The man who will soon be your father was a brave adventurer who \n'
+ 'fought for the good and was made famous for his heroism. \n')
time.sleep(3)
print('One day that brave adventurer meet a beautiful woman who he later \n'
+ 'wed and had you. \n')
time.sleep(3)
def main():
display_intro()
main()
gen = input('\nYour mother had a [Boy or Girl]: ')
name = input("\nAnd they named you: ")
print("You are a {} named {}".format(gen, name))
chara_class = None
# Assigning points Main
my_character = {
'name': name,
'gender': gen,
'class': chara_class,
'strength': 0,
'health': 0,
'wisdom': 0,
'dexterity': 0,
'points': 20
}
# This is a sequence establishes base stats.
def start_stat():
print("\nThis is the most important part of the intro")
time.sleep(3)
print("\nThis decides your future stats and potentially future gameplay.")
time.sleep(4)
print("\nYou have 20 points to put in any of the following category: Strength, Health, Wisdom, or Dexterity.\n"
)
def add_character_points(): # This adds player points in the beginnning
attribute = input("\nWhich attribute do you want to assign it to? ")
if attribute in my_character.keys():
amount = int(input("By how much? "))
if (amount > my_character['points']) or (my_character['points'] <= 0):
print("Not enough points!!! ")
else:
my_character[attribute] += amount
my_character['points'] -= amount
else:
print("That attribute doesn't exist! \nYou might have to type it in all lowercase letters!!!")
def remove_character_points():
attribute = input("\nWhich of the catagories do you want to remove from? ")
if attribute in my_character.keys():
amount = int(input("How many points do you want to remove? "))
if amount > my_character[attribute]:
print("\nYou are taking away too many points!")
else:
my_character[attribute] -= amount
my_character['points'] += amount
else:
print(
"That attribute doesn't exist! \nYou might have to type it in all lowercase letters!!!")
def print_character():
for attribute in my_character.keys():
print("{} : {}".format(attribute, my_character[attribute]))
playContinue = "no"
while playContinue == "no":
Continue = input("Are you sure you want to continue?\n")
if Continue == "yes" or "Yes" or "y":
playContinue = "yes"
start_stat()
add_character_points()
elif Continue == "n" or "No" or "no":
main()
running = True
while running:
print("\nYou have {} points left\n".format(my_character['points']))
print("1. Add points\n2. Remove points. \n3. See current attributes. \n4. Exit\n")
choice = input("Choice: ")
if choice == "1":
add_character_points()
elif choice == "2":
remove_character_points()
elif choice == "3":
print_character()
elif choice == "4":
running = False
else:
pass
def story_str():
print(
"\nYou were always a strong child who easily do physical labor and gain lots of muscle."
)
time.sleep(3)
print("\nYou regularly trained with your dad who was also a skilled swordsman.")
time.sleep(3)
print("\nAs you grew into an adult, you're swordsmanship improved drastically.")
time.sleep(3)
print("\nOnce old enough, you joined the local guild as a warrior.")
time.sleep(3)
def story_dex():
print("\nYou were a sly child. You would always be stealing from other people and with"
+ "\nconstant practice you became proficient at thieving.")
time.sleep(3)
print("\nCombined with the skill of knives and short-blades, you became an extremely deadly assassin."
)
time.sleep(3)
print("\nOnce old enough, you joined the local guild as an assassin.")
time.sleep(3)
def story_wis():
print("\nYou grew up as a very intellegent child. You read books everyday and realized that magic"
+ "is the best offensively and defensively.")
print("\nYou grew up and attended the best magic school avalible and graduated."
)
print("\nYou soon went to the local guild and joined as a wizard.")
run_story = False
while run_story:
if my_character['strength'] >= 13:
story_str()
chara_class = 'Warrior'
run_story = True
else:
continue
if my_character['dexterity'] >= 13:
story_dex()
chara_class = 'Assassin'
run_story = True
else:
continue
if my_character["wisdom"] >= 13:
story_wis()
chara_class = 'Mage'
run_story = True
else:
continue
The command I have typed on part1 is to try to import my_character is:
from intro import my_character
print(my_character)
I have been trying to import my_character but it comes up as:
Traceback (most recent call last):
File "C:/Users/user/Desktop/part1.py", line 5, in <module>
my_character
NameError: name 'my_character' is not defined
The original file was named "intro" and the new one is named "part1". Do I need to do the 'if name == "__main"' thing? If so, what does that do?
Check for:
1) is the file name my_character.py
2) you have imported it as my_character
3) my_character is in the main python directory (if you are importing in interpreter)

The script is not assigning points to the attribute

I'm trying to create a text-based adventure game and all is going well until I encountered a problem with assigning points to attributes. I've been using this website to help with the process but realized that it might be in Python 2. Here's all that I've done so far code:
#Date started: 3/13/2018
#Description: text-based adventure game
import random
import time
def display_intro():
print('It is the end of a 100-year war between good and evil that had \n' +
'killed more than 80% of the total human population. \n')
time.sleep(3)
print('The man who will soon be your father was a brave adventurer who \n' +
'fought for the good and was made famous for his heroism. \n')
time.sleep(3)
print('One day that brave adventurer meet a beautiful woman who he later \n' +
'wed and had you. \n')
time.sleep(3)
def get_gender(gen=None):
while gen == None: # input validation
gen = input('\nYour mother had a [Boy or Girl]: ')
return gen
def get_name(name = None):
while name == None:
name = input("\nAnd they named you: ")
return name
def main():
display_intro()
gender_num = get_gender()
charater_name = get_name()
print("You entered {} {}.".format(gender_num, charater_name))
if __name__ == "__main__":
main()
character_name = get_name()
# Assignning points Main
my_character = {'name': character_name, 'strength': 0, 'wisdom': 0, 'dexterity': 0, 'points': 20}
#This is a sequence establises base stats.
def start_stat():
print("\nThis is the most important part of the intro\n")
time.sleep(3)
print("This decides your future stats and potentially future gameplay.")
time.sleep(4)
print("\nYou have 20 points to put in any of the following category:
Strength, Health, Wisdom, or Dexterity.\n")
def add_charater_points(): # This adds player points in the beginnning
attribute = input("\nWhich attribute do you want to assign it to? ")
if attribute in my_character.keys():
amount = int(input("By how much?"))
if (amount > my_character['points']) or (my_character['points'] <= 0):
print("Not enough points!!! ")
else:
my_character[attribute] += amount
my_character[attribute] -= amount
else:
print("That attribute doesn't exist!!!")
def print_character():
for attribute in my_character.keys():
print("{} : {}".format(attribute, my_character[attribute]))
playContinue = "no"
while playContinue == "no":
Continue = input("Are you sure you want to continue?\n")
if Continue == "yes" or "Yes" or "y":
playContinue = "yes"
start_stat()
add_charater_points()
else:
display_intro()
gender_num = get_gender()
charater_name = get_name()
running = True
while running:
print("\nYou have {} points left\n".format(my_character['points']))
print("1. Add points\n2. Remove points. \n3. See current attributes. \n4. Exit\n")
choice = input("Choice: ")
if choice == "1":
add_charater_points()
elif choice == "2":
pass
elif choice == "3":
print_character()
elif choice == "4":
running = False
else:
pass
And here's what happens when I run it:
It is the end of a 100-year war between good and evil that had
killed more than 80% of the total human population.
The man who will soon be your father was a brave adventurer who fought for
the good and was made famous for his heroism.
One day that brave adventurer meet a beautiful woman who he later wed and
had you.
Your mother had a [Boy or Girl]: boy
And they named you: Name
You entered boy Name.
And they named you: Name
Are you sure you want to continue?
yes
This is the most important part of the intro
This decides your future stats and potentially future gameplay.
You have 20 points to put in any of the following category: Strength,
Health, Wisdom, or Dexterity.
Which attribute do you want to assign it to? strength
By how much? 20
You have 20 points left
1. Add points
2. Remove points.
3. See current attributes.
4. Exit
Choice: 3
name : Name
strength : 0
wisdom : 0
dexterity : 0
points : 20
You have 20 points left
1. Add points
2. Remove points.
3. See current attributes.
4. Exit
Choice:
Oh, and prompt for the name of the play goes again twice for some reason. Also, what does the my_character.keys() under def add_charater_points() mean? Since I just started to learn to code python, if there are any other tips you guys can give me it would be greatly appreciated.
The last two lines of this snippet
if (amount > my_character['points']) or (my_character['points'] <= 0):
print("Not enough points!!! ")
else:
my_character[attribute] += amount
my_character[attribute] -= amount
add the character points to the attribute, and immediately subtract them again. I think you might mean
my_character['points'] -= amount
Your repeated prompt is probably because you have a whole lot of code that logically seems to belong in function main() but is coded to run after main() finishes.

Python: My code repeats itself after it should have finished

I am writing a rock, paper, scissors game in Python but my code doesn't work as it should. I'm new to Python so please let me know if my code isn't formatted corectly. The game runs fine, assuming you enter one of the already existing answers. However, if you enter one that is different, the code seems to loop randomly after the 'end()' function is executed.
Here is my code:
# imports needed files
from random import randint
import time
# creates a function that ends the game
def end(cpuScore,playerScore):
time.sleep(1)
cont = input("Would you like to play again? (y or n)\n")
if cont=="y":
time.sleep(1)
start()
else:
print("Well... That's a bit rude.")
# creates a function to play the game
def rps(cpuScore,playerScore,num):
# loops code 3 times (unless 'num' is different)
for x in range(num):
num-=1
# creates options
options = ["rock","paper","scissors"]
# picks a random choice for cpu
cpu = options[randint(0,2)]
# asks the player to choose
player = input("rock, paper or scissors?\n")
# why not gun?
if player=="gun":
result = "w"
elif player==cpu:
result = "d"
elif player=="rock":
if cpu=="paper":
result = "l"
if cpu=="scissors":
result = "w"
elif player=="paper":
if cpu=="scissors":
result = "l"
if cpu=="rock":
result = "w"
elif player=="scissors":
if cpu=="rock":
result = "l"
if cpu=="paper":
result = "w"
# if they choose something other than rock, paper, scissors or gun
else:
print("That's an invalid input!")
# adds one to num so that this round is not counted as one of the 3
num+=1
# plays the game again with the amount of rounds remaining
rps(cpuScore,playerScore,num)
# tells the player how they did
if result=="w":
playerScore+=1
time.sleep(1)
print("Fine! You win! Your silly " + player + " beat my " + cpu + "!!!")
if result=="l":
cpuScore+=1
time.sleep(1)
print("Ha! Sucker!! My epic " + cpu + " smashed your measly " + player + "!!!")
if result=="d":
time.sleep(1)
print("Ah! We drew by both choosing %s! Like they say, great minds think alike!" % cpu)
# announces the scores
print("You are on %s and the computer is on %s!" % (playerScore,cpuScore))
# ends the game after 3 rounds
end(cpuScore,playerScore)
# creates the funtion that sets the variables and starts the game
def start():
result=""
cont=""
cpuScore=0
playerScore=0
rps(cpuScore,playerScore,3)
# begins the game
start()
Thanks
Basically your rps function loops num times, with num = 3 initially. If the user enters an incorrect input, you call back the function, which starts the whole process again, in a new context, for num+1 times.
Thus if you answer wrong the first time you have at least six games to play: four new added and the two initial ones you didn't try to play.
My advice try first to do a program that do one and only one iteration of the rock-paper-scissor game. Adding more iteration is a simple fact of adding a global loop.

Beginner to Python - why the heck is my while loop not working?

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

Categories

Resources