6
\$\begingroup\$

This is my first Python text-based game. Let me know if there is something I should improve on or fix in the way that my code is written because I feel that I am being very redundant in my code, but I'm just learning this stuff.

Also note that note.txt just says:

this cabin will self destruct in.....

#Lost In the Woods - A simple text based game
from sys import exit

def start():
    print "You are in the middle of the woods alone and scared!"
    print "There is no one around but yourself."
    print "You look around and wonder....."
    print "What will you do?"
    print "1.move forward\n2.stay still"

    choice = raw_input("> ")

    if "move" in choice:
        bear_fight()
    else:
        print "Well your still at the same spot."
        start()

def bear_fight():
    print "Ahead of you is a huge hungry bear with razor sharp claws"
    print "Hes looks angry too!"
    print "Do you....."
    print "1.throw rock\n2.play dead\n3.run away\n"

    choice = raw_input("> ")

    if "run" in choice:
        print "Duhhh.... Did you think you can out run a bear?"
        dead("The bear catches up and has you for dinner, Good Job")
    elif "play dead" in choice:
        print "The bear laughs at you and chews but off."
        dead("You lost your but and lost this game")
    else:
        print "You deafted the bear with a rock! Hows that possible?"
        print "Anyways, You contine to move forward untill......"
        cabins()

def cabins():
    print "You come acroos two cabins."
    print "One of the left and one on the right"
    print "Whcih cabin do you pick?"
    print "1.left\n2.right\n"

    choice = raw_input("> ")

    if "left" in choice:
        cabin_one()
    else:
        cabin_two()

def cabin_two():
    print "You apprach the cabin on the right."
    print "You notice a note on the cabin door."
    print "Will you......"
    print "1.read the note\n2.open the door"

    choice = raw_input("> ")

    if "read" in choice:
        letter = open("note.txt", 'r')
        print letter.read()
        letter.close()
        for count in range(10, 0, -1):
            print count
        dead("The cabin explodes and you die")
    else:
        print "As you walk into the cabin"
        print "You slip on a toy car and crack you skull!"
        dead("Good job, mabey you should have read the note first!")

def cabin_one():
    print "You enter the cabin and decide to spend then night."
    print "You wake up the next morning and go outside."
    print "You notice the bight sun and a dustty trail on the ground."
    print "Will you follow the sun or follow the trail"
    print "1.follow sun\n2.follow trail"

    choice = raw_input("> ")

    if "sun" in choice:
        the_sun()
    else:
        the_path()

def the_sun():
    print "You sweet to death and die!"
    dead("Follow the path next time dummy")

def the_path():
    print "the path leads to a long road."
    print "How will you get home from here?"
    print "1.hich-hike\n2.walk the road"

    choice = raw_input("> ")

    if "hich" in choice:
        print "No bobdy comes for you."
        dead("You starve to death and die")
    else:
        print "You see civiliztion and stop at the first buger king."
        win("Congrats you win this silly game!")

def dead(msg):
    print msg + "!!!"
    exit(0)

def win(msg):
    print msg
    exit(0)

start()
\$\endgroup\$
  • \$\begingroup\$ for count in range(10, 0, -1): print count prints numbers immediately, doesn't it? It would be nice to wait a bit before printing. \$\endgroup\$ – justanothercoder Feb 27 '15 at 18:22
5
\$\begingroup\$

Your code is indented well, and appears to have no problems in this way.


When you start the game, you should have all code that would otherwise just run defined in a method like this:

if __name__ == "__main__":
    start()

You can learn about this more here: What does if __name__ == “__main__”: do?


It is very good that your main delegates all the work of starting a game to a start() method.


You should probably run your text through a spell checker, should this be "nobody", "civilization", "Burger King" (capitalized as a proper noun), and "sweat"?

"No bobdy comes for you."
"You see civiliztion and stop at the first buger king."
"You sweet to death and die!"

There are many other misspellings in here.


I would probably create a method to print the options the user has, and you can pass the options as a tuple:

def print_options(options):
    for i in range(0, len(options)):
        print str(i + 1) + ". " + options[i]

This can now be called like this:

print_options(("t1", "t2", "t3"))

Your game will be a little boring once the user has played it a couple times. There seems to be no element of randomness, so there is only one path to victory. The user won't want to lose, so once they realize this, they probably won't play your game. To defeat this problem, you should probably use a random number generator to randomly choose options, which can be weighted to give certain actions a higher probability of happening.


