0

I am learning Python by creating a text-based adventure game. I was having a difficult time figuring out if I could call a previous variable. For example, this is a snippet of my code (advice on how to consolidate would be helpful haha) I have an if statement that allows the player to select an input.

Under the ALIEN input, you'll see if they select 1. They choose "Accept defeat".

I have the same outcome towards the end of this code, for the player to choose "Accept defeat" again after the IMPROV input. I would like to loop back to the first alien variable if that option is chosen. Rather than writing the same if, elif, statements over again. Is this possible?

   def main(): #Groups together the entire script, allows for a loop. The enitire script is called main.
import sys #imports system settings and functions
from colorama import init #imports color scheme
init()
init(autoreset=True) #resets color scheme after every use
#Text based adventure game in progress
from colorama import Fore, Back, Style
s_b = Style.BRIGHT # This allows you to shorthand a variable, rather than typing Style.BRIGHT everytime.
f_c = Fore.CYAN
f_g = Fore.GREEN
f_y = Fore.YELLOW
f_r = Fore.RED
print ("")
print ("")
print (f_y + s_b + "                                                                           WELCOME TO THE MAZE                                   ")
print ("")
print ("")
print (s_b + "You have found yourself stuck within a dark room, inside this room are 5 doors.. Your only way out..")
print ("")
print (s_b + "Do you want to enter door 1,2,3,4, or 5?") #This gives the player options to choose.
print ("")
door = input(f_y + s_b + "> ");
# input("> ") means the player can give any variable
# Will only work if the variable is defined down below
if door == "1":
    print ("")
    print (s_b + "Theres an alien eating what appears to be a human arm, though its so damaged it's hard to be sure. There is a knife next to the alien.")
    print ("")
    print (s_b + "what do you want to do?")
    print ("")
    print (f_g + s_b + "1. Go for the knife")
    print ("")
    print (f_g + s_b + "2. Attack alien before it notices you")
    print ("")

    alien = input(f_y + s_b + "> ");

    if alien == "1":
        print ("")
        print (s_b + "You approach the knife slowly, While the alien is distracted. You finally reach the knife, but as you look up, the alien stares back at you.")
        print ("")
        print (s_b + "You make a move to stab the alien, but he is too quick. With one swift motion, the alien thrusts you into the air.")
        print ("")
        print (s_b + "You land hard, as the alien makes it's way towards you again. What should you do?")
        print ("")
        print (f_g + s_b + "1. Accept defeat?")
        print ("")
        print (f_g + s_b + "2. Last ditch effort?")
        print ("")

        improv = input(f_y + s_b + "> ")

        if improv == "1":
            print ("")
            print (s_b + "The alien stands over you, as you grimace in pain. You extend your arms out revealing your chest. Showing the alien you're not afrain of death.")
            print ("")
            print (s_b + "The alien stops, and brings it's face close to yours. You have gained the alien's respect, he walks slowly back to the arm he was consuming.")
            print ("")
            print (s_b + "You lie in shock, What should you do now?")
            print ("")
            print (s_b + f_g + "1. Get up and try to communicate with the alien?")
            print ("")
            print (s_b + f_g + "2. Get up and continue onward through this seemingly dangerous world?")
            print ("")

            onward = input(f_y + s_b + "> ")

            if onward == "1":
                print ("")
                print (s_b + "You take a deep breath, still in pain, you slowly limp your way towards the alien.")
                print ("")
                print (s_b + "As the alien hears you approach, it stops eating the arm and turns towards your direction.")
                print ("")
                print (s_b + "What should you say?")
                print ("")
                print (s_b + f_g + "1. 'Why didn't you kill me?'")
                print ("")
                print (s_b + f_g + "2. 'Help me escape this place.'")
                print ("")

                kill = input(f_y + s_b + "> ")


                if kill == "1":
                    print ("")
                    print (s_b + "You walk close to the alien as he stares into your eyes, you show no fear as you stare right back. 'Why didn't you kill me?' you ask.")
                    print ("")
                    print (s_b + "The alien huffs and responds in the deepest voice imaginable, 'I only kill those who have fear.'")
                    print ("")
                    print (s_b + "You respond..")
                    print ("")
                    print (s_b + f_g + "1. I have fear.")
                    print ("")
                    print (s_b + f_g + "2. You don't scare me, nothing does.")
                    print ("")

                    kill2 = input(f_y + s_b + "> ")

                    if kill2 == "1":
                        print ("")
                        print (s_b + "'I am terrified of you' you say. I am terrified of everything, I had given up.'")
                        print ("")
                        print (s_b + "The alien responds 'This is why you approach me? To express your fear? Have I misread you?'")
                        print ("")
                        print (s_b + "'You haven't misread me, I am ready to die.' you respond.")
                        print ("")
                        print (s_b + "The alien respects your wishes, 'Well, I can arrange that..'")
                        print ("")
                        print (s_b + "The alien swiftly swipes off your head, leaving your body lifeless.")
                        print ("")
                        print (s_b + f_r + "You died.. GAME OVER!! You gave up too soon..")
                        print ("")

                if kill == "2":
                    print ("")
                    print (s_b + "You limp up to the alien, brushing down your clothes.")
                    print ("")
                    print (s_b + "The alien stares at you, seemingly waiting for you to say something.")
                    print ("")
                    print (s_b + "'Help me escape this place' you say.")
                    print ("")
                    print (s_b + "'Help you?' responds the alien with a fighteningly deep voice. 'Why would you think I would help you?'")
                    print ("")
                    print (s_b + f_g + "1. Because you didn't kill me, and I need to get out of this place.")
                    print ("")
                    print (s_b + f_g + "2. Because I will kill you if you dont.")
                    print ("")


            elif onward == "2":
                print ("")
                print (s_b + "You quickly turn over and limp as far from the alien as you can.")
                print ("")
                print (s_b + "This world is dark, so it's difficult to see what's ahead.")
                print ("")
                print (s_b + "You continue onward in hopes to find a way out.")
                print ("")




        elif improv == "2":
            print ("")
            print (s_b + "You quickly scan the area for weapons and shelter. The alien is approaching quickly. You notice a black wall.")
            print ("")
            print (s_b + "There is no way you can reach the wall in time, and even if you do, the alien will just follow..")
            print ("")
            print (s_b + "What should you do?")
            print ("")
            print (f_g + s_b + "1. Attempt to run behind the wall")
            print ("")
            print (f_g + s_b + "2. Accept defeat?")
            print ("")

            wall = input(f_y + s_b + "> ")

            if wall == "1":
                print ("")
                print (s_b + "You scream in agony as you pull yourself up and make a break toward the wall.")
                print ("")
                print (s_b + "You hear the alien directly behind you. You dive behind the wall, landing on a sharp object.")
                print ("")
                print (s_b + "The object is an incredibly sharp sword. The alien hurries around the wall and attacks you.")
                print ("")
                print (s_b + "What should you do?")
                print ("")
                print (s_b + f_g + "1. Attempt to take the alien's limbs off with the sword.")
                print ("")
                print (s_b + f_g + "2. Aim stright for the aliens neck with the sword.")
                print ("")

            elif wall == "2":

                improv = input(f_y + s_b + "> ")

    elif alien == "2":
        print ("")
        print (s_b + "You catch the alien off-guard. He stumbled and hisses in your direction. You scream in terror before he grabs the knife, and punctures your throat as he rips off your limbs.")
        print ("")
        print (s_b + f_r + "You died.. GAME OVER.. Mistakes can't be made this soon.. OUCH")
        print ("")

    else:
        print ("")
        print (s_b + "You froze, you decided to do nothing. In shock, you let the alien notice and approach you. He gashes your face and begins to consume your body.")
        print ("")
        print (s_b + f_r + "You died.. GAME OVER.. How did you die this soon??")
        print ("")

    restart=input(f_y + s_b + "Start over? Yes or No? ").lower()
    if restart == "yes":
        sys.stderr.write("\x1b[2J\x1b[H") ## This will clear out screen in the terminal
        main()

    else:
        exit()  #Remember this to start a loop, from restart=input, to exit()

