def cmd_equip(self, args): """Equip an equippable item from your inventory.""" if len(args) < 2: self.message("Provide an item to equip.") return item_name = " ".join(args[1::]).lower() found_items = util.find(self.inv, name=item_name) if len(found_items) == 1: self.equip(found_items[0][0]) elif len(found_items) > 1: #TODO handle ambiguity self.message(f"Ambigious item name. Results={found_items}") else: self.message(f"Could not find item '{item_name}'.")
def drop(self, args): """Drop an item into the environment""" if len(args) < 2: self.message("Provide an item to drop.") return item_name = " ".join(args[1:]).lower() found_items = util.find(self.inv, name=item_name) if len(found_items) == 1: item = found_items[0][0] self.inv.remove_item(item) self.location.inv.add_item(item) elif len(found_items) > 1: #TODO handle ambiguity self.message(f"Ambigious item name. Results={found_items}") else: self.message(f"Could not find item '{item_name}' to drop.")
def pickup(self, args): """Pick up item from the environment.""" if len(args) < 2: self.message("Provide an item to pick up.") return item_name = " ".join(args[1::]).lower() # TODO: find a way to provide type=Item found_items = util.find(self.location, name=item_name) if len(found_items) == 1: item = found_items[0][0] self.location.inv.remove_item(item) self.inv.add_item(item) elif len(found_items) > 1: #TODO handle ambiguity self.message(f"Ambigious item name. Results={found_items}") else: self.message(f"Could not find item '{item_name}' to pick up.")
def cmd_use(self, args): """ Use an item. usage: use [item] [options for item] Options may vary per item. """ # TODO: allow players to use accessible items in location? if len(args) < 2: self.message("Please specify an item.") return item_name = args[1] found_items = util.find(self.inv, name=item_name) if len(found_items) == 1: item = found_items[0][0] self.inv.remove_item(item) item.on_use(self, args[2:]) # replace the item self.inv.add_item(item) elif len(found_items) > 1: #TODO handle ambiguity self.message(f"Ambigious item name. Results={found_items}") else: self.message(f"Could not find item '{item_name}' to use.")
def test_error_handling(self): """Test that util.find properly checks its arguments""" return obj = location.Location("test", "") msg = ("util.find() names argument should be a str or " "iterable of strings, (received type '{}')") # this should work find(obj, name="foo") # this should fail since the provided name is an int with self.assertRaises(TypeError, msg=msg.format("<class 'int'>")): find(obj, name=3) # multiple strings find(obj, name=["foo", "bar"]) find(obj, name={"foo", "bar"}) with self.assertRaises(TypeError, msg=msg.format("<class 'float'>")): find(obj, name=["foo", 3.4]) msg = ("util.find() types argument should be a type or " "iterable of types, (received value '{}')") find(obj, name="foo", type=str) find(obj, name="foo", type=(str, float)) find(obj, name="foo", type={str, float}) with self.assertRaises(TypeError, msg=msg.format("<class 'int'>")): find(obj, type=3) with self.assertRaises(TypeError, msg=msg.format("<class 'str'>")): find(obj, type=(str, "float")) find(obj, maxdepth=3) msg = ("util.find() maxdepth argument must be int or float, received " "type '{}'") with self.assertRaises(TypeError, msg=msg.format("<class 'str'>")): find(obj, type=(str, "float")) # can provide must_have arguments find(obj, must_have={"foo": "bar"}) msg = ("util.find() optional argument must be dict, received " "type '{}'") with self.assertRaises(TypeError, msg=msg.format("<class 'int'>")): find(obj, must_have=3)
def test_find_location(self): """Test that util.find works with locations. (Implictly tests that Location.find_child works.) """ shopkeep = char.Character("Bill") # the drunkard is named "outside" for some reason drunkard = char.Character("Outside") guest = char.Character("Matt") tavern = location.Location("Tavern", "A cool tavern") outside = location.Location("Outside", "It's muddy.") basement = location.Location("Tavern Basement", "This is where he stores the ale.") upstairs = location.Location("Tavern Upstairs", "There is a comfy bed for guests.") safe_room = location.Location("Tavern Safe Room", "Room only shopkeep knows about.") exit_list = [ location.Exit(outside, "out", ["outside"]), # only shopkeeper allowed downstairs location.Exit(basement, "basement", ["downstairs"], interact=char.Filter("whitelist", include_chars=[shopkeep])), # only the guest and the shopkeeper allowed upstairs location.Exit(upstairs, "upstairs", ["up"], interact=char.Filter("blacklist", exclude_chars=[drunkard])), # only the shopkeeper can see the safe_room, but others # can interact if they know about it location.Exit(safe_room, "safe room", ["safe"], perceive=char.Filter("whitelist", include_chars=[shopkeep])) ] for ex in exit_list: tavern.add_exit(ex) tavern.add_char(shopkeep) tavern.add_char(drunkard) tavern.add_char(guest) self.maxDiff = 3000 # just doing a generic find should yield everything in the location self.assertCountEqual(find(tavern), exit_list + [shopkeep, drunkard, guest]) # providing a depth less than 0 should give us no items self.assertCountEqual(find(tavern, maxdepth=-1), []) # can we filter by type? self.assertCountEqual(find(tavern, type=location.Exit), exit_list) self.assertCountEqual(find(tavern, type=char.Character), [shopkeep, guest, drunkard]) self.assertCountEqual( find(tavern, type=(char.Character, location.Exit)), exit_list + [shopkeep, drunkard, guest]) # can we look by name? self.assertCountEqual(find(tavern, name="outside"), [exit_list[0], drunkard]) self.assertCountEqual(find(tavern, name="outside", type=location.Exit), [exit_list[0]]) # name and type self.assertCountEqual(find(tavern, name="outside", type=location.Exit), [exit_list[0]]) self.assertCountEqual(find(tavern, name="up"), [exit_list[2]]) self.assertCountEqual(find(tavern, name="safe"), [exit_list[3]]) self.assertCountEqual(find(tavern, name="bill"), [shopkeep]) # testing that all the permissions checking works as expected self.assertCountEqual(find(tavern, name="bill", pov=shopkeep), [shopkeep]) # shopkeeper can see all the exits self.assertCountEqual(find(tavern, type=location.Exit, pov=shopkeep), exit_list) self.assertCountEqual(find(tavern, type=location.Exit, pov=drunkard), [exit_list[0], exit_list[3]]) self.assertCountEqual(find(tavern, type=location.Exit, pov=guest), [exit_list[0], exit_list[2], exit_list[3]]) # now adding some items tavern.add_item(HealthPotion(1)) tavern.add_item(HealthPotion(1)) tavern.add_item(HealthPotion(5)) tavern.add_item(SilverCoin()) tavern.add_item(SilverCoin()) tavern.add_item(SilverCoin()) items = [(HealthPotion(1), 2), (HealthPotion(5), 1), (SilverCoin(), 3)] # directly comparing items is hard, so we will serialize them first self.assertEqual(10, len(find(tavern))) # helper function to make comparing items easier def item_list(i_list): return [(item.save(), c) for (item, c) in i_list] self.assertCountEqual(item_list(find(tavern, type=Item)), item_list(items)) self.assertCountEqual( item_list(find(tavern, name="Health Potion")), item_list([(HealthPotion(1), 2), (HealthPotion(5), 1)])) self.assertCountEqual(item_list(find(tavern, hp=1)), item_list([(HealthPotion(1), 2)]))