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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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