Example #1
0
 def get(self, item):
     if not item.traits.portable:
         r = Failure("You can't carry around the {}!".format(
             item.full_name()))
     elif self.in_inventory(item):
         r = Failure("You already have the {}!".format(item.full_name()))
     elif not self.is_nearby(item):
         container = self.nearby_container_having(item)
         creature = self.nearby_creature_having(item)
         if container:
             r = self.get_from(item, container)
         elif creature:
             r = self.ask_for(creature, item)
         else:
             r = ProximityFailure(item.full_name())
     else:
         r1 = self.location.remove_item(item)
         if r1.success:
             r2 = self.inventory.add_item(item)
             if r2.success:
                 r = Success("You take the " + item.full_name())
             else:
                 self.location.add_item(item)
                 r = Failure(
                     "Your load is too heavy to pick up the {}".format(
                         item.full_name()))
     return r
Example #2
0
 def remove_item(self, item, force=False):
     if not force and self.traits.closed:
         result = Failure("The " + self.full_name() + " is closed")
     else:
         if item.id in self.items:
             self.items.remove(item.id)
             result = Success("You remove the " + item.name + " from the " +
                              self.full_name())
         else:
             result = Failure("The {} {}n't {} the {}!".format(
                 item.full_name(), item.existential(), self.put_preposition,
                 self.full_name()))
     return result
Example #3
0
 def put_in(self, item, container):
     if not self.is_nearby(container):
         r = ProximityFailure(container.full_name())
     else:
         if not self.is_nearby(item):
             r = ProximityFailure(item.full_name())
         else:
             if container == item:
                 r = Failure("You can't put the {} {} itself!".format(
                     container.full_name(), container.put_preposition))
             else:
                 if self.in_inventory(item):
                     source = self.inventory
                 else:
                     source = self.location
                 r1 = source.remove_item(item)
                 if r1.success:
                     r2 = container.add_item(item)
                     if r2.success:
                         r = Success("The {} {} now {} the {}".format(
                             item.full_name(),
                             item.existential(), container.put_preposition,
                             container.full_name()))
                     else:
                         source.add_item(item)
                         r = r2
                 else:
                     r = r1
     return r
Example #4
0
 def hit_with(self, creature, weapon):
     if not self.is_nearby(creature):
         r = ProximityFailure(creature.full_name())
     elif not self.in_inventory(weapon):
         r = OwnershipFailure(weapon.full_name())
     else:
         if not creature.traits.hostile:
             creature.become_hostile()
         attack_difficulty = random.randint(0, 100)
         if weapon.accuracy < attack_difficulty:
             r = Failure("Your attack misses!")
         else:
             creature.health -= weapon.damage
             if creature.is_alive():
                 r = Success(
                     "You hit the {}. It reels from your attack!".format(
                         creature.full_name()))
             else:
                 r = Success((
                     "You deal the {} a fatal blow. It falls to the ground dead, "
                     +
                     "and its body dissolves into the hungry earth").format(
                         creature.full_name()))
                 for item_id in creature.inventory.items:
                     item = self.game.vocabulary.lookup_noun(item_id)
                     creature.inventory.remove_item(item)
                     self.location.add_item(item)
                 self.location.remove_item(creature, force=True)
                 creature.location = None
     return r
Example #5
0
    def throw(self, throwable, target=None):
        if not self.in_inventory(throwable):
            r = OwnershipFailure(throwable.full_name())
        elif target and not self.is_nearby(target):
            r = ProximityFailure(throwable.full_name())
        else:
            if throwable.size > 30:
                message = "You heave the {} {}; it falls to the ground {}"
                direction = "into the air"
                result = "with a solid thunk"
            elif 10 < throwable.size <= 30:
                message = "You lob the {} {}; it hits the ground {}"
                direction = "across the room"
                result = "and rolls to a stop"
            else:  # throwable.size < 10
                message = "You toss the {} {}; it comes back down {}"
                direction = "into the air"
                result = "with a soft plop"

            if target:
                direction = "at the {}, but miss".format(target.full_name())

            if throwable.traits.fragile:
                result = "and smashes to bits"
                self.inventory.remove_item(throwable)
            else:
                self.drop(throwable)
            r = Failure(
                message.format(throwable.full_name(), direction, result))

        return r
