Last active
December 20, 2015 13:29
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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