Python text adventure woes - python

if schoice == 1:
print "You walk right up to the rat and proceed to BEAT THE SHIT OUT OF IT AHHHHHH. Ahem. Anyway, you look at your blood-covered fists and feel good about yourself. You know that you just leveled up your Unarmed to 11. BOOYA!"
skills("Unarmed") = 11
else:
"You proceed to be a little bitch and sneak past the rat. Even though you know that you are being a total coward, you feel good, and you know that you leveled up your sneak to 11. Oh Yeah!"
skills("Sneak") = 11
First off, I would like to say that I have the raw_input stuff with everything else set up, but I was just wondering if I HAVE to split off from here, and then have to write the same thing a gazillion times, or I could make both of these choices, no matter which is picked, to proceed to a shared new choice?

You don't have to split everything every time there is a choice, no.
Consider this:
print('This happens first')
choice = raw_input('Make a choice (1 or 2)')
if choice == 1:
print('Conditional event no1')
else:
print('Conditional event no2')
print('This happens after the choice, no matter what happened')
The story can go on from there. You can visualize this as a flowchart resembling this:
/------ Choice 1 -------\
Starting point / \____ Happens in either case
\ /
\------ Choice 2 -------/

Related

Multiple changes to the same variable within different if statements

SOLVED: I read through my code, it was a 'bug'. When I copied the dice roll method from the 'player character', since it uses the same mechanics for the enemies, I set the damage to 0 if it rolls with one die on accident.
Beginner here. (Python crash course halfway of chapter 9)
I am trying to build a simple turn based text game to practice (classes,if statement, modifying dictionaries/lists etc).
I will copy two snippets from my code, so you can understand my problem better.
(I'm really sorry that I can't give a short description, my best try was the title, but that still doesn't make it good enough. If you want an abridged tldr, go to the bottom with the bold texts.)
First, I have two characters, that you can choose from as an if-elif-else statement.
I used the same "player_xy" (xy being like health, damage etc) for the two characters, but assigning different values to them based on the player's choice. (My reasoning being is so I only have to reference the same variable in the code later in the battle system, making my job easier.)
(The variables fighter_max_hp.. etc are defined earlier, but it doesn't matter (tried moving it to before/inside the if statements.)
while select_repeat == True:
print("Type 'f' for fighter , 'm' for mage, or 'q' to quit!")
character = input("TYPE: ")
#player chooses fighter
if character == 'f':
player_max_hp = fighter_max_hp
player_max_mana = fighter_max_mana
#this goes on for a while, setting up all the stats
#player chooses mage
elif character == 'm':
player_max_hp = mage_max_hp
player_max_mana = mage_max_mana
#this goes on for a while, setting up all the stats
#player chooses to quit
elif character == 'q':
select_repeat = False
#invalid input
else:
print("\nPlease choose a valid option!")
Later in the code, I have a part where a randomizer sets up enemies to fight.
I used the same "enemy_xy" (xy being like health, damage etc) for the enemies. (My reasoning was the same here as for the characters.)
(Same, as with the player variables (tried moving it to before/inside the if statements.)
while enemy_select == True:
#game chooses an enemy to fight!
min = 1
max = 3
enemy_chooser = int(random.randint(min, max))
if enemy_chooser == 1:
#choose werewolf
enemy_hp = werewolf_hp
enemy_dice = werewolf_dice
#this goes on for a while, setting up all the stats
if enemy_chooser == 2:
#choose lesser mimic
enemy_hp = int(player_max_hp / 2)
enemy_dice = player_dice
elif enemy_chooser == 3:
#choose zombie
enemy_hp = zombie_hp
enemy_dice = zombie_dice
#this goes on for a while, setting up all the stats
Keep in mind, all of these enemies use the same "enemy_hp", "enemy_dice" etc. variables, within the same battle system, just assigned as "enemy_hp = werewolf_hp" or "enemy_hp = "zombie_hp".
The fight happens, and:
If your enemy is the werewolf:
you deal damage to it
you receive damage from it
you can kill it
you can get killed by it
If your enemy is the lesser mimic:
you deal damage to it
you can ONLY receive damage from it if you are a fighter (mage's hp doesn't decrease)
you can kill it
you can ONLY get killed by it if you are a fighter (obviously, since it doesn't deal damage to mage hp)
If your enemy is the zombie:
you deal damage to it
you CAN NOT receive damage from it (not the fighter, or the mage)
you can kill it
you can not get killed by it (obviously, since no damage)
Otherwise, it prints out the different variable values as assigned (different stats for each monster) as expected, and it uses correct calculations to deal damage.. it just can't in the two cases mentioned above.
Now comes the main part of my question...
If I change the variables like this:
elif enemy_chooser == 2:
#choose zombie
enemy_hp = werewolf_hp ##CHANGE
enemy_dice = werewolf_dice ##CHANGE
#this goes on for a while, setting up all the stats
Then the zombie can finally deal damage to the player (with the werewolf's stats).
It's as if because the lines
enemy_hp = werewolf_hp
enemy_dice = werewolf_dice
#etc
are written earlier than:
enemy_hp = zombie_hp
enemy_dice = zombie_dice
#etc
it somehow effects the variable (regardless or not if the "if" statement is true).
because werewolf_xy was defined earlier than zombie_xy
#enemy werewolf defined first in the code
werewolf_hp = 20
werewolf_dice = 2
#etc
#enemy zombie defined right after
zombie_hp = 35
zombie_dice = 1
#etc
Same happens with the fighter and mage selection.
Somehow the player_hp = xy_hp only works if xy = fighter, because the fighters variables are defined earlier in the code, and thus making the "lesser mimic" deal damage only to the fighter.
My question is "simply".. why?
I tried everything in my power, to no avail.
As you have seen, I could identify what causes the problem (and thus I >could< potentionally work around it), but I still don't know why Python does what it does, and that bothers me.
Any help or input from more experienced users would be greatly appreciated.
Thank you in advance!
Tankerka
You have a bug.
There's not enough details in this (long!) narrative to identify the bug.
Here's how you fix it:
breakpoint()
Put that near the top of your code,
and use n next, plus p print var,
to see what your code is doing.
It is quicker and more flexible than print( ... ).
Read up on that pair of commands here:
https://docs.python.org/3/library/pdb.html
Separate item: refactor your code as you go along.
You're starting to have enough if / elif logic
that it won't all fit in a single screenful
with no scrolling.
That suggests that it's a good time to use def
to break out a helper function.
You might def get_enemy_hp( ... ):, for example,
and also define get_enemy_dice().
Other things you might choose to study:
a class can be a good way to organize the variables you're defining -- embrace the self syntax!
a dict could map from enemy type to hp, or to dice
The nice thing about helper functions is they're
the perfect target for unit tests.
It takes a minute to write a test, but it winds up saving you time.
https://docs.python.org/3/library/unittest.html
When you identify and fix the problem, let us know!
https://stackoverflow.com/help/self-answer

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 can I implement a function/loop in a cmd game?

I've started to make a cmd-based minigame, and I wanna implement a feature, where you come across choices which you have to decide that what option will you choose. My problem however is that in my code, if you type anything other than the two options listed, than the game will just 'end' there.
print('Welcome to \'The Exchange\'.')
print('This game is all about making wise decisions with your money.')
print('At the beginning, you\'ll start out with 10$, and from here,')
print('Everything is YOUR choice! Have fun!\n')
# Starter informations. #
yourMoney = 100
# First choise part of the game. #
print('You\'ve come to your first decision of the game -')
print('Do you want to make an insurance for 5 dollars, or you just wanna skip it for now?')
firstDecision = input('Type \"make\" to make one, and \"skip\" to just skip it.\n')
if(firstDecision == "make"):
print("Fine.")
elif(firstDecision == "skip"):
print("Not fine.")
else:
print("You've misspelled it, try again!")
But I want to make it that if you type anything other than the two options, then the game would simply ask the question again, and again, until you type any of the two optins, and then, it would move on. I know, that I have to use some kind of loop, or function, and I also tried these in my code, but it haven't turned out too great. I'd greatly appreciate the help.
My suggestion with minimal change in the code.
print('Welcome to \'The Exchange\'.')
print('This game is all about making wise decisions with your money.')
print('At the beginning, you\'ll start out with 10$, and from here,')
print('Everything is YOUR choice! Have fun!\n')
# Starter informations. #
yourMoney = 100
# First choise part of the game. #
print('You\'ve come to your first decision of the game -')
print('Do you want to make an insurance for 5 dollars, or you just wanna skip it for now?')
firstDecision = input('Type \"make\" to make one, and \"skip\" to just skip it.\n')
while(firstDecision != 'make' or firstDecision != 'skip'):
if(firstDecision == "make"):
print("Fine.")
### Do here all your logics and in the end add the line below
break
elif(firstDecision == "skip"):
print("Not fine.")
### Do here all your logics and in the end add the line below
break
else:
print("You've misspelled it, try again!")
firstDecision = input('Type \"make\" to make one, and \"skip\" to just skip it.\n')
Please let me know if there were problems or this is not what you wanted.

Can't figure out how to have percentage chnnances for something to happen

I am making a text-based game; I am trying to figure out a way to have multiple endings and certain percentages for each to happen, but when I run this, it comes up with weird letters and sometimes multiple endings.
choice1_wakeup = input ("Wake Up? Y or N:")
if choice1_wakeup == 'y' or choice1_wakeup == 'Y':
print ("Placeholder")
else:
import random
for x in range(100):
ending_percent = (random.randint(1,10))
if ending_percent > 2:
choice1_ending_common = ("You are woken a while later and see the priest holding a knife to your throat for a moment before he slits it and you bleed out.")
print (random.choice(choice1_ending_common))
elif ending_percent < 2 and ending_percent >0.5:
choice1_ending_rare = ("You wake up a little while later and find yourself dangling over the mouth of the sacrificial volcano while your tribe chants the name of the fire goddess, kahuahuahua, kahuahuahua, kahuahuahua. “What’s happening?” you ask the priest. “You are being sacrificed for your crimes” he replies and at that he tosses you into the fiery abyss.","A few minutes later you are woken by the suddenly extremely cold temperatures. You look around and spot the god of death daharasus. “Why haven’t you completed your rituals to me yet?” he asks you in a stone cold voice. “I’m sorry, I fell asleep” you frightendly reply. “I don’t want excuses!” he screams, he levels his finger at you and you are instantly killed, your soul is forever trapped in the same spot reliving that moment over and over forever.")
print (random.choice(choice1_ending_rare))
else:
choice1_ending_impossible = input ('You are woken up by a stranger a few hours later. "Who are you?" you ask the strange man standing over you. "My name is Jeff Probst" he replies. "I was wondering if you would like to be on my new TV show?" Y or N:')
if choice1_ending_impossible >= 'y' or choice1_ending_impossible >= 'Y':
print ("impossible test")
Please read the documentation for the choice method. That method picks a random element from the iterable sequence you give it. In this case, the sequence you provide is the text of a single ending. The available choices are the individual letters of that ending, so ... you get a single, random character.
If you want to choose a random text, you need to give it a list of strings, such as
ending_list = [
["You and your team vote Jeff Probst off the island.",
"You eat five ugly things and win the immunity challenge.",
"The show is canceled for lack of geologically stable shooting locations."]
Now you can pick one element from ending_list. Is that enough to get you going?

Beginner Python: How to give different responses to ELSE in a while-loop

So, I'm working my way through Learn Python the Hard Way, and I am on Lesson 36, where I make my own BBS-text-style game based on the one he did in lesson 35.
http://learnpythonthehardway.org/book/ex36.html
http://learnpythonthehardway.org/book/ex35.html
So, I did a decent job, but I noticed that when I mimicked his eternal while-loop, where the player can't ever leave the room under anything but very specific circumstances, the loop always gives the same response for the else...unless they say the right thing, they're stuck forever.
Here's my code:
def sleeping_giant():
print "There is a single door, with a giant sleeping in front of it."
print "How can you get the giant to move?"
print "Should you wake him?"
giant_moved = False
while True:
choice = raw_input("> ")
if choice == "Yes":
dead("The giant rips you into four pieces and uses your quartered body as a stack of pillows.")
elif choice == "No" and not giant_moved:
print "The giant rolls in his sleep, clearing an easy path to the door."
giant_moved = True
elif "Open" or "Go" in choice and giant_moved:
treasure_room()
else:
print "I have no idea what the fuck you are trying to say to me. English. Do you speak it?!"
Apologies if that format doesn't translate well.
Anyway, anytime the user types something that doesn't satisfy an if or an elif, they will receive that same else response.
How would I change this? As in, make it more dynamic, so that if they keep screwing up the response, the else response changes?
I can't figure out how to get the code to say (in non-literal terms, I mean, I can't get the logic to say), 'If the else has been used, the response should be a new else, and once that one has been used, it should be yet another else response'.
If this doesn't make sense, please let me know.
Here's the incremental version of Greg's answer using a counter so you can get a predictable order of responses:
global responses = [ "Nice try. Try again.",
"Sorry, what was that?",
"I don't know what that means."]
def sleeping_giant():
counter = 0
print "There is a single door, with a giant sleeping in front of it."
print "How can you get the giant to move?"
print "Should you wake him?"
giant_moved = False
while True:
choice = raw_input("> ")
if choice == "Yes":
dead("The giant rips you into four pieces and uses your quartered body as a stack of pillows.")
elif choice == "No" and not giant_moved:
print "The giant rolls in his sleep, clearing an easy path to the door."
giant_moved = True
elif ("Open" in choice or "Go" in choice) and giant_moved:
treasure_room()
else:
print responses[counter]
if counter < 2:
counter += 1
This condition:
elif "Open" or "Go" in choice and giant_moved:
parses as the following (according to operator precedence):
elif "Open" or (("Go" in choice) and giant_moved):
Since "Open" is considered True, this condition will always match. It sounds like you might instead want:
elif ("Open" in choice or "Go" in choice) and giant_moved:
To choose a different response, try something like:
else:
responses = [
"Nice try. Try again.",
"Sorry, what was that?",
"I don't know what that means.",
]
print random.choice(responses)

Categories