Example #6
0
 def lock_with(self, lockable, key):
     if self.is_nearby(lockable):
         if lockable.traits.locked:
             r = Failure("The {} is already locked".format(
                 lockable.full_name()))
         else:
             if key.can_lock(lockable):
                 lockable.traits.locked = True
                 r = Success("The {} is now locked".format(
                     lockable.full_name()))
             else:
                 r = Failure("The {} cannot be locked with the {}!".format(
                     lockable.full_name(), key.full_name()))
     else:
         r = ProximityFailure(lockable.full_name())
     return r
Example #7
0
 def unlock_with(self, lockable, key):
     if self.is_nearby(lockable) or self.nearby_container_having(lockable):
         if not lockable.traits.locked:
             r = Failure("The {} is already unlocked".format(
                 lockable.full_name()))
         else:
             if key.can_lock(lockable):
                 lockable.traits.locked = False
                 r = Success("The {} is now unlocked".format(
                     lockable.full_name()))
             else:
                 r = Failure(
                     "The {} cannot be unlocked with the {}!".format(
                         lockable.full_name(), key.full_name()))
     else:
         r = ProximityFailure(lockable.full_name())
     return r
Example #8
0
 def add_item(self, item, force=False):
     if not force and self.traits.closed:
         result = Failure("The " + self.full_name() + " is closed")
     else:
         if item.id in self.items:
             result = Failure("The {} {} already {} the {}".format(
                 item.full_name(), item.existential(), self.put_preposition,
                 self.full_name()))
         elif item.size > self.remaining_capacity():
             result = Failure("Sorry, the {} won't fit {} the {}".format(
                 item.full_name(), self.put_preposition, self.full_name()))
         else:
             self.items.append(item.id)
             result = Success("Okay, the {} {} now {} the {}".format(
                 item.full_name(), item.existential(), self.put_preposition,
                 self.full_name()))
     return result
Example #9
0
 def process_get(schema):
     if schema[Role.PATIENT]:
         r = schema[Role.AGENT].get_from(schema[Role.THEME],
                                         schema[Role.PATIENT])
     else:
         theme = schema[Role.THEME]
         if isinstance(theme, Creature) and not theme.traits.portable:
             r = Failure(
                 "You are unable to subdue and capture the {}!".format(
                     theme.full_name()))
         elif not theme.traits.portable:
             r = Failure(
                 "The {} is solidly anchored and cannot be removed".
                 format(theme.full_name()))
         else:
             r = schema[Role.AGENT].get(schema[Role.THEME])
     return r
Example #10
0
 def is_valid_schema(self, schema):
     r = None
     missing_roles = set()
     for role in Role.values:
         if role in self.unassigned_roles and schema.get_role(role):
             r = NotUnderstoodFailure()
             break
         elif role in self.required_roles:
             if schema.get_role(role) is None:
                 missing_roles.add(role)
             else:
                 role_value = schema.get_role(role)
                 if not (role in self.permissive_roles
                         or role_value.is_valid_for_role(role, self)):
                     r = Failure(self.role_messages[role].format(
                         role_value.full_name()))
                     break
     if r is None:
         # TODO: Add heuristic to guess identity of missing words, if possible
         if len(missing_roles) > 0:
             preposition = None
             for k, v in self.preposition_roles.items():
                 if v in missing_roles:
                     preposition = k
             if Role.PATIENT in missing_roles:
                 if preposition:
                     r = Failure("What do you want to {} {}?".format(
                         self.name, preposition))
                 else:
                     r = Failure("What do you want to {}?".format(
                         self.name))
             elif Role.THEME in missing_roles or Role.INSTRUMENT in missing_roles:
                 if preposition:
                     r = Failure("What do you want to {} the {} {}?".format(
                         self.name, schema[Role.PATIENT].full_name(),
                         preposition))
                 else:
                     r = Failure("What do you want to {} the {}?".format(
                         self.name, schema[Role.PATIENT].full_name()))
             else:
                 r = NotUnderstoodFailure()
         else:
             r = Success("Success")
     return r
Example #11
0
 def drop(self, item):
     r1 = self.inventory.remove_item(item)
     if r1.success:
         r2 = self.location.add_item(item)
         if r2.success:
             r = Success("You drop the " + item.full_name())
         else:
             r = Failure("You can't drop the " + item.full_name() + "here!")
     else:
         r = OwnershipFailure(item.full_name())
     return r
Example #12
0
 def close(self, closeable):
     if self.is_nearby(closeable):
         if closeable.traits.closed:
             r = Failure("The {} is already closed".format(
                 closeable.full_name()))
         else:
             closeable.traits.closed = True
             r = Success("You close the {}".format(closeable.full_name()))
     else:
         r = ProximityFailure(closeable.full_name())
     return r
Example #13
0
 def go(self, direction):
     if direction.id in self.location.exits:
         self.location.visited = True
         passage = self.location.exits[direction.id]
         r1 = passage.go(self.game, self)
         if r1.success:
             r = self.location.describe(verbose=False)
         else:
             r = r1
     else:
         r = Failure("You can't go {} from here".format(direction.name))
     return r
Example #14
0
 def ask_for(self, creature, item):
     if not self.is_nearby(creature):
         r = ProximityFailure(creature.full_name())
     elif not creature.in_inventory(item):
         r = Failure("The {} doesn't have the {}".format(
             creature.full_name(), item.full_name()))
     elif not creature.traits.friendly or item in creature.wanted_items:
         r = Failure("The {} is unwilling to part with the {}".format(
             creature.full_name(), item.full_name()))
     else:
         r1 = creature.inventory.remove_item(item)
         if r1.success:
             r2 = self.inventory.add_item(item)
             if r2.success:
                 r = Success(
                     "The {} gladly hands over the {} to you".format(
                         creature.full_name(), item.full_name()))
             else:
                 creature.inventory.add_item(item)
                 r = r2
         else:
             r = r1
     return r
Example #15
0
 def give_to(self, item, creature):
     if not self.is_nearby(creature):
         r = ProximityFailure(creature.full_name())
     elif not self.in_inventory(item):
         r = OwnershipFailure(item.full_name())
     elif item in creature.wanted_items:
         r1 = self.inventory.remove_item(item)
         if r1.success:
             r2 = creature.inventory.add_item(item)
             if r2.success:
                 creature.become_friendly()
                 r = Success("The {} gratefully accepts the {}".format(
                     creature.full_name(), item.full_name()))
             else:
                 self.inventory.add_item(item)
                 r = r2
         else:
             r = r1
     else:
         r = Failure("The {} politely declines to take the {}".format(
             creature.full_name(), item.full_name()))
     return r
Example #16
0
 def extract_report(self, container):
     try:
         report_content = self.extract_file_from_container(
             container, "report-public.xml")
         # Taken from: https://stackoverflow.com/a/18281386/10390454
         tree = ET.ElementTree(ET.fromstring(report_content))
         root = tree.getroot()
         test_suite = root[0]
         ts_attr = test_suite.attrib
         report = Report(ts_attr["errors"], ts_attr["failures"],
                         ts_attr["name"], ts_attr["skipped"],
                         ts_attr["tests"], ts_attr["time"])
         for test_case in test_suite.findall("testcase"):
             tc_attr = test_case.attrib
             tcm_attr = test_case.find("meta").attrib
             output = None
             if "output" in tcm_attr:
                 output = tcm_attr["output"]
             meta = Meta(tcm_attr["expected"], tcm_attr["expression"],
                         tcm_attr["hint"], output)
             tcf = test_case.find("failure")
             failure = None
             if tcf is not None:
                 tcf_attr = tcf.attrib
                 failure = Failure(tcf_attr["message"], tcf_attr["type"])
             tce = test_case.find("error")
             error = None
             if tce is not None:
                 tce_attr = tce.attrib
                 error = Error(tce_attr["message"], tce_attr["type"])
             test_case = TestCase(tc_attr["name"], tc_attr["time"], meta,
                                  failure, error)
             report.testcases.append(test_case)
         return report
     except docker.errors.NotFound:
         return None
     except:
         raise
