In many cases these ‘games’ were written in the low level language du jour, such as ‘C’, or in a custom language like ‘Inform’ (in the case of Infocom games) which was also written in ‘C’. There were languages which would’ve been better suited for these games/simulations, object oriented programming (OOP) languages such as Smalltalk, or Objective-C, but they were generally not utilised as such.
Recently in my workplace I have been developing full time (for the past couple of years) in Python, a wonderful high level language written by Guido van Rossum which is a proper OOP language. As such, the idea of writing a simulation (not a ‘game’ per se) which would allow me to focus on not only how one would model the real world (to a certain depth), but as an exercise in python objects.
While the code is still an ongoing side work of mine, I am posting the parent class (SimObject) and it’s associated child classes (Place, Person and ExitObject) for review by those who are interested. Please note that due to certain conflicts with word press, proper pythonic indentation (required for execution) is not established as such.
#####################################################
# S I M O B J E C T C L A S S #
#####################################################
class SimObject:
object_master_list=[]
def __init__(self,
object_id = 0,
object_sku = 0,
short_description = 'Short Description',
long_description = 'Long Description',
name = 'Name',
weight = 1.0,
height = 1.0,
width = 1.0,
depth = 1.0,
visible = True,
closed = False,
contents = [],
stack = []):
self._object_id = object_id
self._object_sku = object_sku
self._short_description = short_description
self._long_description = long_description
self._name = name
self._weight = weight
self._height = height
self._width = width
self._depth = depth
self._visible = visible
self._closed = closed
self._contents = []
self._stack = []
self.object_master_list.append(self)
def getObjectById(self,object_id):
for sim_objects in self.object_master_list:
if sim_objects.getObjectId() == object_id:
return sim_objects
def addContents(self,item):
try:
self._contents.append(item)
return True
except:
return False
def addToStack(self,item):
try:
self._stack.append(item)
return True
except:
return False
def isVisible(self):
return self._visible
def getContents(self):
return self._contents
def getShortDescription(self):
return self._short_description
def getLongDescription(self):
return self._long_description
def getSize(self):
return "Object Details ... Weight: %.2f, Height: %.2f, Width: %.2f, Depth: %.2f" % (self._weight, self._height, self._width, self._depth)
def getHeight(self):
return self._height
def getWeight(self):
return self._weight
def getName(self):
return self._name
def getObjectId(self):
return self._object_id
def getDescription(self):
output = ''
vowels = ['a','e','i','o','u']
if isinstance(self,Place):
short_desc = self.getShortDescription()
output += short_desc + "\n"
underline = ''
for i in str(short_desc):
underline += '-'
output += underline + "\n"
output += self.getLongDescription() + '\n'
for thing in self.getContents():
if isinstance(thing,ExitObject):
if thing.isVisible():
output += "There is "
if thing.getName()[0].lower() in vowels:
output += 'an '
else:
output += 'a '
output += thing.getName() + ' '
output += 'here.\n'
else:
### Don't short exits if they are just cardinal directions (_visible=False)
pass
itemlist = []
peoplelist = []
for thing in self.getContents():
if isinstance(thing,SimObject) and not isinstance(thing,ExitObject) and not isinstance(thing,Person):
itemlist.append(thing.getName())
elif isinstance(thing,Person):
peoplelist.append(thing.getName())
if len(itemlist) == 1:
output += "There is "
if itemlist[0][0].lower() in vowels:
output += 'an '
else:
output += 'a '
output += itemlist[0] + ' '
output += 'here.\n'
if len(itemlist) >= 2:
total_items = len(itemlist)
item_counter = 1
output += "There are "
for items in itemlist:
if items[0].lower() in vowels:
output += 'an '
else:
output += 'a '
if item_counter <= total_items-2:
output += str(items)+', '
elif item_counter == total_items-1:
output += str(items)+' and '
else:
output += items + " "
item_counter += 1
output += "here.\n"
output += "\n"
if len(peoplelist) == 1:
output += str(peoplelist[0]) + " is here.\n"
elif len(peoplelist) > 1:
item_counter = 1
total_items = len(peoplelist)
for items in peoplelist:
if item_counter <= total_items-2:
output += str(items) + ', '
elif item_counter == total_items-1:
output += str(items) + ' and '
else:
output += str(items)
item_counter += 1
output += "are here.\n"
elif isinstance(self,Person):
output += self.getName()
output += "is standing before you!\n"
elif isinstance(self,ExitObject):
if self.isVisible():
output += str(self.getShortDescription()) + '\n'
else:
output += "You see nothing out of the ordinary here.\n"
else:
output += "unsure of type!\n"
output += "\n"
return output
#####################################################
# P L A C E C L A S S #
#####################################################
class Place(SimObject):
def __init__(self,
object_id = 0,
object_sku = 0,
short_description = 'Short Description',
long_description = 'Long Description',
name = 'Name',
weight = 1.0,
height = 1.0,
width = 1.0,
depth = 1.0,
visible = True,
contents = []):
SimObject.__init__(self,
object_id=object_id,
short_description = short_description,
long_description = long_description,
name = name,
weight = weight,
height = height,
width = width,
depth = depth,
visible = visible,
object_sku = object_sku,
contents = [])
#####################################################
# P E R S O N C L A S S #
#####################################################
class Person(SimObject):
def __init__(self,name="",object_id=0,object_sku=0):
SimObject.__init__(self,name=name,object_id=object_id,object_sku=object_sku)
self._hp = 100
def isAlive(self):
if self._hp > 0:
return True
else:
return False
def getStats(self):
print "%s has %i hit points remaining!" % (self._name,self._hp)
def receiveHit(self,damage="0"):
self._hp = self._hp - damage
if self._hp <>
self._hp = 0
def attack(self,enemy):
if type(enemy) == type(self):
attempt_roll = randint(1,10)
if attempt_roll > 5:
enemy.receiveHit(attempt_roll)
else:
print "Missed %s!" % str(enemy._name)
else:
print "Cannot attack %s" % str(enemy)
def getSize(self):
return "Person Details ... Weight: %.1f, Height: %.1f, Width: %.1f, Depth: %.1f" % (self._weight, self._height, self._width, self._depth)
def move(self,destination):
#### add test against dimensions. person WxD must be greater than Exit HxW, and the smallest Person dimension much be
#### smaller than the smallest Exit dimension
destination_room = self.getObjectById(destination)
destination_room.addContents(self)
#####################################################
# E X I T C L A S S #
#####################################################
class ExitObject(SimObject):
def __init__(self,visible=False,name="ExitName",short_description='Exit',
long_description='an Exit',aliases=(), destination=0,object_id=0,object_sku=0, weight=1.0,width=1.0,height=1.0,depth=1.0,closed=False):
"""Aliases are lists of names by which this exit can be referenced"""
SimObject.__init__(self,visible=visible,name=name,short_description=
short_description, long_description=long_description,object_id=object_id,
object_sku=object_sku, weight=weight,width=width,height=height,depth=depth,
closed=closed)
self._aliases = aliases
self._destination = destination
def getDestination(self):
return self._destination
def getAliases(self):
return self._aliases