Skip to content

Instantly share code, notes, and snippets.

@AndrewDowning
Last active December 20, 2015 13:29
Show Gist options
  • Save AndrewDowning/6139247 to your computer and use it in GitHub Desktop.
Save AndrewDowning/6139247 to your computer and use it in GitHub Desktop.
Rooms - My fun way to do the Rooms Python project that Aaron had to do at school.
import csv
class Command(object): # Decorator for command functions in Rooms class.
Functions = {} # Builds dict of command functions {name:function}
HelpText = {} # Builds dict of help text {name:helptext}
def __init__(self, helpText):
self.HelpText = helpText
def __call__(self, f):
Command.Functions[f.__name__] = f
Command.HelpText [f.__name__] = self.HelpText
return f
class Room(object): # A Room with knowledge of neighbouring rooms.
def __init__(self, roomNum, roomName, n,s,e,w,u,d, roomDesc):
self.roomNum = roomNum
self.roomName = roomName
self.neighbours = map(int, [n,s,e,w,u,d])
self.roomDesc = roomDesc
self.sshFlag = False
def linkNeighbours(self, rooms, directions): # Convert neighbours from tuple of room numbers into dict of Room by direction.
self.neighbours = {direction:rooms[nextRoom] for direction, nextRoom in zip(directions, self.neighbours) if nextRoom}
def adjacentRoom(self, direction): # Returns room in direction, else None.
return self.neighbours.get(direction, None)
def describeRoom(self): # Returns a description of the room
description = self.roomName + ("\n"+self.roomDesc if not Rooms.sshMode or not self.sshFlag else "")
self.sshFlag = True # Don't print room description if in 'ssh' mode and previously printed.
return description
class Rooms(list): # The Rooms game, built on a self(list) of rooms.
directions = ["north", "south", "east", "west", "up", "down"]
def __init__(self, csvFileName):
list.__init__(self,(None,)) # Room zero is non-room
for row in csv.reader(open(csvFileName), delimiter=','): # Load the room data from CSV file
self.append(Room(len(self), *row))
for room in self[1:]: # Make neighbours index-able by direction name
room.linkNeighbours(self, Rooms.directions)
self.currentRoom = self[1] # Always starts in room 1
self.sshMode = False
def doCommand(self, command): # Try to do the command they typed
try:
Command.Functions[command[0]] (self,*command[1:])
except KeyError: # No function for the command typed.
self.help("all")
except TypeError: # Parameters to the function don't match.
self.help(command[0])
@Command("help ! provide help for a command by name or 'all'")
def help(self, command):
if command == "all":
print("Valid commands are:\n " + "\n ".join(Command.HelpText[command] for command in sorted(Command.HelpText.keys())))
else:
print(Command.HelpText.get(command, "%s is not a command"%command))
@Command("go <direction> ! May be any of " + ",".join(directions))
def go(self, direction):
adjacentRoom = self.currentRoom.adjacentRoom(direction)
if adjacentRoom is None:
print("Can't go in that direction.")
else:
self.currentRoom = adjacentRoom
print("You are now in", self.currentRoom.describeRoom())
@Command("look <direction> ! May be any of " + ",".join(directions))
def look(self, direction):
adjacentRoom = self.currentRoom.adjacentRoom(direction)
print(("Looking %s, you see " % direction) + adjacentRoom.describeRoom() if adjacentRoom else "Nothing to see in that direction.")
@Command("ssh ! Turns on 'ssh' mode so descriptions are only shown once.")
def ssh(self):
self.sshMode = True
@Command("verbose ! Turns off 'ssh' mode so descriptions are always shown")
def verbose(self):
self.sshMode = False
@Command("save <name> ! Saves current game as <name>")
def save(self, name):
csv.writer(open(name+'.csv', 'w')).writerow([self.currentRoom.roomNum, self.sshMode])
@Command("load <name> ! Loads saved game from <name>")
def load(self, name):
(roomNum, self.sshMode) = next(csv.reader(open(name+'.csv')))
self.currentRoom = self[int(roomNum)]
@Command("quit ! Exits the game")
def quit(self):
print("Nice playing with you. See you later.")
self.currentRoom = None # Flags exit.
Rooms = Rooms("rooms.csv")
print("You start out in", Rooms.currentRoom.describeRoom())
while Rooms.currentRoom:
command = None
while not command:
command = input("> ").lower()
Rooms.doCommand(tuple(command.split()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment