Python printing an Else statement when not supposed to [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
I'm having trouble trying to get a game creation exercise to stop printing the else statement (at the bottom of the code block). the idea is, you can navigate from room to room, but if you go in a direction you're not supposed it should tell you. However, it seems to be doing that even when you CAN go somewhere. I'd greatly appreciate any advice.
Code is below:
class Room:
number_of_rooms = 0
def __init__(self, room_name):
self.name = room_name
self.description = None
self.linked_rooms = {}
self.character = None
Room.number_of_rooms = Room.number_of_rooms + 1
def set_description(self, room_description):
self.description = room_description
def get_description(self):
return self.description
def set_name(self, room_name):
self.name = room_name
def get_name(self):
return self.name
def describe(self):
print(self.description)
def set_character(self, new_character):
self.character = new_character
def get_character(self):
return self.character
def describe(self):
print( self.description )
def link_room(self, room_to_link, direction):
self.linked_rooms[direction] = room_to_link
def get_details(self):
print(self.name)
print("--------------------")
print(self.description)
for direction in self.linked_rooms:
room = self.linked_rooms[direction]
print( "The " + room.get_name() + " is " + direction)
def move(self, direction):
if direction in self.linked_rooms:
return self.linked_rooms[direction]
else:
print("You can't go that way")
return self
I would greatly appreciate any advice on this, it's maddening. I just need it to stop printing "You can't go that way" when you can. It actually does work, it just insist on printing it every time you go into a new room as well as when you can't.
This is the code it links to
foyer = Room("foyer")
ballroom = Room("ballroom")
dining_hall = Room("dining hall")
kitchen = Room("kitchen")
foyer.link_room(ballroom, "south")
ballroom.link_room(foyer, "north")
ballroom.link_room(dining_hall, "east")
dining_hall.link_room(ballroom, "west")
dining_hall.link_room(kitchen, "north")
kitchen.link_room(dining_hall, "south")

If you add the following test code to the end of your class (assuming that it is inside a module Room.py):
if __name__ == "__main__":
print("Testing")
# rooms
room1 = Room("Floor")
room2 = Room("Kitchen")
room3 = Room("Living Room")
# link the rooms
room2.link_room(room1, "left")
room3.link_room(room1, "right")
# move
room2.move("up") # not allowed
room3.move("right") # should be possible
Then you can run the test code directly if you execute the module.
Now if you are in room 3 (living room) it is possible to get out on the right.
But if you are in room 2 (kitchen) you can only move to the left.
The test prints "You can't go that way" only if you do a move like room2.move("up") which is correct, because only "left" is allowed. Comment that line and you won't see that message any more.
According to this test, the class is behaving as it should. Note that you could (and should!) also write a unit test from the example I gave, asserting the expected output.
Update:
In your example, allowed moves are:
# allowed
kitchen.move("south")
dining_hall.move("north")
ballroom.move("east")
foyer.move("south")
And examples for not allowed moves are:
# not allowed
kitchen.move("west")
dining_hall.move("east")
ballroom.move("south")
foyer.move("north")
For these you will get "You can't go that way".
Maybe the issue you had was that you were using objects rather than strings as parameter to describe the direction.
For example, this will always fail (printing "You can't go that way"):
foyer.move(ballroom) # param should be a string, not an object
To prevent this kind of error, you could add a check to the move method:
def move(self, direction):
if not isinstance(direction, str):
raise ValueError("Direction needs to be a string!")
if direction in self.linked_rooms:
return self.linked_rooms[direction]
else:
print("You can't go that way")
return self
With that addition, the application will throw an exception, if you pass an object and not a string:
ValueError: Direction needs to be a string!
For interactive testing, you could use this code:
new_dir = "nop"
current_room = foyer
while new_dir != "":
print("current room: " + current_room.name)
print("please enter direction:")
new_dir = input()
if new_dir == "":
print("leaving")
break
new_room = current_room.move(str(new_dir))
if new_room != current_room:
print("moving to: " + new_room.name)
current_room = new_room
For debugging, it might be also helpful if you add the following code to the top of the module:
def Log(func):
def inner(*args, **kwargs):
print(f"Logging {str(func)}: {args[1:]}")
result = func(*args, **kwargs)
print(f"Result: {str(result)}")
return result
return inner
Now you can decorate any of the functions with the #Log attribute like so:
#Log
def __init__(self, room_name):
...
#Log
def move(self, direction):
...
Whenever such a decorated function is called, it will print it to the console, e.g.:
please enter direction:
south
Logging <function Room.move at 0x000001994B97C720>: ('south',)
Result: <main.Room object at 0x000001994B97A150>
moving to: ballroom
current room: ballroom
please enter direction:
If you're done with debugging, you can comment out the attributes (# #Log) to remove the extra print outs.

Related

Why am i getting this error trying to add trap to my textRPG

I have been trying to add traps to my TextRPG I have something I think will work with a little bit of debugging but the first bug that I ran into is.
TypeError: init() should return None, not 'str'
the error is coming from this.
class TrapRoomTile(MapTile):
def __init__(self, x, y):
r = random.randint(1,2)
if r == 1:
self.trap = items.PitFall()
self.tripped_text = "The open hole of a Pit Fall trap obstructs the tunnel."
self.set_text = "The floor in this hallway is unusually clean."
else:
return"""
Looks like more bare stone...
"""
super().__init__(x, y)
def modify_player(self,player):
if not self.trap.is_tripped():
player.hp = player.hp - self.items.damage
print("You stumbled into a trap!")
time.sleep(1)
print("\nTrap does {} damage. You have {} HP remaining.".
format(self.items.damage, player.hp))
def intro_text(self):
text = self.tripped_text if self.items.is_tripped() else self.set_text
time.sleep(0.1)
return text
when i comment out this block of code everything runs as it should. I'm at a loss as to what to do about it. ill post a link to the github repo the code is in world.py starts on line 146.
https://github.com/GusRobins60/AdventureGame.git
The __init__ method in python should only used be used to initialize the class variables. You are returning a string from it, which you should not do.
You can either remove the return statement or set the string to another variable. Here is an example of what you can probably do:
class TrapRoomTile(MapTile):
def __init__(self, x, y):
r = random.randint(1,2)
if r == 1:
self.trap = items.PitFall()
self.tripped_text = "The open hole of a Pit Fall trap obstructs the tunnel."
self.set_text = "The floor in this hallway is unusually clean."
else:
self.set_text = "Looks like more bare stone..."
super().__init__(x, y)
def modify_player(self,player):
if not self.trap.is_tripped():
player.hp = player.hp - self.items.damage
print("You stumbled into a trap!")
time.sleep(1)
print("\nTrap does {} damage. You have {} HP remaining.".
format(self.items.damage, player.hp))
def intro_text(self):
text = self.tripped_text if self.trap.is_tripped() else self.set_text
time.sleep(0.1)
return text

Text-based RPG: How to apply cool downs to user input

Let's say I have a spell named heal. How can I prevent a user from spamming heal every time they are damaged. I have considered applying this to individual combat functions; however, I am not sure how to implement a global rule for this? This code may clear it up:
available_spells = ['fireball', 'heal']
equipped = {'Weapon': "Staff",
'Armor': "Robes",
'Spells': ['fireball', 'heal']}
print "Your available spell(s) is(are) '%s'. " % equipped["Spells"]
inp = raw_input("Type the name of a spell you want to use.: ").lower()
lst = [x for x in available_spells if x.startswith(inp)]
if len(lst) == 0:
print "No such spell"
print ' '
elif len(lst) == 1:
spell = lst[0]
print "You picked", spell
#COMBAT FUNCTIONS HERE
else:
print "Which spell of", equipped["Spells"], "do you mean?"
If I were to make a class that defines certain actions for spells to take, how could I implement that into the code I have? For example if I have a class of spells, with functions defining damage rules, cool down times, etc., how could I reference that function in the code I already have? i.e. the player types 'heal' and I want it to reference an above class that has those values defined to check if the player recently played the spell, and what it does when played.
Am I clear enough in this question? How should I write a spell cool-down mechanic? How can I implement this mechanic into the code above?
Instead of storing all available spells as a list, you could store them as a dictionary, which allows you to also store the desired cooldown duration:
available_spells = {
# spell name: cooldown duration in seconds
'fireball': 3.0,
'heal': 5.0,
}
Each player could have another dict that keeps track of the last time they cast each spell. When the game starts, it would be empty:
cast_spells = {}
When the player attempts to cast a spell, check if the spell name is in the cast_spells dict. If it's not, then they have not yet cast it this game, so they are allowed to cast it:
if spell_name not in cast_spells:
cast_spells[spell_name] = datetime.now()
Otherwise, if the spell name is in the cast_spells dict, check if the required cooldown has elapsed:
elif cast_spells[spell_name] + datetime.timedelta(seconds=spells[spell_name]) < datetime.now():
cast_spells[spell_name] = datetime.now()
Otherwise, the cooldown is still in effect.
else:
print 'Spell not ready.'
I would probably do it using with, an exception handler, and a simple timer. That way you can just repeat the cooldown pattern, have shared cooldowns (like shown below), or even global cooldowns, etc.
Here are the classes:
import time
class CooldownException(Exception):
pass
class Cooldown(object):
def __init__(self, seconds):
self.seconds = seconds
self.expire = None
def __enter__(self):
if not self.expire or time.time() > self.expire:
self.expire = time.time() + self.seconds
else:
raise CooldownException('Cooldown not expired!')
def __exit__(self, type, value, traceback):
pass
heal_cooldown = Cooldown(5)
def heal():
try:
with heal_cooldown:
print 'You heal yourself!'
except CooldownException as e:
print e
def apply_bandage():
try:
with heal_cooldown:
print 'You bandage yourself!'
except CooldownException as e:
print e
def drink_potion():
try:
with heal_cooldown:
print 'You quaff a potion!'
except CooldownException as e:
print e
And here's how they're used:
>>> heal()
You heal yourself!
>>> time.sleep(3)
>>> drink_potion()
Cooldown not expired!
>>> time.sleep(3)
>>> apply_bandage()
You bandage yourself!
If I were to make a class that defines certain actions for spells to take, how could I implement that into the code I have?
As you guessed, your problem is very well suited to classes.
Am I clear enough in this question?
Yes.
Your program, but with classes
Here is your program modified to use two custom classes, FireballSpell and HealSpell. Each one has a .name, which is a string, and a .cast(), which is a custom behaviour. It's nearly identical to your original code, so it should be easy for you to understand:
available_spells = [FireballSpell(), HealSpell()]
equipped = {'Weapon': "Staff",
'Armor': "Robes",
'Spells': [FireballSpell(), HealSpell()]}
while True:
print "Your available spell(s) is(are) '%s'. " % [spell.name for spell in equipped["Spells"]]
inp = raw_input("Type the name of a spell you want to use.: ").lower()
lst = [spell for spell in available_spells if spell.name.startswith(inp)]
if len(lst) == 0:
print "No such spell"
print ' '
elif len(lst) == 1:
spell = lst[0]
print "You picked", spell.name
spell.cast()
else:
print "Which spell of", [spell.name for spell in equipped["Spells"]], "do you mean?"
print ""
Run it and give it a try! Here is the complete script. I'm pretty sure it does exactly what you want.
Specific spells
Each specific class has a name, cooldown time, and specific behaviour. The parent Spell class (see bottom) handles the rest.
class FireballSpell(Spell):
def __init__(self):
self.name = "fireball"
self.cooldown_seconds = 5
def spell_specific_behaviour(self):
# do whatever you like with fireball
# this is only called if the spell has cooled down
print "casting fireball"
class HealSpell(Spell):
def __init__(self):
self.name = "heal"
self.cooldown_seconds = 10
def spell_specific_behaviour(self):
# same applies here as from FireballSpell
print "casting heal"
Spell class
This is a generic Spell class - the parent of all spells. It knows the name, cooldown time, and behaviour from the specific spells (child classes above). It also has generic cooldown mechanic that's shared by the spells:
class Spell:
# spell data - filled in by specific spells
name = "default"
cooldown_seconds = 0
last_cast_time = 0
def cast(self):
# only cast the spell if it has cooled down
if self.is_cooled_down():
# call the behaviour set by the specific spell
self.spell_specific_behaviour();
# set the last cast time to the current time
self.last_cast_time = time.time()
else:
print self.name + " has not cooled down yet!"
def spell_specific_behaviour(self):
# implement in specific spell subclasses
return
def is_cooled_down(self):
current_time_seconds = time.time()
cooldown_expire_time_seconds = self.last_cast_time + self.cooldown_seconds
return current_time_seconds > cooldown_expire_time_seconds
Again, here is the whole thing in one working script. Have fun!
META: decorators, exceptions, and with blocks? Whoa, guys. OP is just now learning about classes. Let's keep it simple here.
Here is another example using decorators...
from functools import wraps
class Cooldown(object):
def __init__(self, seconds, cooldown_message):
self.seconds = seconds
self.expire = None
self.cooldown_message = cooldown_message
def decorator(self, fail_message_callback):
def _wrap_decorator(foo):
def _decorator(*args, **kwargs):
if not self.expire or time.time() > self.expire:
self.expire = time.time() + self.seconds
result = foo(*args, **kwargs)
return result
else:
if fail_message_callback:
fail_message_callback(self.cooldown_message)
return None
return wraps(foo)(_decorator)
return _wrap_decorator
heal_cooldown = Cooldown(5, 'Cooldown not expired!')
def display(message):
print message
#heal_cooldown.decorator(display)
def heal():
display('You heal yourself!')
#heal_cooldown.decorator(display)
def apply_bandage():
display('You bandage yourself!')
#heal_cooldown.decorator(display)
def drink_potion():
display('You quaff a potion!')
heal()
time.sleep(3)
drink_potion()
time.sleep(3)
apply_bandage()

How can I turn a user input into a global function? (Python)

I'm trying to create my own text game, as instructed in Ex 45 of Learning Python the Hard Way, but I'm a bit stuck. I have my own inventory system set up and I need to figure out how to display a list of the inventory any time the user types "inventory" (I also want to do similar things for "help")... I know that I could add an if-statement after every raw_input for it, but I wanted to see if there was some global function or code that I could use to make this a lot easier on me.
I've searched and searched but I have no idea how to phrase the question or what I could possibly do to fix this. Here's my inventory set-up, with how I'm using to call it:
class Item(object):
def __init__(self, name, quantity=1):
self.name = name
self.raw = name.strip().lower()
self.quantity = quantity
def recalc(self):
self.netValue = self.quantity * self.value
class Container(object):
def __init__(self, name):
self.name = name
self.inside = {}
def __iter__(self):
return iter(self.inside.items())
def __len__(self):
return len(self.inside)
def __contains__(self, item):
return item.raw in self.inside
def __getitem__(self, item):
return self.inside[item.raw]
def __setitem__(self, item, value):
self.inside[item.raw] = value
return self[item]
def add(self, item, quantity=1):
if quantity < 0:
print "ERROR."
if item in self:
self[item].quantity += quantity
self[item].recalc()
else:
self[item] = item
inventory = Container("Inventory")
And here's what I'm using to call it when inventory is typed:
print "Inventory: [" + ",".join((item[1].name for item in inventory)) + "]"
You could create a function for each valid user input, such as inventory
Then, you could do:
input = raw_input('...')
self.method = getattr(<your class>, input)
self.method()
which would call
def inventory(self, ...):
pass
you could use a dictionary combined with lambdas, this would be compact and fast
from __future__ import print_function
#store commands
inputLookup = {"Inventory" : lambda: print ("Inventory: [" + ",".join((item[1].name for item in inventory)) + "]"), "other text" : lambda: 3} #and so on
text = input() #replace with hover you get input
inputLookup[text]() # call the function from dictionary at that command
the import will change all your print statements to a print() however.
For lambdas you can also do.
def f():
print "Inventory: [" + ",".join((item[1].name for item in inventory)) + "]"
inputLookup = {"Inventory": lambda: f()}
text = input()
try:
inputLookup[text]
except:
print "that is not a valid input" #or something
this will allow you to use the old print statment
yes, you should never use recursion to the same function in this manner, you'll generate a large stack. Also, those print statements are in a weird place.
def func1():
print "Uh oh."
print "You're outside the house and it's quiet."
print "You EXAMINE and find a ROCK."
While True:
userinput1 = raw_input(">>> ")
if userinput1 == "inventory":
print "Inventory: [" + ",".join((item[1].name for item in inventory)) + "]"
elif userinput1 == "pick up":
if rock not in inventory: # so they can't pick up infinite rocks
inventory.add(rock)
print "You picked up a ROCK."
else:
print "you've already picked up the rock"
elif userinput1 == "examine":
print "Man's best friend."
else:
print "Let's go on about our way then."
break
I failed to see you were just starting out. I would stay away from lambda's for the moment, as they're a bit more advanced, sorry for the confusion. Before, if you look at your if/elif/else tree, there was no way for the else statement to be called, so i've edited it a bit, i hope it functions the way you intended. Also, are inventory and rock globals? if not you would need to declare or reference them in the function. (although as a future note, staying a way from globals is generally good)
hmm...i assume you mean items like the rock and such.
Items = {'rock': Rock(), 'item2': Item2(), 'item3' : item3()} #where Item() is creating the object
Inventory.add(Items[itemname]) # adds the item
You could make Items as a global so you can access it everywhere. This is ok for now, but as you learn, you should generally stay away from globals.

Modifying a function from another in python

For an online course in python, I'm making a basic text-based adventure game in python.
Right now, I have a rudimentary inventory system that works through booleans for if the user has an object or not, and integers for limited items, such as ammo and whatnot.
Here is the code for the inventory system
def Inventory(self): #The inventory for the game. I don't know how to program it properly, so this is my testing ground.
#This will hold the boolean values to if the player has the items or not. Another will be used to show the user the items
street_clothes = False
pistol = False
ammo = 0
phone = False
And this is the code where I am trying to modify the inventory function above
#Eric's apartment
def Eric_Apartment(self):
print "type in grab your gun"
action = raw_input("> ")
if action == "grab":
self.Inventory(CR97) = True
# self.CR97_ammo += 15
# print CR97_ammo
# print self.CR97_ammo
exit(1)
Attempting to run this program gets me this error:
python ex43.py
File "ex43.py", line 78
self.Inventory(CR97) = True
SyntaxError: can't assign to function call
Is there something else I'm supposed to do? I'm very new to python, and this is my first project on my own.
Here is the entire code, for reference
from sys import exit #allows the program to use the exit(1) code
from random import randint #allows the program to use a random number
class Game(object):
#quotes that pop up if the person dies, and also defines the start and self variables
def __init__(self, start):
self.quips = [
"You lose!"
]
self.start = start
def Inventory(self): #The inventory for the game.
#This will hold the boolean values to if the player has the items or not.
street_clothes = False
pistol = False
ammo = 0
phone = False
#this function launches the game, and helps with the room transfer
def play(self):
next = self.start
while True:
print "\n---------"
room = getattr(self, next)
next = room( )
#if the user dies, or fails at the game, this is the function that is ran
def death(self):
print self.quips[randint(0, len(self.quips)-1)]
exit(1)
#Welcome screen to the game
def welcome_screen(self):
print " place holder"
return 'intro_screen'
#Intro screen to the game
def intro_screen(self):
print "place holder"
action = raw_input("> Press any key to continue ")
return 'Eric_Apartment'
#Eric's apartment
def Eric_Apartment(self):
print "type in grab your gun"
action = raw_input("> ")
if action == "grab":
self.Inventory(CR97) = True
# self.CR97_ammo += 15
# print CR97_ammo
# print self.CR97_ammo
exit(1)
a_game = Game("welcome_screen")
a_game.play()
That's an amazingly perverse way to go about it. Why are you using a function to store data?
Just have a player object, with an inventory array.
I'd recommend using objects to model items too. Good use for for a class hierarchy. COuld have a base Item, with Subclasses SingleItem and StackableItem, etc.
Instead of using a function, try using a class -
class Player:
def __init__(self):
self.street_clothes = False
self.pistol = False
self.ammo = 0
self.phone = False
def give_street_clothes(self):
self.street_clothes = True
# etc
But personally, instead of using each item as a boolean, I'd use a list of items:
class Player:
def __init__(self):
self.inventory = []
# add code for ammo/pistol
def has_item(self, item):
return item in self.inventory
def give_item(self, item):
self.inventory.add(item)
def remove_item(self, item):
self.inventory.remove(item)
# etc

How can I use a returned value to open up another instance of a class in Python?

I am on exercise 43 doing some self-directed work in Learn Python The Hard Way. And I have designed the framework of a game spread out over two python files. The point of the exercise is that each "room" in the game has a different class. I have tried a number of things, but I cannot figure out how to use the returned value from their initial choice to advance the user to the proper "room", which is contained within a class. Any hints or help would be greatly appreciated.
Apologies for the poor code, I'm just starting out in python, but at my wit's end on this.
Here is the ex43_engine.py code which I run to start the game.
from ex43_map import *
import ex43_map
import inspect
#Not sure if this part is neccessary, generated list of all the classes (rooms) I imported from ex43_map.py, as I thought they might be needed to form a "map"
class_list = []
for name, obj in inspect.getmembers(ex43_map):
if inspect.isclass(obj):
class_list.append(name)
class Engine(object):
def __init__(self, room):
self.room = room
def play(self):
# starts the process, this might need to go inside the loop below
next = self.room
start.transportation_choice()
while True:
print "\n-------------"
# I have tried numerous things here to make it work...nothing has
start = StartRoom()
car = CarRoom()
bus = BusRoom()
train = TrainRoom()
airplane = AirplaneRoom()
terminal = TerminalRoom()
a_game = Engine("transportation_choice")
a_game.play()
And here is the ex43_map.py code
from sys import exit
from random import randint
class StartRoom(object):
def __init__(self):
pass
def transportation_choice(self):
print "\nIt's 6 pm and you have just found out that you need to get to Chicago by tomorrow morning for a meeting"
print "How will you choose to get there?\n"
print "Choices: car, bus, train, airplane"
choice = raw_input("> ")
if choice == "car":
return 'CarRoom'
elif choice == "bus":
return 'BusRoom'
elif choice == "train":
return 'TrainRoom'
elif choice == "airplane":
return 'AirplaneRoom'
else:
print "Sorry but '%s' wasn't a choice." % choice
return 'StartRoom'
class CarRoom(object):
def __init__(self):
print "Welcome to the CarRoom"
class BusRoom(object):
def __init__(self):
print "Welcome to the BusRoom"
class TrainRoom(object):
def __init__(self):
print "Welcome to the TrainRoom"
class AirplaneRoom(object):
def __init__(self):
print "Welcome to the AirplaneRoom"
class TerminalRoom(object):
def __init__(self):
self.quips = [
"Oh so sorry you died, you are pretty bad at this.",
"Too bad, you're dead buddy.",
"The end is here.",
"No more playing for you, you're dead."
]
def death(self):
print self.quips[randint(0, len(self.quips)-1)] # randomly selects one of the quips from 0 to # of items in the list and prints it
exit(1)
Instead of returning a string try returning an object, ie
if choice == "car":
return CarRoom()
It might be a good idea to make a Room class, and derive your other rooms from it.
The Room base class can then have a class variable which automatically keeps track of all instantiated rooms.
I haven't thoroughly tested the following, but hopefully it will give you some ideas:
# getters.py
try:
getStr = raw_input # Python 2.x
except NameError:
getStr = input # Python 3.x
getStr.type = str
def typeGetter(dataType):
def getter(msg):
while True:
try:
return dataType(getStr(msg))
except ValueError:
pass
getter.type = dataType
return getter
getInt = typeGetter(int)
getFloat = typeGetter(float)
getBool = typeGetter(bool)
def getOneOf(*args, **kwargs):
"""Get input until it matches an item in args, then return the item
#param *args: items to match against
#param getter: function, input-getter of desired type (defaults to getStr)
#param prompt: string, input prompt (defaults to '> ')
Type of items should match type of getter
"""
argSet = set(args)
getter = kwargs.get('getter', getStr)
prompt = kwargs.get('prompt', '> ')
print('[{0}]'.format(', '.join(args)))
while True:
res = getter(prompt)
if res in argset:
return res
.
# ex43_rooms.py
import textwrap
import random
import getters
class Room(object):
# list of instantiated rooms by name
ROOMS = {}
#classmethod
def getroom(cls, name):
"""Return room instance
If named room does not exist, throws KeyError
"""
return cls.ROOMS[name]
def __init__(self, name):
super(Room,self).__init__()
self.name = name
Room.ROOMS[name] = self
def run(self):
"""Enter the room - what happens?
Abstract base method (subclasses must override)
#retval Room instance to continue or None to quit
"""
raise NotImplementedError()
def __str__(self):
return self.name
def __repr__(self):
return '{0}({1})'.format(self.__class__.__name__, self.name)
class StartRoom(Room):
def __init__(self, name):
super(StartRoom,self).__init__(name)
def run(self):
print textwrap.dedent("""
It's 6 pm and you have just found out that you need to get to Chicago
by tomorrow morning for a meeting! How will you get there?
""")
inp = getters.getOneOf('car','bus','train','airplane')
return Room.getroom(inp)
class CarRoom(Room):
def __init__(self,name):
super(CarRoom,self).__init__(name)
class BusRoom(Room):
def __init__(self,name):
super(BusRoom,self).__init__(name)
class TrainRoom(Room):
def __init__(self,name):
super(TrainRoom,self).__init__(name)
class PlaneRoom(Room):
def __init__(self,name):
super(PlaneRoom,self).__init__(name)
class TerminalRoom(Room):
def __init__(self,name):
super(TerminalRoom,self).__init__(name)
def run(self):
print(random.choice((
"Oh so sorry you died, you are pretty bad at this.",
"Too bad, you're dead buddy.",
"The end is here.",
"No more playing for you, you're dead."
)))
return None
# create rooms (which registers them with Room)
StartRoom('start')
CarRoom('car')
BusRoom('bus')
TrainRoom('train')
PlaneRoom('airplane')
TerminalRoom('terminal')
.
# ex43.py
from ex43_rooms import Room
def main():
here = Room.getroom('start')
while here:
here = here.run()
if __name__=="__main__":
main()

Categories

Resources