In start(), you recursively call start() if the user chooses to stay still. In this case, it probably is not a big deal because you don't create a bunch of variables and the user won't choose to stay still forever, but it isn't always a good idea to do this because the call will be added to the stack recursively until the stack overflows (if this point is ever reached); instead, you should use a loop to display the prompt until the user chooses to move.


Your win() and dead() methods are essentially the same. You should combine these into one method for ending the game.


When you open and read the note at cabin 2, I would not put that in a file by itself. It does not describe what the program is doing any more than just printing the note with print - in fact, I think print shows what is happening better. What it is doing is describing what the user is doing, which is very different than what the program itself is doing.

\$\endgroup\$
  • \$\begingroup\$ Do note that that def print_options(options): ... can be changed to def print_options(*options): .... This way the user doesn't have to input a list or tuple, but rather can call it like this: print_options("t1", "t2", "t3). \$\endgroup\$ – Ethan Bierlein Apr 21 '15 at 14:41
5
\$\begingroup\$

You are misusing functions as if they were goto labels. The start() function should implement the first screen and only the first screen. It should not contain your entire program.

What you should be doing instead is using an event loop like this:

func = start
while func:
    func = func()

It turns out to be slightly more complicated than that, since you also want to support passing arguments to func. Here is your game, reorganized in that way.

def start():
    print "You are in the middle of the woods alone and scared!"
    print "There is no one around but yourself."
    print "You look around and wonder....."
    print "What will you do?"
    print "1.move forward\n2.stay still"

    choice = raw_input("> ")

    if "move" in choice:
        return bear_fight, None
    else:
        print "Well your still at the same spot."
        return start, None

def bear_fight():
    print "Ahead of you is a huge hungry bear with razor sharp claws"
    print "Hes looks angry too!"
    print "Do you....."
    print "1.throw rock\n2.play dead\n3.run away\n"

    choice = raw_input("> ")

    if "run" in choice:
        print "Duhhh.... Did you think you can out run a bear?"
        return dead, "The bear catches up and has you for dinner, Good Job"
    elif "play dead" in choice:
        print "The bear laughs at you and chews but off."
        return dead, "You lost your but and lost this game"
    else:
        print "You deafted the bear with a rock! Hows that possible?"
        print "Anyways, You contine to move forward untill......"
        return cabins, None

def cabins():
    print "You come acroos two cabins."
    print "One of the left and one on the right"
    print "Whcih cabin do you pick?"
    print "1.left\n2.right\n"

    choice = raw_input("> ")

    if "left" in choice:
        return cabin_one, None
    else:
        return cabin_two, None

def cabin_two():
    print "You apprach the cabin on the right."
    print "You notice a note on the cabin door."
    print "Will you......"
    print "1.read the note\n2.open the door"

    choice = raw_input("> ")

    if "read" in choice:
        letter = open("note.txt", 'r')
        print letter.read()
        letter.close()
        for count in range(10, 0, -1):
            print count
        return dead, "The cabin explodes and you die"
    else:
        print "As you walk into the cabin"
        print "You slip on a toy car and crack you skull!"
        return dead, "Good job, mabey you should have read the note first!"

def cabin_one():
    print "You enter the cabin and decide to spend then night."
    print "You wake up the next morning and go outside."
    print "You notice the bight sun and a dustty trail on the ground."
    print "Will you follow the sun or follow the trail"
    print "1.follow sun\n2.follow trail"

    choice = raw_input("> ")

    if "sun" in choice:
        return the_sun, None
    else:
        return the_path, None

def the_sun():
    print "You sweet to death and die!"
    return dead, "Follow the path next time dummy"

def the_path():
    print "the path leads to a long road."
    print "How will you get home from here?"
    print "1.hich-hike\n2.walk the road"

    choice = raw_input("> ")

    if "hich" in choice:
        print "No bobdy comes for you."
        return dead, "You starve to death and die"
    else:
        print "You see civiliztion and stop at the first buger king."
        return win, "Congrats you win this silly game!"

def dead(msg):
    print msg + "!!!"
    return None, None

def win(msg):
    print msg
    return None, None

func, args = start, None
while func:
    if args:
        func, args = func(args)
    else:
        func, args = func()

Also note that by doing it properly like that, the loop exits naturally when the while loop condition becomes false. There is no need to have a call to sys.exit() that is buried in a function that is several layers deep in the call stack.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.