Python beginner, text-based game - python

I'm fairly new to the programming game; I'm 3/4 of the way through Learn Python the Hard Way and I had a question about a little text-based game I made... So in this game my guy is stranded on a desert island and you have the option(raw input) of going left right or into the jungle. After choosing a direction, you're given the option to choose how many miles to walk. Each direction is supposed to have a different end result (and mile distance).
If you enter a number that is less than the number of miles to the destination, you're prompted with a choice to either "turn around or "keep going". If you enter turn around, you're taken back to the beginning, where you're again asked to choose a direction. If you enter keep going, the program returns to miles(), where you can choose a new amount of miles to walk.
def miles():
print "How many miles do you walk?"
miles_choice = raw_input("> ")
how_much = int(miles_choice)
if how_much >= 10:
right_dest()
elif how_much < 10:
turn()
else:
print "You can't just stand here..."
miles()
Ok so here's two questions:
How would I make it so that if the user originally enters a number of miles less than the destination distance, and the second mile input + the first mile input == the amount of miles to the destination, it will add the inputs and run my destination function, not just repeat miles().
Since all three final destinations will have different distances, should I write three separate mile functions? Is there a way to make it so that depending on the original direction chosen, miles() will run the different endpoints?
I'm sorry if this doesn't make a lick of sense... I'm still learning and I'm not sure how to fully explain what I'm trying to get across.

You could store the amount of miles to walk in each direction in a dict, and then check the dict to see if the user has walked far enough:
distances = {
'right': 7,
'left': 17,
'forward': 4
}
direction_choice = raw_input("> ")
miles_choice = raw_input("> ")
if how_much >= distances['direction_choice']:
right_dest()
elif how_much < distances['direction_choice']:
turn()
else:
print "You can't just stand here..."
miles()
Be sure to properly validate and cast the user input, which I have not addressed. Good luck!

I don't fully understand the requirements (the intended behavior and constraints). However, you might consider passing a parameter to your function (through and argument) to convey the maximum number of miles which the play could go in that direction).
For example:
#!/usr/bin/env python
# ...
def miles(max_miles=10):
print "How many miles do you walk?"
while True:
miles_choice = raw_input("> ")
try:
how_much = int(miles_choice)
except ValueError, e:
print >> sys.stderr, "That wasn't a valid entry: %s" % e
continue
if max_miles > how_much > 0:
break
else:
print "That's either too far or makes no sense"
return how_much
... in this case you pass maximum valid number of miles into the function through the "max_miles" argument and you return a valid integer (between 1 and max_miles) back.
It would be the responsibility of this function's caller to then call right_dest() or turn() as appropriate.
Note that I've removed your recursive call to miles() and replace it with a while True: loop, around a try: ... except ValueError: ... validation loop. That's more appropriate than recursion in this case. The code does a break out of the loop when the value of how_much is valid.
(By the way, if you call miles() with no parameter then the argument will be set to 10 as per the "defaulted argument" feature. That's unusual to Python (and Ruby) ... but basically makes the argument optional for cases where there's a sensible default value).

#Question #1: I used Class intern variables. You will maybe need them for further programming parts and should take it to zero when you are done on one direction, to start with zero for next step/lvl.
#Question #2: Dictionaries are the best way to do so,self.dest. Parameter pos used as key to get the value from the dictionary.
class MyGame:
def __init__(self):
self.current_miles = 0
self.dest = {'Left' : 10, 'Into the jungle' : 7, 'Right' : 22}
def miles(self,pos):
print "How many miles do you walk?"
miles_choice = raw_input("> ")
self.current_miles += int(miles_choice)
if self.current_miles >= self.dest.get(pos):
self.miles("Right")
elif self.current_miles < self.dest.get(pos):
print "you went "+ str(self.current_miles) + " miles"
else:
print "You can't just stand here..."
self.miles(pos)
mg = MyGame()
mg.miles('Into the jungle')

Related

Choose your own adventure - choice function?

