What's wrong with this if statement - python

I'm teaching myself python with Learn Python the hard way and I've run into a problem on ex36.
I'm at a fairly early stage in development and I can't figure out what's wrong with my if statement. For whatever reason my code never makes it past
elif "1" or "2" in choice and not key.
even if "1" or "2" aren't in the statement. I don't understand why this is happening. Look is fine. When I was using another nested if statement for this the nested statement got past this point, but it got hung up on another point so I moved my initializing variables-Not really sure if that's a thing in python or not--I did move them though-outside of the while loop.
Here's the code in its entirety before I ramble on too much.
I understand that the logic isn't complete and that more than half the code isn't finished, but I need to know why this statement isn't working.
#write function definition statements.
def darkRoom():
door = raw_input(">>> ")
if "1" in door:
lions()
elif "2" in door:
tiger()
elif "3" in door:
bear()
else:
print """A thunderous voice booms through the room exclaiming,
"CHOOSE DOOR 1, 2, OR 3!"""
darkRoom()
def lions():
#naming error somewhere here
keys = False
lions = False #lions are calm if false. They are pissed if true
warning = True
while True:
choice = raw_input(">>> ")
print " %r %r %r" % (keys, lions, warning)
x = "1" or "2" not in choice and not key and lions
if "take" and "key" in choice:
key = True
print """There are two doors behind the angry pride of lions.
Which door are you going to run to and open before the lions eat you?"""
door = raw_input(">>> ")
if "1" in door and key == True:
threeBrickRoads()
elif "2" in door and key == True:
quickSand()
else:
youDie("You take too long to decide which door to take and the lions eat you.")
elif "look" in choice:
print "Looks like you're going to have to take the key from the lions"
#never gets past this statement even when 1 and two not in choice. This is what my question
#is about
elif "1" or "2" in choice and not key:
print "The Door is locked and the lions are starting to stare."
lions = True
print " %r %r %r" % (keys, lions, warning)
print "%r" % choice
#never reaches this point. I don't know why.
elif x and warning:
print """The lions leave the key and start to chase you. Quick get the
key before they catch you"""
warning = False
#Statement never reaches this point. It should
elif x and not warning:
youDie("You take too long to take the key and the lions eat you for it.")
# entering jig in statement should put me here and not at line 46
else:
print """"You quickly realize that doesn't do you any good.
You take another look at your surroundings"""
#don't think I need that while I have the while loop.
#lions()
##def tiger():
##def bear():
##def threeBrickRoads():
##def quickSand():
##def sizePuzzle():
##def riddlesOnWall():
##def wolfSheepCabbage():
##def duckHunt():
##def hangman():
##def goldRoom():
##def oceanShore():
##def winScreen():
def youDie():
print why, """You lay there pondering your mistake as
the last fleeting pulses of life slowly beat out of you."""
#exit(0)
darkRoom()

elif "1" or "2" in choice and not key
This is interpretted as follows ("1" or (("2" in choice) and (not key)))
Since "1" is always true, this is always true. I think what you mean is:
elif choice in ['1', '2'] and not key

Let's have a look at this line:
elif "1" or "2" in choice and not key:
What this line actually states is that it basically requires one of the following two conditions to be True:
if "1" (without anything else)
if "2" in choice and not key
This is a typical mistake if you are a beginner and you can fix this easily if you write it as follows (easiest fix):
elif choice in [1, 2] and not key:
What this means is: If choice is equal to any of the elements contained in the list [1,2] and key is not True.

elif any(x in ["1", "2"] for x in choice) and not key:

Related

Text Game Closes after every command - NOTE: I just started out

