Python: If-elses inside the class "init"; It works?

I'm another newb programmer going through Learn Python the Hard Way and encountering something that I don't quite understand.

I preface this by saying that although I really enjoy his lesson plan, one unfortunate side effect seems to be that I don't understand a lot of technical talk related to the programming world. It took me two days to figure out what an “instance” is, and even now I only think that I get it, hehe. Therefore, I hope that the answer to my request has not yet been asked in a more technically descriptive way, if I wish it was superfluous.

Anyway, what I'm trying to do here is a full text adventure, using classes to describe each room. What I'm actually doing is importing my old work into this new product, more than "OOP" - doing something - converting a program that had essentially 980 lines of function calls.

So I used to have these “rooms” inside each function that would check if you met certain game goals to describe the room for you. Example:

def room_one(): if "flashlight" in pack: print "You see an exit to the NORTH and a bear to the EAST." elif "flashlight" not in pack: print "It too dark to see." 

A boring room, but a suitable description. Therefore, trying to do this with classes, I seem to hit a wall. I will show you the code that I use to define the runner game and room classes.

 class Runner(object): def __init___(self): self.goals = [] #an array for game achievements (talked_to_king, etc) self.pack = [] #an array for game items (flask, key, etc) def play(self, currentroom, gamestate): while True: print "\n--------" print currentroom.desc #this line prints the room description, could cmd = raw_input("> ") #it also be part of the problem? gamestate.state = currentroom.actions(cmd) if gamestate.state != "SAME": currentroom = gamestate.state else: pass class Room(object): def __init__(self): self.desc = "null" #short room description self.lookdesc = "super null" #longer room description for the LOOK command def actions(self, cmd): if 'help' in cmd: print """ 'look' -- see your surroundings, including exits. 'get' -- to pick up an item (if it can be picked up). 'inventory' -- displays your collected items 'throw' -- some objects can be thrown 'talk' -- speak to someone Other commands, or objects to interact with, will tend to show up IN UPPERCASE. (but still type them in lowercase!) Cardinal directions (north, south, east, west) for movement. """ return "SAME" elif 'inv' in cmd: print "--Inventory--\n" for items in game.pack: print items print "-------------\n" return "SAME" elif 'look' in cmd: print self.lookdesc return "SAME" elif 'goals' in cmd: for goal in game.goals: print goal return "SAME" else: print "That won't work here." return "SAME" class Office(Room): def __init__(self): super(Office, self).__init__() # here the part that doesn't work if 'principal' in game.goals: self.desc = "You're in the principal office, and there a zombie in here!" else: self.desc = "You're in the principal office." self.lookdesc = "The walls in here are dingy from decades of smoking.\nA door to the WEST leads back to the foyer." def actions(self, cmd): if "west" in cmd and not "principal" in game.goals: print "Buck up and talk to the old prune." return "SAME" elif "talk" in cmd: print "You call to the principal." game.goals.append('principal') next = raw_input("--Mr. Friiiiinkseseeees...--") print "But OH MY DAMN he actually a zombie now." next = raw_input("--Aww weak--") return "SAME" return super(Office, self).actions(cmd) 

To make sure that an array of “targets” was added, I set up a simple target verification function in the parent class of Room, and I'm pretty sure that the game.goals file has been added. But the if-else statement doesn't seem to do anything; no matter what in the array of goals, I always get "alienation" when I return to the room.

In fairness, to put an if-else in the init room, as if it were some kind of shot in the dark, in fact, I was surprised that I did not receive an error message telling me that it was not where it was! But the fact that he doesn't seem to care about the contents of the game.goals array tells me that this is not the best way to do this. How do I implement this?

As a subquery - with such a program, if the game mode is changed enough so that the contents of the room are drastically changed, is it better that I have a whole class for the changed room? Is it more important to maintain a “card” and say that RoomThree (Room) is always RoomThree regardless of what changes have occurred in the game system, or if by the time the game returns to RoomThree the place is broken, plundered, full of vampires and smells of salad, should it to be just completely different? I hope not, because it seems prudent that each room is simply “that room,” and let the contents of things like game.goals and game.pack change the class instance instead of just creating a new class for when they are executed certain conditions.

Anyway, it was a long time. tl; dr - Am I doing this weird?

EDIT AGAIN: Removed the main question code to meet the new code suggested by people here, also added the parent class "Room" to find out if this is a problem. There is no solution yet, but I believe the quality of the code has improved :) whee

FINAL EDIT (I hope): Yeah, the Stone answer was again most helpful. Since I was returning “the same” to my runner, he used an old copy of Office. I needed to create a completely new instance to recognize this change; returning "Office ()" instead of "SAME", I did this. Thanks to everyone for helping to not only solve the problem, but also to make the code more readable, and also to help me change my mindset regarding my if-else verbal statements. Mwah: D

+4
source share
2 answers

What happens when you have 100 numbers? Will your play function have 100 statements, just to set the room you're in? (install it again, basically)

It would probably be much better to simply configure the state of the game directly to what you want when it changes.

edit: I am just re-reading what you have now, the problem seems obvious if you have not left the vital code.

The only time you add the main question to the goal is inside the member function of the Office class. Therefore, by the time you move on to adding the principal to the goals, it’s too late, Office is already initialized and will not be reinitialized unless you create a new instance of Office. You will need to update the room description after adding this goal.

+1
source

I suppose that:

  if not 'principal' in game.goals: 

did you mean this:

  if 'principal' not in game.goals: 

or that:

  if not ('principal' in game.goals): 

not 'somestring' is False , because a non-empty string is always True , and you do not have False for your purposes, so it always evaluates False .


Where are Office objects created? Because you only check the condition for creating the object, and after that the object is added to the target, so if you use the same object again, the description will not change.

-1
source

All Articles