I'm working on a choose-your-own-adventure game in Python to try to learn how to code. I might be doing this entirely wrong, but I thought rather than just nesting if-elif-else statements endlessly, I could write some sort of function that would be a template for all choices in the game.
My ideas was to have every decision in a given scene to generate two lists - choices and outcomes. The "multitemplate" function would then load the choose and outcomes lists, present the options to the player, take in the answer, and call the correct function for the outcome given.
My issue is that the outcome list is a list of functions, which Python doesn't seem to like. It says I've not defined the functions properly, but when I define my outcome functions before calling "multitemplate", it just prints them first.
Here's my code:
#Function to allow the adventurer to make choices
def refusal():
print("You stop at the roadsign you passed on your way into town. There are only two directions - towards Tarroway, or towards Angion, the town from whence you came.")
def guards():
print("The guards stop you.")
def theinn():
print("You follow the joyful chatter down the deserted street. Its source is a squat, one story building. A sign above the door reads \"The Forked Tongue\"")
choose = ["I walk towards the merry sounds.", "I turn on my heels and head back where I came from.","I stay where I am and watch the night quietly."]
outcome = [theinn(), refusal(), guards()]
def multitemplate(choose,outcome):
global mychoice
global carryon
for x in range(len(choose)):
print (f"{x+1}) " + choose[x], end="\n")
mychoice = (input())-1
while True:
if (mychoice) in range(len(choose)):
carryon = True
outcome[mychoice]
carrion()
else:
print("Please enter the number of the choice you wish to make.")
carryon = False
mychoice = int((input()))-1
I'd appreciate any input on how this should work properly, or if I'm going down a completely blind alley here.
Thanks!

How do I incorporate an if statement inside of another if statement?

