Skip to content

Instantly share code, notes, and snippets.

@mtensor
Created March 15, 2021 00:26
Show Gist options
  • Save mtensor/9fb4c5370be62579623e14d4aaf5c944 to your computer and use it in GitHub Desktop.
Save mtensor/9fb4c5370be62579623e14d4aaf5c944 to your computer and use it in GitHub Desktop.
#worldmodel.py
class CommandError(Exception):
pass
class QueryError(Exception):
pass
class FancyDefaultDict(dict):
def __init__(self, fn):
super(FancyDefaultDict, self).__init__()
self.fn = fn
def __missing__(self, key):
res = self[key] = self.fn(key)
return res
class PlacesEnv:
def __init__(self):
self.locations = FancyDefaultDict( lambda locName: Location(locName) )
self.objects = FancyDefaultDict( lambda objName: Obj(objName) )
self.people = FancyDefaultDict( lambda personName: Person(personName) )
self.commands = []
def reset(self):
self.locations = FancyDefaultDict( lambda locName: Location(locName) )
self.objects = FancyDefaultDict( lambda objName: Obj(objName) )
self.people = FancyDefaultDict( lambda personName: Person(personName) )
def go(self, personName, locName):
person = self.people[personName]
loc = self.locations[locName]
person.go(loc)
def pickup(self, personName, objName):
obj = self.objects[objName]
assert obj.holder is None #TODO change to homegrown error
person = self.people[personName]
person.pickup(obj)
def drop(self, personName, objName):
obj = self.objects[objName]
person = self.people[personName]
#assert person.loc is not None #TODO change to homegrown error
person.drop(obj)
def queryObjLoc(self, objName):
obj = self.objects[objName]
return obj.loc.name
def queryInventoryCount(self, personName):
person = self.people[personName]
n = len(person.inventory)
return ['none', 'one', 'two', 'three', 'four'][n]
def queryInventoryIdentities(self, personName):
person = self.people[personName]
return person.inventory.join(',')
def queryPriorLocation(self, objName, locName):
obj = self.objects[objName]
loc = self.locations[locName]
for i, l in reverse(obj.loc_history):
if loc == l: return obj.loc_history[-1 -i -1] #the thing before i
assert False #TODO change to homegrown error
def confirmPersonLoc(self, personName, locName):
person = self.people[personName]
loc = self.locations[locName]
return person.loc == loc #TODO return different type
def give(self, giverName, receiverName, objName):
obj = self.objects[objName]
giver = self.people[giverName]
receiverName = self.people[giverName]
giver.give(obj, receiver)
def add_unparsed_sentence(self, raw_text):
self.reset()
self.commands.append(raw_text)
try:
for command in self.commands:
self.parse_command(command)
except (AssertionError, ValueError) as e:
self.commands.pop()
self.reset()
raise CommandError
def parse_command(self, raw_text):
command, rest = raw_text.strip().split('(')
args = rest[:-1].split(', ')
if command == 'go':
self.go(args[0], args[1])
elif command == 'pickup':
self.pickup(args[0], args[1])
elif command == 'drop':
self.drop(args[0], args[1])
else: assert False, f"unsupported command {command}"
return raw_text
def add_query(self, raw_question):
try:
return self.parse_query(raw_question)
except AttributeError:
raise QueryError
def parse_query(self, raw_question):
command, rest = raw_question.strip().split("(")
arg = rest[:-1]
if command == 'queryObjLoc':
return self.queryObjLoc(arg)
else: assert False, f"unsupported command {command}"
class Location:
def __init__(self, name):
self.name = name
def __repr__(self): return self.name
def __hash__(self): return hash(self.name+'42')
class OptionLocation:
pass
class Person:
def __init__(self, name):
self.name = name
self.inventory = []
self.loc = None
def __hash__(self): return hash(self.name+'42')
def go(self, newLoc):
assert newLoc != self.loc
self.loc = newLoc
for obj in self.inventory: #TODO
obj.move(newLoc)
def pickup(self, obj):
assert obj.holder is None #TODO change to homegrown error
obj.holder = self
assert obj.name not in [o.name for o in self.inventory]
obj.loc = self.loc
self.inventory.append(obj)
def drop(self, obj):
obj.holder = None
obj.holder_history.append(self)
self.inventory.remove(obj) #TODO change to homegrown error
def give(self, obj, receiver):
assert obj.holder == self #TODO change to homegrown error
obj.holder_history.append(self)
self.inventory.remove(obj) #TODO change to homegrown error
obj.holder = receiver
if self.loc and receiver.loc:
assert self.loc == receiver.loc
self.inventory.remove(obj) #TODO change to homegrown error
receiver.inventory.append(obj)
class Obj:
def __init__(self, name):
self.name = name
self.loc = None
self.loc_history = []
self.holder = None
self.holder_history = []
def __hash__(self): return hash(self.name+'42')
def move(self, loc):
if self.loc is not None:
self.loc_history.append(self.loc)
self.loc = loc
if __name__ == '__main__':
e = PlacesEnv()
e.go('Max', 'office')
e.go('Eric', 'roof')
e.pickup('Max', 'apple')
e.pickup('Eric', 'milk')
e.go('Max', 'basement')
e.pickup('Max', 'football')
e.drop('Max', 'apple')
print(e.queryObjLoc('apple'))
print(e.queryObjLoc('milk'))
print(e.queryObjLoc('football'))
print(Person("max") == Person("max"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment