I am creating a text-RPG taking inspiration from older text adventures where the player enters an English command; such as 'pick up sword' and the like.
I have established a simple; enter 'A' to do this and enter 'B' to do this, but I would like to expand my system for more freedom.
I need to create a system that; when the player types in a command the program picks out key words.
I assume this would be achievable via the 'in' command.
Here is my code:
print "What would you like to do??"
input_loop_sleep = str('')
choice_sleep = raw_input(str('>>>'))
loop_sleep = False
table_time = False
bed_time = False
error_time = False
while loop_sleep == False:
if str('sleep') in choice_sleep or str('bed') in choice_sleep or str('goodnight') in choice_sleep or str('Sleep') in choice_sleep or str('tired') in choice_sleep:
while bed_time == False:
print "you decide to go back to sleep"
time.sleep(1)
print "..."
time.sleep(1)
print ""
time.sleep(1)
print "darkness"
time.sleep(1)
print ""
print "you wake up..."
time.sleep(1)
print "it is now 9:15am"
time == int(9.15)
time.sleep(1)
print "You are standing in your room, slightly more refreshed."
time.sleep(1)
print "there is a table with some things on it, stairs, and a wardrobe... with the doors wide open..."
time.sleep(1)
print "that's strange... you swear that they were shut when you went to sleep..."
break
else:
bed_time == True
break
bed_loop_choice = raw_input('>>>')
elif str('bedside') in choice_sleep or str('table') in str(choice_sleep):
while table_time == False:
print "You rub your eyes and pick up some belongings from a"
print "bedside table."
time.sleep(1)
print "Map added!"
time.sleep(1)
print "100 gold added!"
time.sleep(1)
print "Leather Bag added!"
cash == int(100)
time.sleep(1)
Map == str('map of', str(province))
Inventory == [str(Map)]
container == str('leather bag')
print "your", str(container), str("contains a"), str(Map), str('and'), str(cash)
break
else:
table_time == True
break
else:
print "invalid command!"
when I run the code, no matter what I type in it always goes with the 'sleep' option.
I probably just made some simple mistake!
can you please help me with what I did wrong and how I can fix it.
To answer your question about why the sleep loop is repeated all the time:
You're controlling the loop via
while bed_time == False:
but you never set bed_time to True in your loop (only in the else clause, but that clause is only executed when the loop exits normally, not when it's exited via break, as you're now doing - therefore bed_time will never change).
Furthermore, direct comparisons to a boolean value are usually frowned upon. The idiomatic way (in most languages, not just Python) would be while not bedtime:.
You should probably read some beginners' programming books and/or the Python tutorial before embarking on such a big project. There are several issues in your code that convey the impression that you really need to get a grasp on some basic programming principles and Python idioms.
For example,
int(9.15)
is not a good way to store a time - the result will be 9.
You're then using time == int(9.15), which means "compare the module time to the integer 9". I guess you meant time = int(9.15) which is already bad for the reasons stated above, but there would be even another problem: You would be overwriting the module name time, which will cause the subsequent time.sleep(1) command to fail with an AttributeError.
There's no need for most str() calls in your code because you're using it on objects that already are strings. Where you're not, it's incorrect: str('map of', str(province)) will raise TypeError (str takes only one argument).
You're using uppercase variable names for objects that aren't class instances.
Etc., etc...
I think this should be sufficient to sort out the problem
In [1]: str('bed') in "bedside"
Out[1]: True
So when you write bedside it gets inside the sleep option if condition and hence you are getting wrong answer .
You should write :
if str('bed') == choice_sleep or *other conditions* :
then got inside the sleep option
P.S: I am assuming you have imported the time module .
P.P.S: I checked the code with entering table it is working fine .
Related
I would like to know why this code does not work; it should exit at the "GAME OVER" point, but it continues to my next defined function.
I have tried other variations on exit() such as: sys.exit(), quit() and SystemExit.
run_attack = input("What do you do: Run/Attack\n")
run = ['run', 'Run', 'RUN']
attack = ['attack', 'Attack', 'ATTACK']
run_attack = 1
while run_attack < 10:
if run_attack == ("run") or ("Run") or ("RUN"):
print ("You turn to run from the wolf but he quickly pounces
you...")
time.sleep(2)
print("You are quickly ripped apart and just about get to see
yourself be eaten.")
print("GAME OVER")
break
exit() #This is where the game should exit, yet after input it
continues to the next function
elif run_attack == ("attack") or ("Attack") or ("ATTACK"):
print("You brace yourself for a bite and have no time to reach"
"for any kind of weapon form your backpack.")
time.sleep("2")
input("You clock the dog hard, twice on the muzzle.")
print("The dog recoils in pain and retreats back to the woods.")
print("You quickly start running as you assume there will be a den in the woods.")
break
else:
input("Type Run or Attack...")
You have several problems in your code; why did you write this much without testing it?
First, you read the user's input, immediately replace is with 1, and then try to test it (incorrectly) as if it were still a string. Your posted code has several syntax errors, so I have some trouble reproducing the problem. However, the immediately obvious problem is here:
break
exit() # This is where ...
You can't get to the exit statement, as you break from the loop just before you can get there.
I strongly recommend that you back up to a few lines and use incremental programming: write a few lines at a time, debug those, and don't continue until they do what you want.
Also look up how to test a variable against various values. Your if statement is incorrect. Instead, try the list inclusion you're trying to set up:
if run_attack in run:
...
elif run_attack in attack:
...
I took the liberty of rewriting your whole program to show you a few things wrong with it and a few tricks. I've done it without the loop, since you never use it anyway... you can add the while loop later once you've mastered it, but you should really go back to basics on some things here:
run_attack = input("What do you do: Run/Attack\n")
if run_attack.lower() == "run":
print("""some
stuff
with
multiple
lines and GAME OVER""")
exit()
elif run_attack in ("attack", "Attack", "ATTACK"):
print("""some
stuff
with
multiple
lines""")
else:
input("Type Run or Attack...")
Some notes:
Using """ for strings enables you to write multiple lines without multiple print statements
Using str.lower() on strings makes everything easy to compare because you only have to compare it to the lowercase version of each string. However for attack you can notice I used a different inclusion test, without multiple conditions. Either way works here.
Like the other answer here (and many comments), you should use only exit() to leave the program entirely, or only break to exit the loop and continue to other code that's beneath the entire loop.
When you rewrite your loop, with a condition like while number_of_turns < 10 don't forget to add 1 to the number of turns on each loop, otherwise that condition is always True and you'll have an infinite loop...
I'm actually quite surprised this code had any resemblance to the behavior you expected from it, my suggestion is to go back over to the basics of python, learn loops, string methods, basic commands. The rest is already said in the other answer here (which is better than mine, frankly) just wanted to add some ideas.
The second rule for If-Statements here, which has me confused states that:
If this else should never run because it doesn't make sense, then you must use a die function in the else that prints out an error message and dies, just like we did in the last exercise. This will find many errors.
Here's the code from the last exercise:
def dead(why):
print why, "Good job!"
exit(0)
def start():
print "You are in a dark room."
print "There is a door to your right and left."
print "Which one do you take?"
choice = raw_input("> ")
if choice == ‘left’:
bear_room()
else:
dead(‘You stumble around the room until you starve.’)
Is it essentially saying that you must successfully terminate the program if a condition is not met?
Yes, the idea is:
import sys
def die(msg):
print msg
sys.exit(1)
if condition:
# do stuff
else:
die('This cannot happen!')
You could also use an assert instead, or raise an exception, or anything else that would fail catastrophically. This helps you validate at runtime that the clause you didn't expect to execute, really didn't run.
IMHO you shouldn't get too hung up on how this die is done, exactly. The important point the referred text tries to make is that when you're sure some condition is true, you might as well assert it forcefully so that you can catch runtime bugs.
The guide is trying to show you that you can see the choice that a user gives when it's something that you don't check for in your if statement. If your else looks like:
else:
dead(choice)
You will be able to see what the user input that you didn't expect.
The problem is that the syntax only allows for "Left", when the prompt allows entry of anything. In other words, if I enter "Bob", I will starve. I should be trapping for anything that isn't appropriate and "die"ing at that point (or helping the user make an appropriate decision).
This is an attempt at teaching error handling and die. You would rewrite it such that you allow accurate entry or die (no exit). If you don't choose left, there is no other choice even though the prompt states there are two choices.
If you truly expect only 'left' to be added, a better way of checking for unexpeted input would be
if choice != ‘left’:
dead(‘You stumble around the room until you starve.’)
bear_room()
That way you still validate that the input is what you expected, but it saves indentation and space for the main logic.
I'm trying to create a small, basic guessing game in python, something like Text Twist. Here's the code:
while game_running == True:
if (tries_left != 0):
print "Tries left: " + str(tries_left)
chosen_text = text_list[picker(text_length)]
scrambled_text = scrambler(chosen_text)
print "Guess the word/s: " + scrambled_text
guess_text = raw_input("Your answer (space included): ")
if (chosen_text == guess_text):
print "Congratulations! You guessed correctly!"
game_running = False
else:
tries_left-=1
else:
print "LOL. You dun goofed son. Terminating like SkyNet..."
game_running = False
Out of sight functions:
picker - basically a randomizer
scrambler - scrambles the words. In progress and not yet implemented.
You have 3 tries to guess correctly, or the app terminates. If you guessed correctly, the app displays a message, then terminates. Sounds simple enough.
The Problem:
I could not get this to work:
if (chosen_text == guess_text):
Even though I'm 100% sure (via print chosen_text) that I guessed it right.
What I Tried:
I tried reversing the order, putting str() around them, and even reversing the flow of the if and else, using is instead of ==, and removing the tries function, fwiw.
Nothing could get it to go true...
...unless I hard-code chosen_text, and guess that correctly.
Am I missing something?
You probably want to insert some debugging code:
print repr(chosen_text)
print repr(guess_text)
This will show you exactly what two strings you are dealing with. The repr function will put quotes around the strings, and let you identify whether there are unexpected spaces or other difficult-to-see issues with your strings.
If there are, you might try something like:
if chosen_text.strip() == guess_text.strip():
print "Congratulations! You guessed correctly!"
Or if there are differing capitalizations:
if chosen_text.strip().lower() == guess_text.strip().lower():
print "Congratulations! You guessed correctly!"
There are some other things you could do to make your code more Pythonic / more in the Python idiom. For example:
while game_running == True:
is better stated as:
while game_running:
But those few other cleanups are stylistic, and not related to your comparison difficulty.
This part of my code is giving me problems with the raw_input. The thing is, the terminal does not detect any problems and the program runs, however it never asks the user for input, the program just prints what it has to print at the beginning and then exits for some odd reasons, everything inside the while is not executed. Thanks in advance.
Heres the code:
options_secondscenario = ['Whats going on out there?', 'So what now?']
def second_scenario():
print "Conversation 1"
print "Conversation 2"
print "Conversation 3"
print options_secondscenario
option = options_secondscenario[1]
while next == option:
choice_secondscenario = raw_input("> ")
if next == 'Whats going on out there?':
print "Conversation 4"
elif next == 'So what now':
third_scenario()
else:
dead()
second_scenario()
next == option is never true, because next is a built-in function and is never equal to a string. In fact, this would actually be an error in Python 3. So your while loop is never entered.
I'd like to start out that I'm new to programming. I've never taken any classes on it. I just decided it sounded interesting and try it.
Anyway, I've been reading the "Learn Python the Hard Way" online and have gotten to exercise 36. This exercise involves making my own text-based game. Now, for the question. When is an appropriate time to use and modify global variables? I just started my adventure and want to add things that the player has to do before other events happen, such as pull a lever in a different room before the gate in the first room opens. And if the player wishes to return to the first room later on, the gate and lever still be triggered.
Here's the code so far. Mind you it's not fleshed out. Just wanted to know if it worked.
print "You are a lone adventurer with the bounty to clear out the crypt."
print "You come with nothing but your sword and a compass."
print "You enter the crypt."
print "To the north you have a gated portaculas and rooms to the west and east."
print "What do you do?"
gate = False
lever = False
def entrance():
global gate
while True:
choice = raw_input('> ')
if choice == 'west':
guard_shack()
elif choice == 'east':
lever_rm()
elif choice == 'north' and gate == False:
print "The gate is still closed and locked."
entrance()
elif choice == 'north' and gate == True:
fountain_rm()
else:
entrance(gate)
def lever_rm():
global lever
global gate
print "You enter the room."
print "What do you do"
while True:
choice = raw_input('> ')
if 'search' in choice:
print "You look around the room and notice a lever on the opposite wall."
elif "pull lever" in choice:
print "You pull the lever."
lever = True
gate = True
elif choice == 'west':
entrance()
else:
print '> '
def fountain_rm():
print "you're in the lever room!"
entrance()
Unfortunately, many tutorials (and professors) teach bad code in the name of simplicity (and they usually never bother to teach the right way later). In this case, the problem is exacerbated by the fact that you are directly executing top-level code instead of putting it in a main function and using if __name__ == '__main__': main() at the end.
You should try to avoid all global state that can be mutated. It's okay to declare constants, or even lists/sets/dicts that you're not allowed to change. But everything else should be either passed as a function parameter, or stored as an attribute on self of some class.
If nothing else, think about how you would write unit tests in the presence of mutable global variables (hint: it's impossible).
To transform code like you've given, indent everything and add a heading class CryptGame:, add self as the first argument to every function, and replace all variables declared global foo with self.foo.