main()

  • 3
    What are `f_g`, `f_y`, and `s_b`? Variable names like that make code hard to read. – ChrisGPT was on strike Aug 15 '18 at 20:04
  • 1
    Also, try using `\n` as a newline, instead of `print("")` – Rushabh Mehta Aug 15 '18 at 20:06
  • 4
    Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation, as suggested when you created this account. [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) applies here. We cannot effectively help you until you post your MCVE code and accurately describe the problem. We should be able to paste your posted code into a text file and reproduce the problem you described. – Prune Aug 15 '18 at 20:08
  • 1
    Your posted code dies at line 1. It is not at all minimal. You've used non-descriptive variable names. Most of all, you've made no attempt to write a loop to solve your problem, one which is covered well on many tutorial sites and other question on Stack Overflow. Please perform the expected research and follow the SO guidelines. We're happy to help you, but we need these things to be (1) straightforward for us; (2) useful for our archive -- which after all, is the charter of this site. – Prune Aug 15 '18 at 20:14
  • 1
    also you don't have any handling for if they enter something not allowed like `3` – depperm Aug 15 '18 at 20:14
  • I changed the variables from colorama Fore.GREEN, for example to f_g, to keep me from typing the entire variable each time. I could post the entire script, but at this moment, it is quite long. I figured just posting a snippet of the code would suffice. Should I re-post my question with the full script? – Idealprinciple Aug 15 '18 at 20:15

