import whrandomimport busparseimport string# declare some constantsthe = 1a = 2The = 101A = 102# function to capitalize a stringdef cap(s):	return string.upper(s[0]) + s[1:]# base type of any objectclass Thing:        	# initialization method	def __init__(self,pName):		self.name = string.split(pName,',')[0]	# main name		self.synonyms = string.split(string.lower(pName),',')		self.size = 10			# size (100=human)		self.container = None		# its location		self.desc = ''			# description		self.listening = 0		# wants Tell() calls?		self.salient = 1		# show in room contents list?		# add names to the parser's list of nouns		for n in self.synonyms:			if n not in busparse.nouns:				busparse.nouns.append(n)	# get name	def GetName(self, article=0):		if not article: return self.name		if article==the:			if hasattr(self,'the'): return self.the + ' ' + self.name			return 'the ' + self.name		if article==a:			if hasattr(self,'a'): return self.a + ' ' + self.name			return 'a ' + self.name			if article==The:			if hasattr(self,'the'): return cap(self.the) + ' ' + self.name			return 'The ' + self.name		if article==A:			if hasattr(self,'A'): return cap(self.a) + ' ' + self.name			return 'A ' + self.name	 		return self.name	# check for a name match	def NameMatch(self, pName):		return pName in self.synonyms	# get note (for when listing the contents of a room)	def GetNote(self):		if not self.salient: return ''		r = whrandom.randint(0,2)		if r == 0:			return 'You see ' + self.GetName(a) + ' lying here.'		if r == 1:			return self.GetName(A) + ' is lying here.'		if r == 2:			return 'There is '+ self.GetName(a) + ' here.'	# get description	def GetDesc(self,pDepth=0):		if self.desc != '': return self.desc		return "It looks like an ordinary " + self.GetName() + "."	# let the object hear something	def Tell(self, pWhat):		# by default, do nothing		return	# use the object	def Use(self, pByWhom):		# for a standard Thing, attempt to pick it up		pByWhom.dirobj = self.GetName()		pByWhom.cmdGET()# end of class Thing# base type of any object which can contain anotherclass Container (Thing):	# initialization method	def __init__(self,pName):		Thing.__init__(self,pName)		self.contents = []	# return true if this object can contain another	def CanContain(self,pThing):		return pThing.size < self.size;	# move the given object to the contents of this one	def ContainNoCheck(self,pThing):		if pThing.container != None:			# remove from previous container			pThing.container.contents.remove(pThing)		pThing.container = self		self.contents.append(pThing)	def GetDesc(self):		if not self.contents: return Thing.GetDesc(self)		return Thing.GetDesc(self) + '\n' + self.GetContentsDesc()	def GetContentsDesc(self):		if not self.contents: return self.GetName(The)+' is empty.'		out = 'It looks like ' + self.GetName(the) + ' contains:\n'		for item in self.contents:			out = out + '\n   - ' + item.GetName(a)		return out# end of class Container# base class of any room or locationclass Room(Container):	def __init__(self,pName):		Container.__init__(self,pName)		self.light = 75		# where 0=pitch black, 100=sunlight		self.size = 5000	def GetDesc(self, pDontNote=None):		if self.light < 20:			return "It's too dark to see.\n"		out = Thing.GetDesc(self) + '\n'		for item in self.contents:			if item != pDontNote and item.salient:				out = out + '\n  ' + item.GetNote()		return out + '\n'	def Tell( self, pWhat, pExcept=[]):		whom = filter(lambda x,n=pExcept: x.listening and x not in n, self.contents)		for i in whom: i.Tell(pWhat)# class for exits -- things which connect one room to anotherclass Exit(Thing):	def __init__(self,pName):		Thing.__init__(self,pName)		self.dest = None		# by default, no destination		self.salient = 0		# and not salient		self.size = 300			# and as big as 3 people	# move someone through the exit, if possible	def Transport(self,pWhom):		if not self.dest:			Tell(pWhom,self.GetName()+" leads nowhere.")			return		if self.size < pWhom.size or not self.dest.CanContain(pWhom):			Tell(pWhom,"You don't fit!")		# perform the move		pWhom.Announce(pWhom.GetName()+" exits to "+self.GetName(the)+".")		pWhom.Tell("You head "+self.GetName()+".")		self.dest.ContainNoCheck(pWhom)		pWhom.Announce(pWhom.GetName()+" enters the room.")		pWhom.Tell(self.dest.GetDesc(pWhom))	def Use(self, pByWhom):		self.Transport(pByWhom)# base class of any person, monster, or other chanacterclass Actor(Container):	def __init__(self,pName):		Container.__init__(self,pName)		self.size = 100			# human-sized		self.listening = 1		# wants Tell() calls		self.par = busparse.Parser()	# my very own command interpreter		self.commanding = None	# whom we're bossing around	def GetNote(self):		return self.GetName() + " is here."	def Use(self, pByWhom):		# for an Actor, being used means being given commands		pByWhom.commanding = self	def Act(self):		# by default, no action		return	def Announce(self, pWhat):		if self.container:			self.container.Tell( pWhat, [self] )	# given the name of a noun, return the visible object	def FindNoun(self,pName):		if not pName: return None		if pName == 'self' or pName == 'me': return self		if pName == 'here' or pName == 'room': return self.container		l = filter(lambda x,a=pName: x.NameMatch(a),self.contents)		if not l:		    l = filter(lambda x,a=pName: x.NameMatch(a),self.container.contents)		if l: return l[0]		return None	def DoCommand(self,cmd):		par = self.par		# just for convenience below...		while cmd:			cmd = par.Parse(cmd)			if par.verb == 'look': self.cmdLOOK()			elif par.verb == 'get' or par.verb=='take':				self.cmdGET()			elif par.verb == 'drop':				self.cmdDROP()			elif par.verb == 'inv' or par.verb == 'i':				self.cmdINV()			elif par.verb == 'put':				self.cmdPUT();			elif par.verb == 'use':				self.cmdUSE();				if self.commanding: self.commanding.DoCommand(cmd)				self.commanding = None				cmd = ''			elif par.verb == 'go':				i = self.FindNoun(self.par.dirobj)				if i: i.Transport(self)			else:				self.Tell("Unknown command.")	def cmdLOOK(self):		atwhat = None		if self.par.dirobj: atwhat = self.FindNoun(self.par.dirobj)		elif self.par.atobj: atwhat= self.FindNoun(self.par.atobj)		elif self.par.inobj:			atwhat= self.FindNoun(self.par.inobj)			if not atwhat: self.Tell('Look in what?!?')			if not hasattr(atwhat,'GetContentsDesc'):				self.Tell(atwhat.GetName(The)+' is not a container.')			else: self.Tell(atwhat.GetContentsDesc())			return		else:	# no object; describe the room			if self.container != None:				self.Tell(self.container.GetDesc(self))			else: self.Tell('You are in the Void.')			return		if atwhat:			self.Tell(atwhat.GetDesc())		else: self.Tell('Look at what?!?')	def cmdGET(self):		pWhat = None		if self.par.inobj:			pWhere = self.FindNoun(self.par.inobj)			if pWhere:				l = filter(lambda x,a=self.par.dirobj: x.NameMatch(a),pWhere.contents)			if l: pWhat = l[0]		if not pWhat: pWhat = self.FindNoun(self.par.dirobj)		if pWhat:			if pWhat.container == self:				self.Tell("You've already got that.")				return			if not self.CanContain(pWhat):				self.Tell("You can't carry that.")				return			self.ContainNoCheck(pWhat)			self.Tell('You get the ' + pWhat.GetName() + '.')			self.Announce(self.GetName() + " gets " + pWhat.GetName(a) + ".")		else: self.Tell('Get what?!?')	def cmdDROP(self):		pWhat = self.FindNoun(self.par.dirobj)		if pWhat:			if pWhat.container != self:				self.Tell("You aren't carrying that.")				return			if not self.container.CanContain(pWhat):				self.Tell("You can't drop that here.")				return			self.container.ContainNoCheck(pWhat)			self.Tell('You drop the ' + pWhat.GetName() + '.')			self.Announce(self.GetName() + " drops " + pWhat.GetName(a) + ".")		else: self.Tell('Get what?!?')	def cmdPUT(self):		pWhat = self.FindNoun(self.par.dirobj)		if not pWhat:			self.Tell('Put what?!?')			return		pWhere = self.FindNoun(self.par.inobj)		if not pWhere:			self.Tell('Put it where?!?')			return		if pWhat.container == pWhere:			self.Tell(pWhat.GetName() + ' is already in ' + pWhere.GetName(the))			return		if not pWhere.CanContain(pWhat):			self.Tell("You can't put that in " + pWhere.GetName(the) + ".")			return		pWhere.ContainNoCheck(pWhat)		self.Tell('You put the ' + pWhat.GetName() + ' in the ' + pWhere.GetName() + '.')		self.Announce(self.GetName() + " puts " + pWhat.GetName(a) + ' into ' + pWhere.GetName(a) + '.')	def cmdUSE(self):		pWhat = self.FindNoun(self.par.dirobj)		if not pWhat:			self.Tell('Use what?!?')			return		pWhat.Use(self)	def cmdINV(self):		if not self.contents: self.Tell('You are empty-handed.')		else:			self.Tell('You are carrying:')			for item in self.contents:				self.Tell('    - ' + item.GetName(a) )# end of class Actor# class of the player -- i.e., the Actor interfaced to the terminalclass Player(Actor):	def Tell(self, pWhat):		print pWhat	def Act(self):		cmd = string.lower(raw_input('>'))		self.DoCommand(cmd)# end of class Player# class parrot -- puts whatever it hears to the terminalclass Parrot(Actor):	def Tell(self,pWhat):		print '[' + self.GetName() + ' hears] ' + pWhat# create some sample objectsrock = Thing("rock,stone")bag = Container("bag,sack")bag.size = 20me = Player("Everyman")Bert = Actor("Bert,Herbert,Albert")bird = Parrot("bird,parrot,squawker")bird.size = 15here = Room("Empty Room")here.desc = "You're in an empty room.  An exit lies north."here.ContainNoCheck(bag)here.ContainNoCheck(me)here.ContainNoCheck(Bert)here.ContainNoCheck(bird)there = Room("Outside")there.ContainNoCheck(rock)here2there = Exit('north,n,out,outside,exit')here.ContainNoCheck(here2there)here2there.dest = therethere2here = Exit('south,s,in')there2here.dest = herethere.ContainNoCheck(there2here)def test():	while 1:		me.Act()