I'm sort of a beginner at Python; I'm trying to write a text adventure game that prompts the user to explore a room given different options. After the user enters "1," I want the game to enter more choices through another if statement. How should I do that? And if this way is incorrect, what function should I use instead? I've tried putting another if statement in, but that leads to the program producing different results, like outputting a different part of the code instead of the one I want. Here is my code right now:
Name = input("What is your name, visitor?")
print(Name + (", you are being watched. Proceed carefully. A breeze of howling wind enters the room. Within the echo, something reaches out to you and offers a candle. Do you want to light the candle?"))
print("1 for YES")
print("2 for NO")
try:
Choice = int(input("What do you choose?"))
print("Choice:", Choice)
except ValueError:
print("Please input 1 or 2 only...")
Choice = int(input("What do you choose?"))
if Choice == 1 :
print("A flickering candlelight bursts forth. You are blinded momentarily. When your eyes adjust, you see a table, drawer, and lamp in the room. You can check:")
print("1 for Table")
print("2 for Drawer")
print("3 for Lamp")
if Choice == 2 :
print("You sit in silence, wondering what to do. Without sight, you're losing options. Eventually, you muster up the courage to stand up. You can't hear your own steps. Fear climbs up your throat. The floor gives way under your feet. You are swallowed by the darkness. GAME OVER.")
quit()
if not 1:
print("Please enter either 1 or 2.")
if not 2:
print("Please enter either 1 or 2")```
There are several issues with this code, but to address your question: nest the if within the outer if:
if Choice == 1 :
print("A flickering candlelight bursts forth. You are blinded momentarily. When your eyes adjust, you see a table, drawer, and lamp in the room. You can check:")
print("1 for Table")
print("2 for Drawer")
print("3 for Lamp")
Choice = int(input("What do you choose?"))
if Choice == 1:
# Do table stuff
elif Choice == 2:
# Do drawer stuff
elif Choice == 3:
# Do lamp stuff
else:
# Handle error

Variables don't change after being run through a function

I'm writing a small game in python in which certain events happen and effect variables which need to stay in certain parameters. I have the main file and then another file which has all of the events in them. Some of the values are changed in the function then supposed to change the overall values in main (Sorry if that doesnt make sense)
Here's the part in main:
while (army > -100 and army < 100 and people > -100 and people < 100 and church > -100 and church < 100 and affairs > -100 and money < 100 and money > -100):
os.system('clear')
#Top Bar. Should Stay throughout game.
print("[-]==[King: " + king + "]==[Years in power:" + str(years) +"]==[Army: " + str(army) + "]==[People: " + str(people) + "]==[Church: " + str(church) + "]==[Foreign Affairs: " + str(affairs) + "]==[Economy: " + str(money) +"]==[-]")
print(people)
event1(army, people, church, affairs, money, years)
That loops until one of the parameters falls below 0 then there's losing conditions
Right now there is only one event, and it's not quite finished, but I only need one thing to at least see a change in the values.
Here that:
def event1(army, people, church, affairs, money, years):
#Feilds are Flooding
print("")
print("Sire! The Feilds in the eastern baronies are flooding! What should we do?")
print("")
print("Choices:")
print("1: The rain will pass, do nothing. (~Money, People)")
print("2: Have the Royal Builders build flood protection! (~Money, People)")
print("")
c=input("Your choice sire: ")
while True:
if c > 2:
print("")
print("Please chose a valid option")
print("Your choice sire: ")
continue
if c == 1:
time.sleep(2)
print("")
print("You do nothing, your people starve from flooded feilds (-People, +Money)")
money = money+20
people = people-20
years = years+1
raw_input("Press Enter to go to the next year")
return money
return years
return people
break
After it runs the event the values people, money and years are all supposed to change, but when it loops, nothing changes.
Any help is appreciated! Thank you!
Those are local variables. As soon as you leave the method scope, the value is lost, unless you return and actually use the returned values.
In your caller, assign your variables with the new returned values:
money, years, people = event1(army, people, church, affairs, money, years)
and in event1, perform only one return (others are unreachable) of the tuple containing the 3 values you want to return (which is unpacked to the 3 upper level eponymous variables):
return money, years, people
YOU DO NOT NEED THE RETURN!!!!!!!!!!!!!!!!!!!! COMPLETELY REMOVE IT! READ THIS! (should help)
The return in fact ruins your command, and there is a really easily explainable way to understand how it works.
First I need to explain something, because I am kind of confused about your code. Return is used to make the value of your command whatever you have returned. Return is used like this:
def AddThreethousandTwohundredSeventyNineToNum(num):
num = num + 3279
return num
and then
print AddThreethousandTwohundredSeventyNineToNum(4)
It should print "3283". (3279 + 4)
print printThreethousandTwohundredSeventyNineToNum(2)
It will print "3281".
You can also do cool things like:
if AddThreethousandTwohundredSeventyNineToNum(x) == y:
DoSomething
All return does is make the value OF THE FUNCTION whatever you want it to be. In the last code, the function looks for what I made num, and sees that it is 4 or 2, so it does num = num + 3279, so num gets increased by 3279 (3273 or 3271). When you do return num, it makes THE FUNCTION equal num.
That means what you have done is changed all those beatiful values in lines 21-23 (money, people, etc.) and technically that is all you had to do. However, when you returned the numbers, you made your command not only change those values, but also become a number, and obviously you cant just have a number lying around in your command. Or else the interpreter will not understand.
I hope I was clear enough, and if not, please please PLEASE tell me (please).

randint usage in Learn Python the hard way exercise 43

I am having trouble with the randint usage of exercise 43 in Learn python the hard way link to exercise. Assuming I follow Zed Shaw's code perfectly in all other parts of the program, and I have from random import randint, when I run the program and type the 3 digit passcode into the keypad, it returns a "BZZZZEDDD!". Here is that section of code:
class LaserWeaponArmory(Scene):
def enter(self):
print "You do a dive roll into the Weapon Armory, crouch and scan the room"
print "for more Gothons that might be hiding. It's dead quiet, too quiet."
print "You stand up and run to the far side of the room and find the"
print "neutron bomb in its container. There's a keypad lock on the box"
print "and you need the code to get the bomb out. If you get the code"
print "wrong 10 times then the lock closes forever and you can't"
print "get the bomb. The code is 3 digits."
code = "%d%d%d" % (randint(1,9), randint(1,9), randint(1,9))
guess = raw_input("[keypad]> ")
guesses = 0
while guess != code and guesses < 10:
print "BZZZZEDDD!"
guesses += 1
guess = raw_input("[keypad]> ")
if guess == code:
print "The container clicks open and the seal breaks, letting gas out."
print "You grab the neutron bomb and run as fast as you can to the"
print "bridge where you must place it in the right spot."
return 'the_bridge'
else:
print "The lock buzzes one last time and then you hear a sickening"
print "melting sound as the mechanism is fused together."
print "You decide to sit there, and finally the Gothons blow up the"
print "ship from their ship and you die."
return 'death'
Lets say in the guess = raw_input("[keypad]> ") when running the program I type in "368".
Shouldn't that be within the parameters of code = "%d%d%d" % (randint(1,9), randint(1,9), randint(1,9)) and be TRUE for if guess ==code:? Instead it runs it as if guess != code and returns a "BZZZZEDDD!"
Your guess of 368 is within the possible range for the code, but that's not what the while loop is checking. The line
code = "%d%d%d" % (randint(1,9), randint(1,9), randint(1,9))
will generate a string of three random digits. The code could be anything between 111 and 999 (except there can be no zeroes) and you have no way of knowing exactly what it is as the program currently stands. At the bottom of the lesson, under Study Drills, the author says:
Add cheat codes to the game so you can get past the more difficult
rooms. I can do this with two words on one line.
Presumably, this code is one of the rooms he's talking about. Try adding something that will give you a hint of the code.

scanning user input in python

direction = input("enter a direction: ")
if direction != "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 != "look":
print ("please enter in the following format, go (north,east,south,west,up,down)")
elif direction == "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) ... the game should then end.")
elif direction == "look":
print ("You see nothing but endless void stretching off in all directions ...")
else:
print ("You wander of in the direction of " + direction)
i need to know how to do this in python.
i need to scan user inputs first 2 letters
for example
i = user_input
#user inputs go ayisgfdygasdf
i need it to be able to scan the user input, check if the first 2 letters are go, and if they are go but it doesnt recognise the second word which in this case is "ayisgfdygasdf" then to print "sorry, i cant do that"
He could also try using:
directions.split()
But it may require to use try/except in some cases.
For more information about split and methods try using:
dir(directions)
to see what methods object directions have
or:
help(directions.split)
to see help about a specific method (in this case method split of object directions)
You can access characters of a string in python by index using the [] notation. You can check the first two character in a string by typing user_input[:2]. This code will include all characters up to, but not including the index typed. So this notation will include user_input[0] and user_input[1]. You can then check if user_input[:2] is equal to 'go' or not, and continue from there.
Hope this helped.
Instead try using:
direction = sys.stdin.readlines()
It may require you to ctrl+D after you are done but you will be able to capture so much more.
Also, to get the subarray you can then you can even check:
direction[:2] != "go"
or alternatively, for more readable code:
if not direction.startswith("go"):
Also I'd recommend, for making your code more readable,
defined_direction = frozenset(["quit", "go north", "go south"])
if( direction not in defined_direction):
print "please enter...."
You can index the individual characters of your input:
if direction[:2] == "go":
print "Sorry, I can't do that."
However, trying assign an if-else branch to each possible input is typically a bad choice... It becomes difficult to maintain very quickly.
A cleaner approach in this case might be to define a dictionary with valid input as follows:
input_response = {"quit":"OK ... but", "go north": "You wander off north", \
"go south": "You wander off south"} # etc
You could then re-write your code to something like:
try:
print input_response[direction]
except KeyError:
if direction[:2] == "go":
print "Sorry, I can't do that."
else:
print ("please enter in the following format...")

Categories