git @ Cat's Eye Technologies The-Swallows / 51b4e03
Infrastructural changes to support "It is in your bed", etc. Cat's Eye Technologies 9 years ago
4 changed file(s) with 77 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
1717
1818 class Event(object):
1919 def __init__(self, phrase, participants, excl=False,
20 previous_location=None):
20 previous_location=None,
21 speaker=None,
22 addressed_to=None):
2123 """participants[0] is always the initiator, and we
2224 record the location that the event was initiated in.
2325
3234 (probably done by passing a number n: the first n
3335 participants are to be considered active)
3436
37 speaker and addressed_to apply to dialogue.
38 If speaker == None, it means the narrator is speaking.
39 If addressed_to == None, it means the reader is being spoken to.
40
3541 """
3642 self.phrase = phrase
3743 self.participants = participants
3844 self.location = participants[0].location
3945 self._previous_location = previous_location
4046 self.excl = excl
47 self.speaker = speaker
48 self.addressed_to = addressed_to
4149
4250 def rephrase(self, new_phrase):
4351 """Does not modify the event. Returns a new copy."""
5361 phrase = self.phrase
5462 i = 0
5563 for participant in self.participants:
56 phrase = phrase.replace('<%d>' % (i + 1), participant.render(self.participants))
64 phrase = phrase.replace('<%d>' % (i + 1), participant.render(event=self))
5765 phrase = phrase.replace('<indef-%d>' % (i + 1), participant.indefinite())
5866 phrase = phrase.replace('<his-%d>' % (i + 1), participant.posessive())
5967 phrase = phrase.replace('<him-%d>' % (i + 1), participant.accusative())
7583 class AggregateEvent(Event):
7684 """Attempt at a way to combine multiple events into a single
7785 sentence. Each constituent event must have the same initiator.
86
87 This is definitely not as nice as it could be.
7888
7989 """
8090 def __init__(self, template, events, excl=False):
352362 if event.participants[0] != character:
353363 continue
354364 print "%r in %s: %s" % (
355 [p.render([]) for p in event.participants],
356 event.location.render([]),
365 [p.render(event=event) for p in event.participants],
366 event.location.render(),
357367 event.phrase
358368 )
359369 print
7171
7272 def __str__(self):
7373 s = "%s is in %s" % (
74 self.subject.render([]),
75 self.location.render([])
74 self.subject.render(),
75 self.location.render()
7676 )
7777 if self.concealer:
78 s += " (hidden there by %s)" % self.concealer.render([])
78 s += " (hidden there by %s)" % self.concealer.render()
7979 if self.informant:
80 s += " (%s told me so)" % self.informant.render([])
80 s += " (%s told me so)" % self.informant.render()
8181 return s
8282
8383
9090 def __str__(self):
9191 return "I should %s %s" % (
9292 self.phrase,
93 self.subject.render([])
93 self.subject.render()
9494 )
9595
9696
101101
102102 def __str__(self):
103103 return "I want %s" % (
104 self.subject.render([])
104 self.subject.render()
105105 )
106106
107107
117117
118118 def __str__(self):
119119 return "%s believes { %s }" % (
120 self.subject.render([]),
120 self.subject.render(),
121121 self.belief_set
122122 )
123123
188188 ### ACTORS (objects in the world) ###
189189
190190 class Actor(object):
191 def __init__(self, name, location=None, collector=None):
191 def __init__(self, name, location=None, owner=None, collector=None):
192192 self.name = name
193193 self.collector = collector
194194 self.contents = set()
195195 self.enter = ""
196 self.owner = owner
196197 self.location = None
197198 if location is not None:
198199 self.move_to(location)
246247 self.location = location
247248 self.location.contents.add(self)
248249
249 def render(self, participants):
250 def render(self, event=None):
251 """Return a string containing what we call this object, in the context
252 of the given event (which may be None, to get a 'generic' description.)
253
254 """
250255 name = self.name
251 if participants:
252 subject = participants[0]
253 posessive = subject.name + "'s"
254 name = name.replace(posessive, subject.posessive())
256 repl = None
257 if self.owner is not None:
258 repl = self.owner.render() + "'s"
259 if event:
260 if event.speaker is self.owner:
261 repl = 'my'
262 elif event.addressed_to is self.owner:
263 repl = 'your'
264 elif event.initiator() is self.owner:
265 repl = event.initiator().posessive()
266 if repl is not None:
267 name = name.replace('<*>', repl)
255268 article = self.article()
256269 if not article:
257270 return name
317330 ### ANIMATE OBJECTS ###
318331
319332 class Animate(Actor):
320 def __init__(self, name, location=None, collector=None):
321 Actor.__init__(self, name, location=location, collector=None)
333 def __init__(self, name, location=None, owner=None, collector=None):
334 Actor.__init__(
335 self, name, location=location, owner=owner, collector=None
336 )
322337 self.topic = None
323338 self.beliefs = BeliefSet()
324339
411426 ###--- generic actions ---###
412427
413428 def place_in(self, location):
414 # like move_to but quieter; for setting up scenes etc
429 """Like move_to but quieter. For setting up scenes, etc.
430
431 """
415432 if self.location is not None:
416433 self.location.contents.remove(self)
417434 self.location = location
418435 self.location.contents.add(self)
419 # this is needed so that the Editor knows where the character starts
420 # (it is possible a future Editor might be able to strip out
421 # instances of these that aren't informative, though)
436 # this is needed so that the Editor knows where the character starts.
437 # the Editor should (does?) strip out all instances of these that
438 # aren't informative to the reader.
422439 self.emit("<1> <was-1> in <2>", [self, self.location])
423440 # a side-effect of the following code is, if they start in a location
424441 # with a horror,they don't react to it. They probably should.
514531 ### LOCATIONS ###
515532
516533 class Location(Actor):
517 def __init__(self, name, enter="went to", noun="room"):
534 def __init__(self, name, enter="went to", noun="room", owner=None):
518535 self.name = name
519536 self.enter = enter
520537 self.contents = set()
521538 self.exits = []
522539 self.noun_ = noun
540 self.owner = owner
523541
524542 def noun(self):
525543 return self.noun_
5454 """This character suspects some other character of hiding this thing."""
5555 def __str__(self):
5656 return "I think someone hid %s" % (
57 self.subject.render([])
57 self.subject.render()
5858 )
5959
6060
6161 ### Base character personalities for The Swallows
6262
6363 class Character(Animate):
64 def __init__(self, name, location=None, collector=None,
65 revolver=None, brandy=None, dead_body=None):
64 def __init__(self, name, location=None, collector=None):
6665 """Constructor specific to characters. In it, we set up some
67 Swallows-specific properties ('nerves') and we set up some important
68 items that this character needs to know about. This is maybe
69 a form of dependency injection.
66 Swallows-specific properties ('nerves').
7067
7168 """
7269 Animate.__init__(self, name, location=location, collector=None)
70 # this should really be *derived* from having a recent memory
71 # of seeing a dead body in the bathroom. but for now,
72 self.nerves = 'calm'
73
74 def configure_objects(self, revolver=None, brandy=None, dead_body=None):
75 """Here we set up some important items that this character needs
76 to know about. This is maybe a form of dependency injection.
77
78 """
7379 self.revolver = revolver
7480 self.brandy = brandy
7581 self.dead_body = dead_body
76 # this should really be *derived* from having a recent memory
77 # of seeing a dead body in the bathroom. but for now,
78 self.nerves = 'calm'
7982
8083 def believe_location(self, thing, location, informant=None, concealer=None):
8184 # we override this method of Animate in order to also remove
2525
2626 ### world ###
2727
28 alice = FemaleCharacter('Alice')
29 bob = MaleCharacter('Bob')
30
2831 kitchen = Location('kitchen')
2932 living_room = Location('living room')
3033 dining_room = Location('dining room')
3639 upstairs_hall = Location('upstairs hall')
3740 study = Location('study')
3841 bathroom = Location('bathroom')
39 bobs_bedroom = ProperLocation("Bob's bedroom")
40 alices_bedroom = ProperLocation("Alice's bedroom")
42 bobs_bedroom = ProperLocation("<*> bedroom", owner=bob)
43 alices_bedroom = ProperLocation("<*> bedroom", owner=alice)
4144
4245 kitchen.set_exits(dining_room, front_hall)
4346 living_room.set_exits(dining_room, front_hall)
6467 liquor_cabinet = Container('liquor cabinet', location=dining_room)
6568 mailbox = Container('mailbox', location=driveway)
6669
67 bobs_bed = ProperContainer("Bob's bed", location=bobs_bedroom)
68 alices_bed = ProperContainer("Alice's bed", location=alices_bedroom)
70 bobs_bed = ProperContainer("<*> bed", location=bobs_bedroom, owner=bob)
71 alices_bed = ProperContainer("<*> bed", location=alices_bedroom, owner=alice)
6972
7073 brandy = Item('bottle of brandy', location=liquor_cabinet)
7174 revolver = Weapon('revolver', location=random.choice([bobs_bed, alices_bed]))
7376
7477 # when making alice and bob, we let them recognize certain important
7578 # objects in their world
76 alice = FemaleCharacter('Alice',
77 revolver=revolver,
78 brandy=brandy,
79 dead_body=dead_body,
80 )
81 bob = MaleCharacter('Bob',
82 revolver=revolver,
83 brandy=brandy,
84 dead_body=dead_body,
85 )
79 for c in (alice, bob):
80 c.configure_objects(
81 revolver=revolver,
82 brandy=brandy,
83 dead_body=dead_body,
84 )
8685
8786 ALL_ITEMS = (falcon, jewels, revolver, brandy)