2 Answers2

2

You don't seem to make use of functions at all. That is something that you should do :)

For example, instead of repeating the input colors every time, make a colored_input:

def colored_input():
    return input(Fore.YELLOW + Style.BRIGHT + "> ")

alien = colored_input()

Second, I'd consolidate the "events" instead of typing them out like you do. For example, I'd store the pages separately in a tuple. Like so:

STARTING_TEXT = """
Theres an alien eating what appears to be a human arm, though its so damaged it's hard to be sure. There is a knife next to the alien.
what do you want to do?¨
"""

STARTING_CHOICES = """
Go for the knife
Attack alien before it notices you
"""

EVENT_START = (STARTING_TEXT, STARTING_CHOICES)

The triple-quotes create a multi-line string. Note that the first and last newline is part of the string, so you'll have to get rid of it later.

Of course, you can put the texts into the tuple directly:

EVENT_APPROACH_KNIFE = ("""
You approach the knife slowly, While the alien is distracted. You finally reach the knife, but as you look up, the alien stares back at you.
You make a move to stab the alien, but he is too quick. With one swift motion, the alien thrusts you into the air.
You land hard, as the alien makes it's way towards you again. What should you do?
""", """
Accept defeat?
Last ditch effort?
""")

Now, if you have a bunch of "events" like this, you can have a function to display them and ask for input in the same step:

def run_event(event):  # from here on, the "event" variable will be whichever EVENT_* you call
    text, choices = event  # separates the two items of the tuple
    # Remove whitespace from start and end. This gets rid of the starting and ending newline
    # that I mentioned earlier:
    # (go ahead, remove the following line and see what happens)
    text = text.strip()
    # Now let's get individual lines - split the text on newlines:
    text_lines = text.split("\n")
    # print them with colors:
    for line in text_lines:
        print(Fore.YELLOW + line)
        print() # To print an empty line, you don't even need to add the ""
    # now let's do the same with choices:
    choices = choices.strip()
    choice_lines = choices.split("\n")
    for num, line in enumerate(choice_lines):
        # the "enumerate" gives you "num" as the number of the line
        # but it counts from 0, so we need to add 1
        # (and wrap it in str() because otherwise you can't add it to a string
        print(Fore.GREEN + Style.BRIGHT + str(num + 1) + ". " + line)
        print()
    # finally, ask for player's choice and return it
    return colored_input()

This will simplify your code greatly. Assuming you define all the events beforehand, you can do the if's like so:

door = run_event(EVENT_DOOR)
if door == "1":
    alien = run_event(EVENT_ALIEN)
    if alien == "1":
        improv = run_event(EVENT_IMPROV)
        ...
    elif alien == "2":
        ...

You could develop this further, for instance, use a list instead of multi-line string for the choices, and associate events to the choices.

But, to answer your original question: structured like this, you can make parts of the game into functions. Like so:

def accept_defeat():
    improv = run_event(EVENT_ACCEPT_DEFEAT)
    if improv == "1":
        ...
    elif improv == "2":
        wall = run_event(EVENT_LAST_DITCH)
        if wall == "1":
            accept_defeat()  # here you're calling the same function again!
        elif ...:
            ...

 # and then somewhere in the main function:
 def main():
      alien = run_event(EVENT_ALIEN):
      if alien == "1":
          accept_defeat()
      elif ...:
          ...

When you're calling a function from within the same function, you are using recursion. This is a rather bad solution, actually: for one, if you decide to "accept defeat" more than 128 or so times in a row, you'll exceed a recursion limit and your program will crash.

But to avoid recursion, you would have to rework your program in deeper ways. ISTM at your skill level, this solution works fine. You can learn more when you hit the limits of this approach - or when you feel like you understand this code very well and want more of a challenge :)

matejcik
  • 1,912
  • 16
  • 26
  • awesome recommendations!! Thank you so much. You made everything clear and your comments explain everything very well. I appreciate the insight! I'll make these changes :) – Idealprinciple Aug 15 '18 at 23:56
0

I would recommend making a type of graph. You'll have to map out all the options but you probably have to do that already. Also, implementing a loop will help handle un-acceptable answers.

One viable possibility (test it here, FYI this is not even as complete as OP example but you can enter 1 twice to see how it should go):

# make a class for each event, it'll contain a description and any number of choices
class Event:
  def __init__(self,description,choices,options):
      self.description=description
      self.choices=choices
      # options should be a list the same length as choices with corresponding keys to other events
      self.options=options
  def to_string(self):
      print(self.description+'\n')
      for choice in self.choices:
        print(choice+'\n')
      # point to the next event
      return self.options[self.make_choice()-1]
  def make_choice(self):
    c=0
    # this won't allow a user to enter a value not offered
    while c<1 or c>len(self.choices):
        c=int(input("your choice> "))
    return c

# this is your map
events={'start':Event("You approach the knife slowly, While the alien is distracted. You finally reach the knife, but as you look up, the alien stares back at you.\nYou make a move to stab the alien, but he is too quick. With one swift motion, the alien thrusts you into the air.\nYou land hard, as the alien makes it's way towards you again. What should you do?",["1. Accept defeat?","2. Last ditch effort?"],['defeat','ditch']),'defeat':Event("The alien stands over you, as you grimace in pain. You extend your arms out revealing your chest. Showing the alien you're not afrain of death.\nThe alien stops, and brings it's face close to yours. You have gained the alien's respect, he walks slowly back to the arm he was consuming.\nYou lie in shock, What should you do now?",["1. Get up and try to communicate with the alien?","2. Get up and continue onward through this seemingly dangerous world?"],['communicate','onward']),'communicate':Event("You take a deep breath, still in pain, you slowly limp your way towards the alien.\nAs the alien hears you approach, it stops eating the arm and turns towards your direction.\nWhat should you say?",["1. 'Why didn't you kill me?'","2. 'Help me escape this place.'"],['kill','escape'])}

c='start'
while True:
    t=events[c].to_string()
    # this is how you'd break the loop if you win or lose
    if t=="Game Over":
        break
    elif t=="You Win":
        break
    c=t
depperm
  • 10,606
  • 4
  • 43
  • 67
  • I'm not sure the OP wants/needs someone to write the code for them – Liora Haydont Aug 15 '18 at 20:45
  • @LioraHaydont they have made an attempt and they have trouble with `figuring out if I could call a previous variable.` This answer offers a solution to that and I believe a slightly more elegant design – depperm Aug 15 '18 at 20:47
  • You could have advised them to use another design and given guidance without writing all the code for them. – Liora Haydont Aug 15 '18 at 20:49
  • Thank you for the responses! – Idealprinciple Aug 15 '18 at 20:49
  • I made the mistake of posting only a portion of the code that does not show how the code runs. My code is quite long and I have solutions to most of the things mentioned. I do appreciate the feedback, I will post again when I am able to (Can't post more than twice in 90 minutes). I'll provide the script with the information that allows you to run it yourselves. Again, my apologies. Twas my first post haha. – Idealprinciple Aug 15 '18 at 20:52