Example #17
0
class Passage(Thing):

    DEFAULT_TRAITS = None
    DEFAULT_FAIL_RESULT = Failure("You can't go that way")

    def __init__(self, game, name, location, direction, destination, description,
                 condition, fail_result, after=None, traits=None):
        self.traits = Traits.merge(self, traits, Passage.DEFAULT_TRAITS)
        super(Passage, self).__init__(game, name, aliases=None)
        self.vocab = game.vocabulary
        self.location = location.id
        self.direction = direction.id
        self.destination = destination.id
        self.description = description
        self.condition = condition
        self.after = after
        if fail_result:
            self.fail_result = fail_result
        else:
            self.fail_result = Passage.DEFAULT_FAIL_RESULT

    def set_direction(self, direction):
        self.direction = direction.id

    def set_destination(self, destination):
        self.destination = destination.id

    def go(self, game, creature):
        if self.condition(game, creature):
            location = self.vocab.lookup_noun(self.location)
            destination = self.vocab.lookup_noun(self.destination)
            game.move_creature(creature, location, destination)
            r = Success("Creature moved from {} to {}".format(location.name, destination.name))
            if self.after:
                r = self.after(game, creature, location, destination)
        else:
            r = self.fail_result
        return r
Example #18
0
    def setup_items(self, game):

        # --------------- Common effects of commands

        def update_score(game, points):
            game.score += points

        def update_health(player, points):
            player.health += points

        def make_creature_hostile(creature):
            creature.become_hostile()

        def instant_death(player):
            player.health = 0

        def lose_item(player, item):
            player.inventory.remove_item(item)

        def end_section(name, game, player, points):
            update_score(game, points)
            result = Result(
                "Congratulations! You have finished {}. ".format(name))
            status = game.status()
            result.append(status.get_message())
            return result

        # ---------------- Create basic locations and objects

        player = game.player

        crumbly_room = Location(
            game,
            name='Crumbly Room',
            description='A small storage room with crumbling plaster walls')
        paneled_room = Location(
            game,
            name='Wood Paneled Room',
            description='A large, warm room with wood-paneled walls')
        north_tower = Location(
            game,
            name='North Tower',
            description='A tower with a high ceiling and red-stained windows')
        balcony = Location(
            game,
            name='Balcony',
            description=
            'A breezy, open balcony with a beautiful view of the landscape below',
            traits=Traits(precarious=True))
        east_tower = Location(
            game,
            name='East Tower',
            description='The tall tower at the eastern side of the house')
        roof = Location(
            game,
            name='Roof',
            description='You are on the roof of the eastern tower.  ' +
            'There is a ladder leading back downwards, and to the west is an open window.',
            traits=Traits(precarious=True))

        west_tower = Location(
            game,
            name='West Tower',
            description='The tall tower at the western side of the house.')

        master_bedroom = Location(
            game,
            'Master Bedroom',
            description=
            'This appears to be a former bedroom, but the bed itself is missing.  '
            + 'A window to the east is open.')
        basement = Location(game,
                            'Basement',
                            description='An empty room, very drafty')
        garden = Location(game, 'garden', description='a lush blooming garden')
        patio = Location(game, 'patio', description='an empty stone patio')
        front_porch = Location(
            game,
            'porch',
            description=
            'The front porch of the house.  A metal gate prevents you from leaving'
        )
        front_porch.add_modifier('front')

        metal_gate = Surface(
            game,
            name='gate',
            description=
            'An impassable metal gate with two locks: one golden and one bronze, '
            + 'blocking your exit!')
        metal_gate.traits.closed = True
        metal_gate.add_modifier('metal')
        front_porch.add_item(metal_gate)

        golden_lock = Door(game, name='lock', description='a golden lock')
        golden_lock.add_modifier('golden')
        metal_gate.add_item(golden_lock, force=True)

        bronze_lock = Door(game, name='lock', description='a bronze lock')
        bronze_lock.add_modifier('bronze')
        metal_gate.add_item(bronze_lock, force=True)

        street = Location(game, 'street', description='an empty street')

        fancy_painting = Item(
            game,
            name='painting',
            description='An ornate painting of the house\'s previous owner',
            aliases=['portrait', 'picture'],
            size=15,
            value=100)
        fancy_painting.add_modifier('fancy')
        west_tower.add_item(fancy_painting)

        east_tower.add_exit(direction.west, paneled_room)
        crumbly_room.add_exit(direction.north, paneled_room)
        paneled_room.add_exit(direction.south, crumbly_room)
        paneled_room.add_exit(direction.north, north_tower)
        paneled_room.add_exit(direction.east, east_tower)
        paneled_room.add_exit(direction.west, west_tower)
        west_tower.add_exit(direction.east, paneled_room)
        roof.add_exit(direction.west, master_bedroom)
        master_bedroom.add_exit(direction.down, basement)
        master_bedroom.add_exit(direction.east, roof)
        basement.add_exit(direction.up, master_bedroom)
        basement.add_exit(direction.west, garden)
        garden.add_exit(direction.east, basement)
        garden.add_exit(direction.south, patio)
        patio.add_exit(direction.north, garden)
        patio.add_exit(direction.south, front_porch)

        front_porch.add_exit(direction.north, patio)
        front_porch.add_exit(
            direction.south,
            street,
            condition=lambda g, p: not metal_gate.traits.closed,
            after=lambda g, p, l, d: end_section("section one", g, p, 50),
            fail_result=Failure("The metal gate blocks your way"))

        def too_small_check(g, p):
            return p.inventory.used_capacity() <= 25

        too_small_result = Failure(
            "Your load is too large to fit through the small hole")

        east_tower.add_exit(
            direction.up,
            roof,
            description='A ladder leads up to a hole in the ceiling far above',
            condition=too_small_check,
            fail_result=too_small_result)
        roof.add_exit(
            direction.down,
            east_tower,
            description="There is a hole here leading down to the tower below",
            condition=too_small_check,
            fail_result=too_small_result)

        sturdy_door = Door(
            game,
            name='door',
            description=
            'A sturdy door leading out to the balcony above the tower')
        sturdy_door.add_modifier('sturdy')

        silver_key = Key(game,
                         name='key',
                         description='A brilliant silver key')
        silver_key.add_modifier('silver')

        steel_key = Key(game, name='key', description='A small steel key')
        steel_key.add_modifier('steel')
        steel_key.set_lockable(sturdy_door)
        roof.add_item(steel_key)

        north_tower.add_item(sturdy_door)
        north_tower.add_exit(direction.south, paneled_room)
        north_tower.add_exit(
            direction.up,
            balcony,
            description="Stairs lead up to a door high above",
            condition=lambda g, p: not sturdy_door.traits.closed,
            fail_result=Failure("A sturdy door blocks the way"))
        balcony.add_exit(direction.down, north_tower)

        light_thing = Item(
            game,
            name='thing',
            description='An easily carried thing, light as a feather',
            size=0)
        light_thing.add_modifier('light')

        fragile_thing = Item(game,
                             name='thing',
                             description='An easily breakable, delicate thing',
                             traits=Traits(fragile=True),
                             size=15)
        fragile_thing.add_modifier('fragile')

        heavy_thing = Item(
            game,
            name='thing',
            description='A heavy block of some unknown material',
            size=45)
        heavy_thing.add_modifier('heavy')

        trunk = Container(game,
                          name='trunk',
                          description='An old wooden trunk',
                          aliases=['chest', 'box'],
                          size=75,
                          value=5,
                          capacity=90)
        trunk.add_modifier('wooden')
        sword = Weapon(game,
                       name='sword',
                       description='A serviceable iron sword',
                       size=15,
                       value=15,
                       damage=50,
                       defense=10,
                       accuracy=80)
        sword.add_modifier('iron')
        trunk.add_item(sword, force=True)

        diamond = Item(game,
                       name='diamond',
                       aliases=['gem', 'jewel'],
                       size=5,
                       value=100,
                       description='A brilliant diamond')

        apple = Edible(game,
                       name='apple',
                       description='A delicious, juicy red apple',
                       size=15,
                       value=5)
        small_table = Surface(game,
                              name='table',
                              description='A small table',
                              size=20,
                              capacity=15)
        small_table.add_modifier('small')
        small_table.add_item(apple, force=True)

        large_table = Surface(game,
                              name='table',
                              description='A large table',
                              size=75,
                              capacity=100)
        large_table.add_modifier('large')
        large_table.add_item(heavy_thing, force=True)
        large_table.add_item(light_thing, force=True)
        large_table.add_item(fragile_thing, force=True)

        bread = Edible(game,
                       name='bread',
                       description='A loaf of crusty brown bread',
                       size=20,
                       value=5,
                       healing=10)

        puddle = Drinkable(game,
                           name='puddle',
                           aliases=['water'],
                           description='A puddle of refreshing water',
                           size=25,
                           value=5,
                           healing=15)

        mouse = Item(
            game,
            name='mouse',
            description='A small mouse scampers back and forth across the ' +
            'room here, searching for food.  It is carrying something '
            'shiny in its mouth.',
            traits=Traits(compelling=True),
            size=0,
            value=0)
        mouse.add_modifier('brown')
        west_tower.add_item(mouse)

        core = Item(game,
                    name='core',
                    description='The core of an eaten apple',
                    size=5,
                    value=0)
        core.add_modifier('apple')
        apple.add_consumed(core)

        crumbs = Edible(game,
                        name='crumbs',
                        description='A small pile of leftover bread crumbs',
                        aliases=['pile'],
                        traits=Traits(composite=True, plural=True),
                        size=5,
                        value=0,
                        healing=0)
        bread.add_consumed(crumbs)

        mud = Item(game,
                   name='mud',
                   description='A clump of soggy wet mud',
                   traits=Traits(composite=True),
                   size=15,
                   value=1)
        puddle.add_consumed(mud)
        vase = Container(game,
                         name='flowerpot',
                         description='a patterned flowerpot',
                         aliases=['flowerpot', 'pot', 'vase'],
                         traits=Traits(closed=False, fragile=True),
                         size=5,
                         value=10,
                         capacity=3)
        flower = Item(game,
                      name='flower',
                      description='a beautiful, fragrant sunflower',
                      size=3,
                      value=5)
        crumbly_room.add_item(small_table)
        crumbly_room.add_item(large_table)
        paneled_room.add_item(trunk)
        paneled_room.add_item(puddle)

        vase.add_item(flower)
        balcony.add_item(vase)

        villager = Creature(
            game,
            name='villager',
            traits=Traits(mobile=True),
            aliases=['farmer'],
            description="A stout but simple villager in farming garb",
            health=75,
            strength=25,
            dexterity=65,
            location=paneled_room)
        villager.add_wanted_item(apple)
        villager.add_item(diamond)

        golden_key = Key(game,
                         name='key',
                         description='A fashionable golden key')
        golden_key.add_modifier('golden')
        golden_key.set_lockable(golden_lock)

        red_fox = Creature(game,
                           name='fox',
                           traits=Traits(hostile=True, mobile=False),
                           description="a bloodthirsty red fox",
                           health=65,
                           strength=15,
                           dexterity=50,
                           location=front_porch)
        red_fox.add_modifier('red')
        red_fox.add_item(golden_key)

        bronze_key = Key(game, name='key', description='A dull bronze key')
        bronze_key.add_modifier('bronze')
        bronze_key.set_lockable(bronze_lock)

        brown_fox = Creature(game,
                             name='fox',
                             traits=Traits(hostile=True, mobile=False),
                             description="a vicious brown fox",
                             health=65,
                             strength=25,
                             dexterity=50,
                             location=front_porch)
        brown_fox.add_modifier('brown')
        red_fox.add_item(bronze_key)

        townsfolk = Creature(
            game,
            name='townsfolk',
            traits=Traits(mobile=True),
            description='A short, well-dressed man with a stubbly beard',
            aliases=['folk', 'man'],
            health=75,
            strength=30,
            dexterity=65,
            location=north_tower)
        townsfolk.add_wanted_item(diamond)
        townsfolk.add_item(bread)

        def shadow_action(game, player):
            player.health -= 5
            return Result("A dark shadow looms ominously in the corner")

        shadow = Creature(
            game,
            name='shadow',
            traits=Traits(hostile=False, mobile=True, evident=False),
            description=
            'You attempt to examine the shadow, but your vision blurs as you try to focus '
            'on its constantly shifting shape, preventing you from forming '
            'any clear impression',
            health=9001,
            strength=20,
            dexterity=90,
            location=east_tower)
        shadow.add_modifier('dark')
        shadow.entry_action = lambda g, p: Result(
            "A dark shadow enters.  The temperature in the room drops "
            "several degrees, as does your blood")
        shadow.exit_action = lambda g, p: Result(
            "The shadow leaves the room, and you once again find "
            "you can breathe freely")
        shadow.present_action = shadow_action

        # -------- Consequences: game milestones and achievements, and special results
        vocabulary = game.vocabulary

        open = vocabulary.lookup_verb_by_name('open')
        get = vocabulary.lookup_verb_by_name('get')
        ask = vocabulary.lookup_verb_by_name('ask')
        smell = vocabulary.lookup_verb_by_name('smell')
        jump = vocabulary.lookup_verb_by_name('jump')
        drop = vocabulary.lookup_verb_by_name('drop')
        throw = vocabulary.lookup_verb_by_name('throw')
        kill = vocabulary.lookup_verb_by_name('kill')
        unlock = vocabulary.lookup_verb_by_name('unlock')

        # Trying to pick up creatures turns them hostile
        for creature in vocabulary.get_objects_of_class(Creature):
            get.add_consequence(schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: creature
            }),
                                necessary_result=result.GENERIC_FAILURE,
                                effect=lambda schema: make_creature_hostile(
                                    schema[Role.THEME]))

        # Be careful in precarious places!
        for room in vocabulary.get_objects_of_class(Location):
            if room.traits.precarious:
                jump.add_consequence(
                    schema=Schema(roles={Role.AGENT: player}),
                    necessary_result=result.GENERIC_SUCCESS,
                    necessary_location=room,
                    effect=lambda schema: instant_death(player),
                    consequent_result=Success(
                        "In your excitement, you slip and fall to the hard ground far below!\n"
                        +
                        "You should probably be more careful where you do your jumping."
                    ))

                # TODO: Some kind of pattern-matching logic here.  This configures for _no_ theme, not _any_ theme ...
                throw.add_consequence(
                    schema=Schema(roles={Role.AGENT: player}),
                    necessary_result=result.GENERIC_FAILURE,
                    necessary_location=room,
                    effect=lambda schema: lose_item(player, schema[Role.THEME]
                                                    ),
                    consequent_result=Failure(
                        "You toss it carelessly, and it sails over the edge and out of sight"
                    ))

        # The mouse is too fast to catch or kill, but it's hungry
        def fed_mouse(crumbs):
            west_tower.remove_item(mouse)
            west_tower.remove_item(crumbs)
            west_tower.add_item(silver_key)

        get.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: mouse
            }),
            necessary_result=result.GENERIC_SUCCESS,
            necessary_location=west_tower,
            effect=lambda schema: player.drop(mouse),
            consequent_result=Failure(
                "You try, but the mouse is far too small and fast for you to catch!"
            ))

        drop.add_consequence(schema=Schema(roles={
            Role.AGENT: player,
            Role.THEME: crumbs
        }),
                             necessary_result=result.GENERIC_SUCCESS,
                             necessary_location=west_tower,
                             effect=lambda schema: update_score(game, 20))

        drop.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: crumbs
            }),
            necessary_result=result.GENERIC_SUCCESS,
            necessary_location=west_tower,
            effect=lambda schema: fed_mouse(crumbs),
            consequent_result=Success(
                "The mouse devours the crumbs, dropping something shiny to the floor in the "
                "process.  It then returns to its hole, well-fed and content"))

        # Foxes work cooperatively!
        def killed_fox(dead_fox, other_fox, key):
            dead_fox.remove_item(key)
            if other_fox.is_alive:
                other_fox.add_item(key)
                return result.GENERIC_SUCCESS
            else:
                return result.GENERIC_FAILURE

        kill.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: red_fox
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=killed_fox(red_fox, brown_fox, golden_key),
            consequent_result=Success(
                "As the red fox falls dead to the ground, its brother retrieves "
                "the golden key from its lifeless form"))

        kill.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: brown_fox
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=killed_fox(brown_fox, red_fox, bronze_key),
            consequent_result=Success(
                "As the brown fox falls dead to the ground, its brother retrieves "
                "the bronze key from its lifeless form"))

        # Achievement: unlock and open the sturdy door
        open.add_consequence(schema=Schema(roles={
            Role.AGENT: player,
            Role.PATIENT: sturdy_door
        }),
                             necessary_result=result.GENERIC_SUCCESS,
                             effect=lambda schema: update_score(game, 10))

        # Achievement: get the diamond from the villager
        ask.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.PATIENT: villager,
                Role.THEME: diamond
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: update_score(game, 20))

        get.add_consequence(schema=Schema(roles={
            Role.AGENT: player,
            Role.THEME: diamond
        }),
                            necessary_result=result.GENERIC_SUCCESS,
                            effect=lambda schema: update_score(game, 20))

        get.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.PATIENT: villager,
                Role.THEME: diamond
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: update_score(game, 20))

        # Health bonus: smell the sunflower
        smell.add_consequence(
            schema=Schema(roles={
                Role.AGENT: player,
                Role.THEME: flower
            }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: update_health(player, 10),
            consequent_result=Success(
                "You feel revived by the bloom's invigorating fragrance"))

        def unlock_gate(this_lock, other_lock):
            this_lock.traits.locked = False
            if other_lock.traits.locked:
                return result.GENERIC_FAILURE
            else:
                update_score(game, 50)
                metal_gate.traits.closed = False
                return result.GENERIC_SUCCESS

        unlock.add_consequence(
            schema=Schema(
                roles={
                    Role.AGENT: player,
                    Role.THEME: golden_lock,
                    Role.INSTRUMENT: golden_key
                }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: unlock_gate(golden_lock, bronze_lock),
            consequent_result=WON_GAME)

        unlock.add_consequence(
            schema=Schema(
                roles={
                    Role.AGENT: player,
                    Role.THEME: golden_lock,
                    Role.INSTRUMENT: golden_key
                }),
            necessary_result=result.GENERIC_SUCCESS,
            effect=lambda schema: unlock_gate(golden_lock, bronze_lock),
            consequent_result=WON_GAME)

        # Start game in crumbly room
        return crumbly_room
Example #19
0
 def open(self, openable):
     if self.is_nearby(openable):
         if openable.traits.closed:
             if openable.traits.locked:
                 r = Failure(
                     "You try to open the {}, but it is firmly locked".
                     format(openable.full_name()))
             else:
                 openable.traits.closed = False
                 if isinstance(openable, Container):
                     container = openable
                     item_count = container.item_count()
                     if item_count == 0:
                         r = Success(
                             "You open the {}, which is empty".format(
                                 container.full_name()))
                     elif item_count == 1:
                         r = Success("Opening the {} reveals a {}".format(
                             container.full_name(),
                             self.vocab.lookup_noun(
                                 container.items[0]).full_name()))
                     else:
                         r = Success("Opening the {} reveals: ".format(
                             container.full_name()))
                         for item_id in container.items:
                             item = self.vocab.lookup_noun(item_id)
                             r.append("\n\t" + item.description)
                 else:
                     r = Success("You open the {}".format(
                         openable.full_name()))
         else:
             r = Failure("The {} is already open".format(
                 openable.full_name()))
     else:
         r = ProximityFailure(openable.full_name())
     return r