print "Welcome to the game. In the game you can 'look around' and 'examine things'."
print "There is also some hidden actions.
print "You wake up."
input = raw_input("> ")
haveKey = False
applesExist = True
if input == "look around":
print "You are in a dusty cell. There is a barrel in the corner of the room, an unmade bed,"
print "a cabinet and chest. There is also a cell door."
elif haveKey == False and input == "use door":
print "The door is locked."
elif haveKey == True and input == "use door":
print "You open the door and immediately gets shot with an arrow. You won, kinda."
elif input == "examine barrel":
print "There is apples in the barrel."
elif applesExist == True and input == "eat apple":
print "Mmmmh, that was yummy! But now there are no apples left..."
applesExist = False
elif applesExist == False and input == "eat apple":
print "sury, u et al aples befur!!1111"
elif input == "examine bed":
print "The bed is unmade, and has very dusty sheets. This place really needs a maid."
elif input == "sleep on bed":
print "You lie down and try to sleep, but you can't because of all the bugs crawling on you."
elif input == "examine chest":
print "There is a key in the chest."
elif input == "take key":
haveKey = True
print "You take the key."
elif input == "examine cabinet":
print "The cabinet is made of dark oak wood. There is a endless cup of tea in it."
elif input == "drink tea":
print "You put some tea in your mouth, but immediately spit it out."
print "It seems it has been here for quite some time."
else:
print "Huh, what did you say? Didn't catch that."
No syntax errors, no errors of any kind. Not. One.
The problem is that after I examine, look around and eat apples the
game closes. How do I fix this? With a While loop?
plz halp
You're obviously very beginner, I won't hammer you about how to do the best architecture. Get used to write code a little first.
If you want to repeat an action, that means a loop (here it's called the main game loop). You code currently takes an input, do a lot of checks to do an action on it, do that action and then... reach the end of the file and stops.
If you wan to go back to the input, you need to enclose all the code you want to repeat in a repetitive code structure, i.e. a loop.
Here is a basic pseudo-code of a game main loop.
playing=True:
while playing:
instruction = takeUserInputOfSomeForm();
if instruction == something:
doStuff()
# etc ...
elif instruction == "quit":
playing=False
You need a loop otherwise when the code hits the bottom of the file Python will exit. http://www.tutorialspoint.com/python/python_loops.htm

changing variables in one function from another function

I'm working on a text based adventure game in python. Nothing super fancy. I want to have a lever in 2 different rooms unlock a gate in a third room. Both levers need to be pulled in order for the gate to be unlocked.
here are the two rooms with the levers.
def SnakeRoom():
choice = raw_input("> ")
elif "snake" in choice:
FirstRoom.SnakeLever = True
print "As you pull the lever... You hear something click down the hall behind you."
SnakeRoom()
elif "back" in choice:
FirstRoom()
else:
dead("Arrows shoot out from the walls. You don't make it.")
def WolfRoom():
choice = raw_input("> ")
elif "wolf" in choice:
FirstRoom.WolfLever = True
print "As you pull the lever... You hear something click down the hall behind you."
WolfRoom()
elif "back" in choice:
FirstRoom()
else:
dead("Arrows shoot out from the walls. You don't make it.")
Here is the room with the gate.
def FirstRoom():
Lever = WolfLever and SnakeLever
choice = raw_input("> ")
if "straight" in choice and Lever != True:
print "You see a large gate in front of you. The gate is locked, there doesn't seem to be any way to open it."
FirstRoom()
elif "straight" in choice and Lever == True:
SecondRoom()
elif "left" in choice:
WolfRoom()
elif "right" in choice:
SnakeRoom()
elif "lever" in choice:
print "WolfLever: %s" % WolfLever
print "SnakeLever: %s" % SnakeLever
print "Lever: %s" % Lever
FirstRoom()
I shortened the code so you don't have to read through all the unnecessary stuff.
My biggest problem is I'm not super familiar with the Python language yet, so I'm not sure how to word everything to find the answers I'm looking for.
edit: Instead of FirstRoom.WolfLever I also tried just using WolfLever, in the body of my code, above Start() I have:
WolfLever
SnakeLever
Lever = WolfLever and SnakeLever
But my functions weren't updating these values. So I tried the FirstRoom. approach.
Credit to #Anthony and the following link: Using global variables in a function other than the one that created them
Globals definitely were the answer (With the exception of using classes). Here's what my WolfRoom() and SnakeRoom() functions look like now:
def WolfRoom():
global WolfLever
choice = raw_input("> ")
elif "wolf" in choice:
WolfLever = True
print "As you pull the lever... You hear something click down the hall behind you."
WolfRoom()
For FirstRoom() I added
global Lever
to the beginning of the function and right before Start() I have
WolfLever = False
SnakeLever = False
this way I have no errors or warnings (Was getting syntax warnings for assigning a value to my levers before declaring them as global) and everything works perfectly.

Trying to return a boolean value from a function

I am trying to program a simple text based game. In order to do this, I am having the user go to three separate rooms to complete a task and receive a piece. In order to do this, I have a value set as False then, upon completion of the room, I have a return statement used to change the Boolean value to True. When all three room functions return a True, then I set that to open a function that progresses the game. As of know, however, the return does not take place, and thus the Boolean values remain unchanged.
Here is an example of one door function:
def door1(incomp1):
if incomp1 == False:
print 'You enter door 1 and find a hideous internet troll.'
print "The troll says, 'LOOK AT THIS LOSER'"
options = ["YOU'RE THE LOSER", "I don't care." , "YOUR MOM IS FAT"]
options2 = [1,2,3]
for x in options:
print "\t :> %s" % x
choice1 = raw_input("What is your response? :>")
if ('loser' in choice1) or ('fat' in choice1):
print "You are sucked into the troll's behaviour and are driven insane"
print "After three days of insanity, you starve to death"
dead()
elif 'care' in choice1:
print 'The troll cannot feed off of your anger.'
print 'The troll starves and you recover one piece of the lever from his stomach.'
change()
entrywayopen()
return incomp1 == True
else:
unknown()
change()
door1(incomp1)
elif incomp1 == True:
print 'You already recovered the piece from room 1.'
entrywayopen()
So, I have incomp1 already at a value of False when the function is called. The user must get the correct answer, in this case the elif statement. At the end, I have it to return incomp1 == True. Yet, the value remains unchanged. My endgame in this room strategy is to return a value of True for the statement if door1(incomp1) and door2(incomp2) and door3(incomp3):. What is causing the Boolean change in value to not be returned?
A little about Python boolean expressions:
every python expression can be evaluated as a boolean
None, False, 0, 0.0, empty strings, lists, tuples and dictionaries are False; most others objects are True
that means: instead of x == True you can usually just write x, in your case: if incomp1:
If you are executing a function and it finishes without hitting a return, a None will be returned implicitly. If you do a boolean comparison on it, it will evaluate as False.
You need to replace "return incomp1 == True" with just "return True". Then call the door1 function like this "incomp1 = door1(incomp1)".
This will change the value of incomp1 to the value returned by the function "True".
You can also replace "elif incomp1 == True:" with a simple "else".
You might also consider adding a .lower() to choice1 = raw_input("What is your response? :>"). This will make it so if the player uses a capital letter in the input it will still function as desired.
def door1(incomp1):
if incomp1 == False:
print 'You enter door 1 and find a hideous internet troll.'
print "The troll says, 'LOOK AT THIS LOSER'"
options = ["YOU'RE THE LOSER", "I don't care." , "YOUR MOM IS FAT"]
options2 = [1,2,3]
for x in options:
print "\t :> %s" % x
#choice1 = raw_input("What is your response? :>")
choice1 = raw_input("What is your response? :>").lower()
if ('loser' in choice1) or ('fat' in choice1):
print "You are sucked into the troll's behaviour and are driven insane"
print "After three days of insanity, you starve to death"
dead()
elif 'care' in choice1:
print 'The troll cannot feed off of your anger.'
print 'The troll starves and you recover one piece of the lever from his stomach.'
change()
entrywayopen()
return True
else:
unknown()
change()
door1(incomp1)
#elif incomp1 == True:
else:
print 'You already recovered the piece from room 1.'
entrywayopen()
incomp1 = door1(incomp1)

Python failing IF STATEMENTS/ Changing Variables

I'm having an issue. Speedy responses would be greatly appreciated! My program is failing IF conditions becuase my functions are not changing the global variable properly for me. They're supposed to, for example, be able to go south and take a key. With that key they can go East and open a locked drawer. Except... they fail the if check to be able to open the drawer.
Thanks in advance! The code blocks in question should be below!
def south():
print ("You can see a key just lying there on the table! What luck!")
choice = raw_input("You better TAKE that!")
if choice == 'TAKE' :
print "You took the key!"
return Key1 == 1, moverooms()
else:
print "You didn't take the key to freedom!?"
south()
def east():
print("You can see a drawer here! Wonder what is inside?")
choice = raw_input("You can MOVEROOMS, or try to USE the drawer and TAKE what's inside...\n ")
if choice == 'USE' :
print "You try to open the drawer... \n"
if Key1 == 1 :
print "You use the key to open the drawer and find a flashlight inside! Better TAKE it!"
Drawer == 1
east()
else:
print ("It's locked! Better find a key...\n")
east()
You really don't want to use global variables, but if you must, your problem seems to be that you're not assigning Key1 = 1 in your TAKE conditional, but returning True or False according to whether or not it already has that value (Key1==1). Note that you need to set it before the return.
Note that if you want to do this (you don't), you'll need to assert global Key at the top of your south() function.
To avoid global variables, return a value for Key1 from south and pass it to east:
def south():
print ("You can see a key just lying there on the table! What luck!")
choice = raw_input("You better TAKE that!")
if choice == 'TAKE' :
print "You took the key!"
Key1 = 1
else:
print "You didn't take the key to freedom!?"
Key1 = 0
return Key1
def east(Key1):
print("You can see a drawer here! Wonder what is inside?")
choice = raw_input("You can MOVEROOMS, or try to USE the drawer and TAKE what's inside...\n ")
if choice == 'USE' :
print "You try to open the drawer... \n"
if Key1 == 1 :
print "You use the key to open the drawer and find a flashlight inside! Better TAKE it!"
Drawer = 1
return Drawer
else:
print ("It's locked! Better find a key...\n")
Drawer = 0
return Drawer
You'll have to handle the logic of the calls to south and east yourself, though.
This might be overkill, but ideally you'll do something along these lines:
class Character(object):
"""
This class represents the player.
It keeps track of found items, opened drawers, etc...
"""
def __init__(self):
# game start: Key not found, drawer not opened.
self.has_key= False
self.has_opened_drawer= False
def go_south(self):
print "You can see a key just lying there on the table! What luck!"
choice = raw_input("You better TAKE that!\n")
if choice == 'TAKE' :
print "You took the key!"
self.has_key= True
else:
print "You didn't take the key to freedom!?"
def go_east(self):
print "You can see a drawer here! Wonder what is inside?"
choice = raw_input("You can MOVEROOMS, or try to USE the drawer and TAKE what's inside...\n")
if choice == 'USE':
print "You try to open the drawer... \n"
if self.has_key:
print "You use the key to open the drawer and find a flashlight inside! Better TAKE it!"
self.has_opened_drawer= True
else:
print "It's locked! Better find a key...\n"
def input_loop(self):
while True:
choice= raw_input('Do you want to go SOUTH or EAST?\n')
if choice=='SOUTH':
self.go_south()
elif choice=='EAST':
self.go_east()
player= Character() # create a Character
player.input_loop() # and let the user control it
Instead of using global variables, you create a Character to store all necessary data, like whether the key was found, or whether the drawer has been opened. That way you won't clutter your global scope with variables.

text based game in python

heres my code
direction = 0
while direction != ("quit"):
direction = input("> ")
if direction[0:4] != "quit" and direction != "go north" and direction != "go south" and direction != "go east" and direction != "go west" and direction != "go up" and direction != "go down" and direction[0:4] != "look":
if direction[0:2] == "go" and direction[3:] == (""):
print("please tell me more")
else:
print("huh?")
elif direction[0:1] == "go" and direction != "north" and direction != "south" and direction != "east" and direction != "west" and direction != "up" and direction != "down":
print ("please tell me more")
elif direction[0:4] == "quit":
print ("OK ... but a small part of you may never leave until you have personally saved Muirfieland from the clutches of evil .. Bwahahahahahah (sinister laugh).")
elif direction[0:4] == "look":
print ("You see nothing but endless void stretching off in all directions ...")
else:
print ("You wander of in the direction of " + direction)
im trying to add this into my code
if the first word is recognised but the second is not, it will respond with :
"sorry, im afraid i cant do that"
im just having troubles getting that one bit into my code, any help will be appreciated thanks.
So quick analysis... You're making text parser which works as following:
Get first word of "command", if we don't know word user used invalid input -> inform and restart
If user used known "command", parse its arguments (like: go north, go south) and let "nested" function take care of argument
Note that "main parsing function" doesn't need to know whether arguments for go() are valid, it just delegates responsibility for validation to go().
So I think you should build code (class) like this:
class Game:
# Initialize internal variables, method automatically called on g = Game()
def __init__(self):
self._exit = False
# Array of known commands, used in run, basically maps commands
# to function and it says: if will get 'go' execute self._go
self._commands = {
'go': self._go,
'quit': self._quit
}
# Array of go sub commands, used by _go
self._commands_go = {
'north': self._go_north
# ...
}
# Mathod for parsing command, if it gets "comamnd" returns ("command",None)
# if "command arg1 arg2" returns ("command", "arg1 arg2")
#staticmethod
def parse_command(string):
string = str(string)
index = string.find(' ')
if index < 0:
return (string, None)
return (string[:index], string[index+1:])
# This is main method; the only one which should be called from outside
# It will just read data from input in never ending loop and parse commands
def run(self):
while not self._exit:
src = input('> ')
(command,args) = Game.parse_command( src)
# Do we have this command, execute it
if command in self._commands:
self._commands[command](args)
else:
print( 'I\'m sorry I don\'t known command {}, try one of these:'.format(command))
print( '\n'.join( self._commands.keys()))
#######################################################
# All game commands go here
#######################################################
def _quit(self,args):
self._exit = True
print( 'Bye bye')
# Movement handling, will get executed when user types 'go ...' nad '...' will be in arg
def _go(self,args):
# No argument
if args is None:
print( 'Go excepts one of these:', '; '.join( self._commands_go.keys()))
return False
# Split sub command anr arguments
(command,args) = Game.parse_command(args)
if command not in self._commands_go:
print( 'Go excepts one of these:', '; '.join( self._commands_go.keys()))
return False
if args is not None:
print( 'Too many arguments for go')
return False
self._commands_go[command](args)
return True
# Go north
def _go_north(self, args):
print( 'Going north')
game = Game()
game.run()
Which would allow you to:
build complex nested commands
build nice and readable commands hierarchy (inventory item 123 update use potion 345) instead of hardly readable set of complex conditions
build function aliases go north can be aliased as gn by adding 'gn': self._go_north to _commands
build reusable arguments parsing (item_id, action, args) = self._parse_item_action(args)
take advantages of object oriented programming (no global variables, everything will be class attribute, lower risk of accidental variables overwriting)
And if you need to parse goasdf as go you can just simply:
for i in self._commands:
if input.startswirh( i):
return self._commands[i](...)
print('Invalid command')
return False
Note: I haven't tested the code, it's just out of my head.
Your code looks quite confusing to me, here is just a simpler version of your code:
flag = 0
count = 0
direction = 0
while direction != ("quit"):
direction = input("> ")
count += 1
if recognised and count == 1: # word is recognised
flag = 1
print "whatever you want..."
elif (not recognised) and count == 2 and flag == 1:
flag = 0
print "sorry, im afraid i cant do that"
else:
flag = 1
print "second is recognised or whatever you want..."
In my code, I've set a flag if first guess is recognised and incremented the count also. On second guess, I'm just checking the flag and count's value.
Not very relative with your code but, When you could instead get the user input, split it so it turns into a list and compare the first word then the second so it could be something like
user = user_input("> ")
user = user.split()
if user[0] == "look"
if user[1] == "left"
do something
if user[1] == "right"
do something
else
print ("sorry, im afraid i cant do that")
Not sure if this is what your looking for though
Simply, I think you need to learn more code to make things a lot easier for yourself here, though maybe classes are a bit much, and I don't mean this in an insulting way.
As a simple start, I'd suggest using the in keyword rather than ==.
For example:
if "north" in direction:
do something
This will "do something" if the input is North, NORTH, go North, go north please and so on.
To solve your issue therefore your code could use something like this:
input = ("> ")
if "go" in input and not ("north" in input and "south" in input...):
print "That is not a direction you can go in."
And so on. The "and not (...)" section can be rewritten much neater but I wrote it as-is to show what is happening easier.
truthcase = None
directions = ["north", "south", ...]
for i in directions:
if i not in input:
continue
else:
truthcase = True
truthcase = False
if "go" in input and not truthcase:
print something
Hopefully this helps.

Categories

Resources