1

As many other askers on this site seem to be doing, I am using Learn Python the Hard Way to, well, learn Python.

I am on Lesson 36, in which we create our own BBS-style text game based on the one he led us through in Lesson 35.

http://learnpythonthehardway.org/book/ex36.html

http://learnpythonthehardway.org/book/ex35.html

I wanted to up the "difficulty" of the game, so I made the maze a little more complex. Instead of one entrance in and one out of each room, some rooms have multiple doors. Some of those doors lead to nothing, but some rooms can be entered from multiple rooms within the map.

So, in the monster_room, the player can enter via the monkey_room or the empty_room. The problem is, the monster_room runs the same code, no matter where the player enters from. Since I built the empty_room first, the door choices and results are based on that room.

Here's the monster_room code:

def monster_room():
    print "You have stumbled into a dark room with a giant, but friendly, monster."
    print "There are four doors:"
    print "One straight ahead, one to your right, one to your left, and the one you just entered through."
    print "Which door would you like to choose?"

    door = raw_input("> ")

    if "left" in door:
        dead("The door magically recedes into the wall behind you and you find yourself forever trapped in a black room with no doors, no windows, and no hope of escape.")
    elif "right" in door:
        monkey_room()
    elif "straight" in door:
        dead("You step into the abyss and fall through nothingness to your certain death.")
    else:
        print "You found a magical shortcut to the Treasure Room!"
        treasure_room()

Okay, so pretty simple, right? But, if someone enters from the monkey room, the positions of the doors is different. Left would lead to the empty room, right to the abyss, straight to trapped forever, and back the way you came still a magical shortcut.

I know I could just create a monster_room_2 or something that would only be entered from the monkey_room and have all the doors in the "right place", but I thought there might be a way to have the game give options based on the function that sent them there. Does that make sense?

Any help would be greatly appreciated.

7
  • Perhaps you could have a came_from parameter for each room, indicating which room you were just in. Then you have if came_from == "monkey_room":, followed by your if/elif/else blocks, then an elif came_from == "empty room":, followed by another if/elif/else block. It could get quite tedious to write -- requiring up to 16 conditionals if the room can be entered from all four directions -- but it's not particularly difficult. Commented Aug 11, 2014 at 18:36
  • 2
    By the way, your program is liable to crash with a "maximum recursion depth exceeded" error after the user explores 999 rooms. This is a common pitfall among Python programmers experimenting with text adventures. It happens whenever you have a lot of room functions, all of which call another room function. Commented Aug 11, 2014 at 18:44
  • That makes sense...and probably would be tedious, but less messy than having several duplicate rooms. What would I use to let the came_from function to know which room sent the user into the current room? Commented Aug 11, 2014 at 18:45
  • Got it, so there is a limit to the size of these things. What do folks do to get around that limit? I guess there are ways to do this without relying on nothing but functions calling on other functions? Commented Aug 11, 2014 at 18:46
  • 1
    One possible alternative design is to return the next room, rather than calling it directly. Then the code that called the previous room calls the next room in turn. This prevents the stack from growing too large and crashing. Here is a revised version of exercise 35, that uses this design. (Using functions as objects in this way is a little more advanced than what Learn Python The Hard Way intends to cover in that chapter, so don't worry too much if you find it confusing) Commented Aug 11, 2014 at 18:56

1 Answer 1

2

You could just set a global value for the current room and then use that.

CURRENT_ROOM = "whatever"

def monster_room():
    global CURRENT_ROOM
    if CURRENT_ROOM = "monkey":
        """Display monkey room choices""" 
    else:
        """display other room choices"""
    # don't forget to set your global to the room selected:
    CURRENT_ROOM = new_room

You could certainly use the function instead of strings if you like:

CURRENT_ROOM = monkey_room

However, global variables are a code smell. You're going to be better off using a class, and/or passing the current room in as a variable.

I'd do something like:

class Game:
    def __init__(self):
        self.current_room = self.initial_room

    def initial_room(self):
        ...

    def monster_room(self):
        ...

    def monkey_room(self):
        ...

    def display_room(self):
        self.current_room()

So in the game "loop" you'd create an instance of Game and use it to help keep track of where you are currently and things like that.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the reply. I'm trying to keep it to only what we've learned so far (but stretching that as much as possible so I really understand it), so I'm gonna put using class on the shelf until we hit that lesson. :) However, with the global variable, that is basically the same as, say, setting current_room at the start, then each time I enter a room, before it starts the if-statement, setting last_room = current_room then current_room = new_room, right? Using the global variable just eliminates the redundancy of having to type that each time?
Sort of. The key thing is that you need to have some memory about where you were last and/or where you are now. There are a ton of ways to do this and it all depends on the structure of your actual code. Globals are probaby the simplest and hackiest way to do maintain some game state, hence the suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.