Esempio n. 1
0
 def __init__(self, wcfg, wfsa):
     self._wcfg = wcfg
     self._wfsa = wfsa
     self._agenda = Agenda(active_container_type=ActiveQueue)
     self._firstsym = defaultdict(
         set)  # index rules by their first RHS symbol
     self._item_factory = ItemFactory()
Esempio n. 2
0
    def __init__(self, wcfg, wfsa):
        """
        """

        self._wcfg = wcfg
        self._wfsa = wfsa
        self._agenda = Agenda(active_container_type=ActiveQueue)
        self._predictions = set()  # (LHS, start)
        self._item_factory = ItemFactory()
Esempio n. 3
0
    def setUp(self):
        self.item_factory = ItemFactory(item_data)

        self.player = Player(
            inventory={},
            wearing=self.item_factory.create_dictionary_from_nouns(
                [Noun.BOXER_SHORTS]),
            score=0,
            health=100,  # percent
            caffeine_level=50  # milligrams
        )
Esempio n. 4
0
    def setUp(self):
        self.item_factory = ItemFactory(item_data)
        self.rooms = {}

        # Build our little universe.
        for id, data in room_data.items():
            self.rooms[id] = Room(id, self.item_factory, data)
 def __init__(self, wcfg, wfsa, slice_vars):
     self._wcfg = wcfg
     self._wfsa = wfsa
     self._agenda = Agenda(active_container_type=ActiveQueue)
     self._firstsym = defaultdict(set)  # index rules by their first RHS symbol
     self._item_factory = ItemFactory()
     self.slice_vars = slice_vars
Esempio n. 6
0
    def new(self):

        # Generic Game variables
        self.ticker = Ticker()
        self.bus = Publisher()
        self.game_state = c.GAME_STATE_PLAYING
        self.player_took_action = False
        self.minimap_enable = False
        self.objects = []
        self.level = 1

        # initializing map structure
        self.map = MapFactory("LordCroket Caves - Level {}".format(self.level),
                              self.all_images).map
        self.minimap = Minimap(self)

        # Field of view
        self.fov = FieldOfView(self)

        # We have 5 sprites groups: two below the player, the player one and two above
        # They are drawn in the order below:
        self.player_min2_sprite_group = pg.sprite.Group()
        self.player_min1_sprite_group = pg.sprite.Group()
        self.player_sprite_group = pg.sprite.Group(
        )  # the default group, also called level 0
        self.player_plus1_sprite_group = pg.sprite.Group()
        self.player_plus2_sprite_group = pg.sprite.Group()
        self.all_groups = [
            self.player_min2_sprite_group, self.player_min1_sprite_group,
            self.player_sprite_group, self.player_plus1_sprite_group,
            self.player_plus2_sprite_group
        ]

        # Camera
        self.camera = Camera(self.map.tile_width * TILESIZE_SCREEN,
                             self.map.tile_height * TILESIZE_SCREEN)

        self.place_doors_stairs_traps(self.level)

        # Place player
        all_pos = self.map.get_all_available_tiles(c.T_FLOOR,
                                                   self.objects,
                                                   without_objects=True)
        self.player = PlayerHelper(self, all_pos.pop())
        self.visible_player_array = self.fov.get_vision_matrix_for(
            self.player, flag_explored=True)

        # place monsters and items
        ItemFactory(self).build_list(20)  # 220
        MonsterFactory(self).build_list(120)

        # And we end with the screens...
        self.screens = {
            c.GAME_STATE_INVENTORY: InventoryScreen(self,
                                                    c.GAME_STATE_PLAYING),
            c.GAME_STATE_MAP: MapScreen(self, c.GAME_STATE_PLAYING),
            c.GAME_STATE_CHARACTER: CharacterScreen(self,
                                                    c.GAME_STATE_PLAYING),
            c.GAME_STATE_PLAYING: PlayingScreen(self, None)
        }
    def __init__(self, wcfg, wfsa):
        """
        """

        self._wcfg = wcfg
        self._wfsa = wfsa
        self._agenda = Agenda(active_container_type=ActiveQueue)
        self._predictions = set()  # (LHS, start)
        self._item_factory = ItemFactory()
Esempio n. 8
0
 def __init__(self, id, item_factory: ItemFactory, data):
     super().__init__(
         item_factory.create_dictionary_from_nouns(
             data.get("inventory") or set()))
     self.id = id
     self.name = data["name"]
     self._description = data["description"]
     self.exits = data["exits"]
     self.rules = data.get("rules") or {}
Esempio n. 9
0
    def go_next_level(self):

        # First: cleanup!
        # Warning: we must act on a copy of the list!!!!!
        for entity in self.objects[:]:
            if entity != self.player:
                entity.remove_completely_object()

        self.level += 1

        # initializing map structure
        self.map = MapFactory(
            "Cave of LordCrocket - Level {}".format(self.level),
            self.all_images).map
        self.minimap = Minimap(self)

        # Field of view
        self.fov = FieldOfView(self)

        self.place_doors_stairs_traps(self.level)

        # Place player
        all_pos = self.map.get_all_available_tiles(c.T_FLOOR,
                                                   self.objects,
                                                   without_objects=True)
        new_player_pos = all_pos.pop()
        self.player.x = new_player_pos[0]
        self.player.y = new_player_pos[1]
        self.visible_player_array = self.fov.get_vision_matrix_for(
            self.player, flag_explored=True)
        self.player.invalidate_fog_of_war = True
        self.player_sprite_group.add(self.player)

        # Camera
        self.camera = Camera(self.map.tile_width * TILESIZE_SCREEN,
                             self.map.tile_height * TILESIZE_SCREEN)
        # place monsters
        ItemFactory(self).build_list(50)
        MonsterFactory(self).build_list(130)
class SlicedEarley(object):
    """
    """

    def __init__(self, wcfg, wfsa, slice_vars):
        """
        """

        self._wcfg = wcfg
        self._wfsa = wfsa
        self._agenda = Agenda(active_container_type=ActiveQueue)
        self._predictions = set()  # (LHS, start)
        self._item_factory = ItemFactory()
        self.slice_vars = slice_vars

    def get_item(self, rule, dot, inner=[]):
        return self._item_factory.get_item(rule, dot, inner)

    def advance(self, item, dot):
        """returns a new item whose dot has been advanced"""
        return self.get_item(item.rule, dot, item.inner + (item.dot,))

    def axioms(self, symbol, start):
        rules = self._wcfg.get(symbol, None)
        if rules is None:  # impossible to rewrite the symbol
            return False
        if (symbol, start) in self._predictions:  # already predicted
            return True
        # otherwise add rewritings to the agenda
        self._predictions.add((symbol, start))
        self._agenda.extend(self.get_item(rule, start) for rule in rules)
        return True

    def prediction(self, item):
        """
        This operation tris to create items from the rules associated with the nonterminal ahead of the dot.
        It returns True when prediction happens, and False if it already happened before.
        """
        if (item.next, item.dot) in self._predictions:  # prediction already happened
            return False
        self._predictions.add((item.next, item.dot))
        new_items = [self.get_item(rule, item.dot) for rule in self._wcfg.get(item.next, frozenset())]
        self._agenda.extend(new_items)
        return True

    def scan(self, item):
        """
        This operation tries to scan over as many terminals as possible,
        but we only go as far as determinism allows.
        If we get to a nondeterminism, we stop scanning and add the relevant items to the agenda.
        """
        states = [item.dot]
        for sym in item.nextsymbols():
            if is_terminal(sym):
                arcs = self._wfsa.get_arcs(origin=states[-1], symbol=sym)
                if len(arcs) == 0:  # cannot scan the symbol
                    return False
                elif len(arcs) == 1:  # symbol is scanned deterministically
                    sto, _ = arcs[0]
                    states.append(sto)  # we do not create intermediate items, instead we scan as much as we can
                else:  # here we found a nondeterminism, we create all relevant items and add them to the agenda
                    # create items
                    for sto, w in arcs:
                        self._agenda.add(self.get_item(item.rule, sto, item.inner + tuple(states)))
                    return True
            else:  # that's it, scan bumped into a nonterminal symbol, time to wrap up
                break
        # here we should have scanned at least one terminal symbol
        # and we defined a deterministic path
        self._agenda.add(self.get_item(item.rule, states[-1], item.inner + tuple(states[:-1])))
        return True

    def complete_others(self, item):
        """
        This operation creates new item by advancing the dot of passive items that are waiting for a certain given complete item.
        It returns whether or not at least one passive item awaited for the given complete item.
        """
        if self._agenda.is_generating(item.rule.lhs, item.start, item.dot):
            return True
        new_items = [self.advance(incomplete, item.dot) for incomplete in self._agenda.iterwaiting(item.rule.lhs, item.start)]
        self._agenda.extend(new_items)
        return len(new_items) > 0  # was there any item waiting for the complete one?


    def complete_itself(self, item):
        """
        This operation tries to merge a given incomplete item with a previosly completed one.
        """
        new_items = [self.advance(item, sto) for sto in self._agenda.itercompletions(item.next, item.dot)]
        self._agenda.extend(new_items)
        return len(new_items) > 0

    def do(self, root='[S]', goal='[GOAL]'):

        wfsa = self._wfsa
        wcfg = self._wcfg
        agenda = self._agenda

        # start items of the kind
        # GOAL -> * ROOT, where * is an intial state of the wfsa
        if not any(self.axioms(root, start) for start in wfsa.iterinitial()):
            raise ValueError('No rule for the start symbol %s' % root)
        new_roots = set()

        while agenda:
            item = agenda.pop()  # always returns an active item

            if item.is_complete():
                # get slice variable for the current completed item
                u = self.slice_vars.get(item.rule.lhs, item.start, item.dot)

                # check whether the probability of the current completed item is above the threshold determined by
                # the slice variable
                if item.rule.log_prob > u:
                    # complete root item spanning from a start wfsa state to a final wfsa state
                    if item.rule.lhs == root and wfsa.is_initial(item.start) and wfsa.is_final(item.dot):
                        agenda.make_complete(item)
                        new_roots.add((root, item.start, item.dot))
                        agenda.make_passive(item)
                    else:
                        if self.complete_others(item):
                            agenda.make_complete(item)
                            agenda.make_passive(item)
                        else:  # a complete state is only kept in case it could potentially complete others
                            agenda.discard(item)
            else:
                if is_terminal(item.next):
                    # fire the operation 'scan'
                    self.scan(item)
                    agenda.discard(item)  # scanning renders incomplete items of this kind useless
                else:
                    if not wcfg.can_rewrite(item.next):  # if the NT does not exist this item is useless
                        agenda.discard(item)
                    else:
                        if not self.prediction(item):  # try to predict, otherwise try to complete itself
                            self.complete_itself(item)
                        agenda.make_passive(item)
        # converts complete items into rules
        logging.debug('Making forest...')
        return self.get_cfg(goal, root)

    def get_intersected_rule(self, item):
        lhs = make_symbol(item.rule.lhs, item.start, item.dot)
        positions = item.inner + (item.dot,)
        rhs = [make_symbol(sym, positions[i], positions[i + 1]) for i, sym in enumerate(item.rule.rhs)]
        return Rule(lhs, rhs, item.rule.log_prob)

    def get_cfg(self, goal, root):
        """
        Constructs the CFG by visiting complete items in a top-down fashion.
        This is effectively a reachability test and it serves the purpose of filtering nonterminal symbols
        that could never be reached from the root.
        Note that bottom-up intersection typically does enumerate a lot of useless (unreachable) items.
        This is the recursive procedure described in the paper (Nederhof and Satta, 2008).
        """

        G = WCFG()
        processed = set()
        fsa = self._wfsa
        itergenerating = self._agenda.itergenerating
        itercomplete = self._agenda.itercomplete

        def make_rules(lhs, start, end):
            if (start, lhs, end) in processed:
                return
            processed.add((lhs, start, end))
            for item in itercomplete(lhs, start, end):
                G.add(self.get_intersected_rule(item))
                fsa_states = item.inner + (item.dot,)
                for i, sym in itertools.ifilter(lambda (_, s): is_nonterminal(s), enumerate(item.rule.rhs)):
                    if (sym, fsa_states[i], fsa_states[
                            i + 1]) not in processed:  # Nederhof does not perform this test, but in python it turned out crucial
                        make_rules(sym, fsa_states[i], fsa_states[i + 1])

        # create goal items
        for start, ends in itergenerating(root):
            if not fsa.is_initial(start):
                continue
            for end in itertools.ifilter(lambda q: fsa.is_final(q), ends):
                make_rules(root, start, end)
                G.add(Rule(make_symbol(goal, None, None),
                           [make_symbol(root, start, end)], 0.0))

        return G
class SlicedNederhof(object):
    """
    This is an implementation of the CKY-inspired intersection due to Nederhof and Satta (2008).
    """

    def __init__(self, wcfg, wfsa, slice_vars):
        self._wcfg = wcfg
        self._wfsa = wfsa
        self._agenda = Agenda(active_container_type=ActiveQueue)
        self._firstsym = defaultdict(set)  # index rules by their first RHS symbol
        self._item_factory = ItemFactory()
        self.slice_vars = slice_vars

    def get_item(self, rule, dot, inner=[]):
        return self._item_factory.get_item(rule, dot, inner)
    
    def advance(self, item, dot):
        """returns a new item whose dot has been advanced"""
        return self.get_item(item.rule, dot, item.inner + (item.dot,))
        
    def add_symbol(self, sym, sfrom, sto):
        """
        This operation:
            1) completes items waiting for `sym` from `sfrom`
            2) instantiate delayed axioms
        Returns False if the annotated symbol had already been added, True otherwise
        """
        
        if self._agenda.is_generating(sym, sfrom, sto):
            return False

        # every item waiting for `sym` from `sfrom`
        for item in self._agenda.iterwaiting(sym, sfrom):
            self._agenda.add(self.advance(item, sto))

        # you may interpret this as a delayed axiom
        # every compatible rule in the grammar
        for r in self._firstsym.get(sym, set()):  
            self._agenda.add(self.get_item(r, sto, inner=(sfrom,)))  # can be interpreted as a lazy axiom

        return True

    def axioms(self):
        """
        The axioms of the program are based on the FSA transitions. 
        """
        # you may interpret the following as a sort of lazy axiom (based on grammar rules)
        for r in self._wcfg:
            self._firstsym[r.rhs[0]].add(r)
        # these are axioms based on the transitions of the automaton
        for sfrom, sto, sym, w in self._wfsa.iterarcs():
            self.add_symbol(sym, sfrom, sto)  

    def inference(self):
        """Exhausts the queue of active items"""
        agenda = self._agenda
        while agenda:
            item = agenda.pop()  # always returns an ACTIVE item
            # complete other items (by calling add_symbol), in case the input item is complete
            if item.is_complete():
                u = self.slice_vars.get(item.rule.lhs, item.start, item.dot)
                # check whether the probability of the current completed item is above the threshold determined by
                # the slice variable
                if item.rule.log_prob > u:
                    self.add_symbol(item.rule.lhs, item.start, item.dot)  # prove the symbol
                    agenda.make_complete(item)  # mark the item as complete
            else:
                # merges the input item with previously completed items effectively moving the input item's dot forward
                agenda.make_passive(item)
                for sto in agenda.itercompletions(item.next, item.dot):
                    agenda.add(self.advance(item, sto))  # move the dot forward

    def do(self, root='[S]', goal='[GOAL]'):
        """Runs the program and returns the intersected CFG"""
        self.axioms()
        self.inference()
        return get_cfg(goal, root, self._wfsa, self._agenda)
Esempio n. 12
0
class SlicedEarley(object):
    """
    """
    def __init__(self, wcfg, wfsa, slice_vars):
        """
        """

        self._wcfg = wcfg
        self._wfsa = wfsa
        self._agenda = Agenda(active_container_type=ActiveQueue)
        self._predictions = set()  # (LHS, start)
        self._item_factory = ItemFactory()
        self.slice_vars = slice_vars

    def get_item(self, rule, dot, inner=[]):
        return self._item_factory.get_item(rule, dot, inner)

    def advance(self, item, dot):
        """returns a new item whose dot has been advanced"""
        return self.get_item(item.rule, dot, item.inner + (item.dot, ))

    def axioms(self, symbol, start):
        rules = self._wcfg.get(symbol, None)
        if rules is None:  # impossible to rewrite the symbol
            return False
        if (symbol, start) in self._predictions:  # already predicted
            return True
        # otherwise add rewritings to the agenda
        self._predictions.add((symbol, start))
        self._agenda.extend(self.get_item(rule, start) for rule in rules)
        return True

    def prediction(self, item):
        """
        This operation tris to create items from the rules associated with the nonterminal ahead of the dot.
        It returns True when prediction happens, and False if it already happened before.
        """
        if (item.next,
                item.dot) in self._predictions:  # prediction already happened
            return False
        self._predictions.add((item.next, item.dot))
        new_items = [
            self.get_item(rule, item.dot)
            for rule in self._wcfg.get(item.next, frozenset())
        ]
        self._agenda.extend(new_items)
        return True

    def scan(self, item):
        """
        This operation tries to scan over as many terminals as possible,
        but we only go as far as determinism allows.
        If we get to a nondeterminism, we stop scanning and add the relevant items to the agenda.
        """
        states = [item.dot]
        for sym in item.nextsymbols():
            if is_terminal(sym):
                arcs = self._wfsa.get_arcs(origin=states[-1], symbol=sym)
                if len(arcs) == 0:  # cannot scan the symbol
                    return False
                elif len(arcs) == 1:  # symbol is scanned deterministically
                    sto, _ = arcs[0]
                    states.append(
                        sto
                    )  # we do not create intermediate items, instead we scan as much as we can
                else:  # here we found a nondeterminism, we create all relevant items and add them to the agenda
                    # create items
                    for sto, w in arcs:
                        self._agenda.add(
                            self.get_item(item.rule, sto,
                                          item.inner + tuple(states)))
                    return True
            else:  # that's it, scan bumped into a nonterminal symbol, time to wrap up
                break
        # here we should have scanned at least one terminal symbol
        # and we defined a deterministic path
        self._agenda.add(
            self.get_item(item.rule, states[-1],
                          item.inner + tuple(states[:-1])))
        return True

    def complete_others(self, item):
        """
        This operation creates new item by advancing the dot of passive items that are waiting for a certain given complete item.
        It returns whether or not at least one passive item awaited for the given complete item.
        """
        if self._agenda.is_generating(item.rule.lhs, item.start, item.dot):
            return True
        new_items = [
            self.advance(incomplete,
                         item.dot) for incomplete in self._agenda.iterwaiting(
                             item.rule.lhs, item.start)
        ]
        self._agenda.extend(new_items)
        return len(
            new_items) > 0  # was there any item waiting for the complete one?

    def complete_itself(self, item):
        """
        This operation tries to merge a given incomplete item with a previosly completed one.
        """
        new_items = [
            self.advance(item, sto)
            for sto in self._agenda.itercompletions(item.next, item.dot)
        ]
        self._agenda.extend(new_items)
        return len(new_items) > 0

    def do(self, root='[S]', goal='[GOAL]'):

        wfsa = self._wfsa
        wcfg = self._wcfg
        agenda = self._agenda

        # start items of the kind
        # GOAL -> * ROOT, where * is an intial state of the wfsa
        if not any(self.axioms(root, start) for start in wfsa.iterinitial()):
            raise ValueError('No rule for the start symbol %s' % root)
        new_roots = set()

        while agenda:
            item = agenda.pop()  # always returns an active item

            if item.is_complete():
                # get slice variable for the current completed item
                u = self.slice_vars.get(item.rule.lhs, item.start, item.dot)

                # check whether the probability of the current completed item is above the threshold determined by
                # the slice variable
                if item.rule.log_prob > u:
                    # complete root item spanning from a start wfsa state to a final wfsa state
                    if item.rule.lhs == root and wfsa.is_initial(
                            item.start) and wfsa.is_final(item.dot):
                        agenda.make_complete(item)
                        new_roots.add((root, item.start, item.dot))
                        agenda.make_passive(item)
                    else:
                        if self.complete_others(item):
                            agenda.make_complete(item)
                            agenda.make_passive(item)
                        else:  # a complete state is only kept in case it could potentially complete others
                            agenda.discard(item)
            else:
                if is_terminal(item.next):
                    # fire the operation 'scan'
                    self.scan(item)
                    agenda.discard(
                        item
                    )  # scanning renders incomplete items of this kind useless
                else:
                    if not wcfg.can_rewrite(
                            item.next
                    ):  # if the NT does not exist this item is useless
                        agenda.discard(item)
                    else:
                        if not self.prediction(
                                item
                        ):  # try to predict, otherwise try to complete itself
                            self.complete_itself(item)
                        agenda.make_passive(item)
        # converts complete items into rules
        logging.debug('Making forest...')
        return self.get_cfg(goal, root)

    def get_intersected_rule(self, item):
        lhs = make_symbol(item.rule.lhs, item.start, item.dot)
        positions = item.inner + (item.dot, )
        rhs = [
            make_symbol(sym, positions[i], positions[i + 1])
            for i, sym in enumerate(item.rule.rhs)
        ]
        return Rule(lhs, rhs, item.rule.log_prob)

    def get_cfg(self, goal, root):
        """
        Constructs the CFG by visiting complete items in a top-down fashion.
        This is effectively a reachability test and it serves the purpose of filtering nonterminal symbols
        that could never be reached from the root.
        Note that bottom-up intersection typically does enumerate a lot of useless (unreachable) items.
        This is the recursive procedure described in the paper (Nederhof and Satta, 2008).
        """

        G = WCFG()
        processed = set()
        fsa = self._wfsa
        itergenerating = self._agenda.itergenerating
        itercomplete = self._agenda.itercomplete

        def make_rules(lhs, start, end):
            if (start, lhs, end) in processed:
                return
            processed.add((lhs, start, end))
            for item in itercomplete(lhs, start, end):
                G.add(self.get_intersected_rule(item))
                fsa_states = item.inner + (item.dot, )
                for i, sym in itertools.ifilter(
                        lambda (_, s): is_nonterminal(s),
                        enumerate(item.rule.rhs)):
                    if (
                            sym, fsa_states[i], fsa_states[i + 1]
                    ) not in processed:  # Nederhof does not perform this test, but in python it turned out crucial
                        make_rules(sym, fsa_states[i], fsa_states[i + 1])

        # create goal items
        for start, ends in itergenerating(root):
            if not fsa.is_initial(start):
                continue
            for end in itertools.ifilter(lambda q: fsa.is_final(q), ends):
                make_rules(root, start, end)
                G.add(
                    Rule(make_symbol(goal, None, None),
                         [make_symbol(root, start, end)], 0.0))

        return G
Esempio n. 13
0
class TestItemMethods(unittest.TestCase):
    def setUp(self):
        self.factory = ItemFactory(item_data)

    def test_traitless_item(self):
        item = self.factory.create_from_noun("basic")
        self.assertEqual(item.name, "a very basic item")
        self.assertIsInstance(item, Item)

    def test_basic_item(self):
        item = self.factory.create_from_noun("shirt")
        self.assertEqual(item.name, "a natty Paisley print shirt")
        self.assertEqual(
            item.description,
            "a delightful fitted shirt with a strong Paisley pattern. As you look closely at it your eyes water slightly."
        )
        self.assertTrue(item.has_trait("moveable"))
        self.assertTrue(item.has_trait("wearable"))

    def test_basic_stateful_item(self):
        item = self.factory.create_from_noun("torch")
        self.assertEqual(item.name, "an Ever Ready torch")
        self.assertTrue(item.has_trait("moveable"))
        self.assertFalse(item.has_trait("wearable"))

    def test_state_change_returns(self):
        item = self.factory.create_from_noun("torch")
        (result, message) = item.do_verb("turn off")
        self.assertFalse(
            result,
            "Turning off a turned off item unexpectedly did something.")
        (result, message) = item.do_verb("turn on")
        self.assertTrue(result, "Could not turn on a turned off item.")
        self.assertEqual(message, "You turn on the torch.",
                         "Wrong message when turning on item.")
        (result, message) = item.do_verb("turn off")
        self.assertTrue(result, "Could not turn off a turned on item.")
        self.assertEqual(message, "You turn off the torch.",
                         "Wrong message when turning off item.")

    def test_stateful_item_states(self):
        item = self.factory.create_from_noun("torch")

        (result, message) = item.do_verb("turn on")
        self.assertTrue(result, "You should be able to turn on a torch.")
        (result, message) = item.do_verb("turn off")
        self.assertTrue(result, "You should be able to turn off a torch.")

        (result, message) = item.do_verb("throw")
        self.assertFalse(result, "Shouln't be able to throw the torch.")
        self.assertEqual(message, "You can't do that.",
                         "Wrong failure message when throwing torch.")

        self.assertEqual(
            item.description,
            "a plastic 1970s Ever Ready torch. It is switched off.")
        item.do_verb("turn on")
        self.assertEqual(
            item.description,
            "a plastic 1970s Ever Ready torch. It's switched on, and emits a surprising amount of light."
        )
        item.do_verb("turn off")
        self.assertEqual(
            item.description,
            "a plastic 1970s Ever Ready torch. It is switched off.")
        item.do_verb("turn off")
        self.assertEqual(
            item.description,
            "a plastic 1970s Ever Ready torch. It is switched off.")

    def test_simple_verbable_item(self):
        item = self.factory.create_from_noun("simpleverbable")
        (result, message) = item.do_verb("flobble")
        self.assertFalse(result,
                         "Shouldn't be able to flobble a SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertTrue(result,
                        "Should be able to command a SimpleVerbableItem.")
        self.assertEqual(message, "simple verb message result",
                         "Wrong command result from SimpleVerbableItem")

    @patch('item.random')
    def test_simple_verbable_item_with_random_result(self, random):
        # https://stackoverflow.com/questions/26091330/how-to-validate-a-unit-test-with-random-values
        # Seed a patched random number generator
        my_random = Random(123)
        random.choice._mock_side_effect = my_random.choice

        item = self.factory.create_from_noun("simpleverbablerandom")
        (result, message) = item.do_verb("flobble")
        self.assertFalse(result,
                         "Shouldn't be able to flobble a SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertTrue(result,
                        "Should be able to command a SimpleVerbableItem.")

        # This is the order our seed guarantees:
        self.assertEqual(message, "message0",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message1",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message0",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message1",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message1",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message0",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message0",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message1",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message2",
                         "Wrong command result from SimpleVerbableItem")
        (result, message) = item.do_verb("command")
        self.assertEqual(message, "message2",
                         "Wrong command result from SimpleVerbableItem")

    def test_container_item(self):
        item = self.factory.create_from_noun("bag")
        self.assertTrue(item.has("shirt"))
        self.assertTrue(item.has("torch"))

    def test_stateful_container_item(self):
        item = self.factory.create_from_noun("cupboard")
        self.assertFalse(item.has("shirt"))
        self.assertFalse(item.has("torch"))
        item.do_verb("open")
        self.assertTrue(item.has("shirt"))
        self.assertTrue(item.has("torch"))

    def test_recursive_take(self):
        container = self.factory.create_from_noun("outercontainer")
        self.assertTrue(container.has("bag"))
        self.assertTrue(container.has("shirt"))
        self.assertTrue(container.has("torch"))

        self.assertIsNotNone(container.take("torch"))
        self.assertIsNotNone(container.take("shirt"))
        self.assertIsNotNone(container.take("bag"))

    def test_recursive_get_item_reference(self):
        container = self.factory.create_from_noun("outercontainer")

        bag = container.get_item_reference("bag")
        self.assertIsNotNone(bag, "Could not get bag from inside container")
        self.assertEqual(bag.id, "bag")

        shirt = container.get_item_reference("shirt")
        self.assertIsNotNone(
            shirt, "Could not get shirt from inside bag inside container")
        self.assertEqual(shirt.id, "shirt")

        torch = container.get_item_reference("torch")
        self.assertIsNotNone(
            torch, "Could not get torch from inside bag inside container")
        self.assertEqual(torch.id, "torch")

    def test_recursive_stateful_container(self):
        anotherbag = self.factory.create_from_noun("anotherbag")
        self.assertTrue(anotherbag.has("shirt"))

    def test_factory(self):
        item = self.factory.create_from_noun("torch")
        self.assertIsInstance(item, StatefulItem)
        self.assertEqual(item.name, "an Ever Ready torch")
        self.assertTrue(item.has_trait("moveable"))
        self.assertFalse(item.has_trait("wearable"))

    def test_stateful_item_rules(self):
        item = self.factory.create_from_noun("statefulitemwithrules")
        (result, message) = item.do_verb("turn off")
        self.assertFalse(
            result, "Turning off an item that's turned off shouldn't work.")

        (result,
         message) = item.do_verb("turn on",
                                 extras={"player_appearance_level": 99})
        self.assertFalse(
            result,
            "Should not be able to turn item on with player appearance below 100"
        )
        self.assertEqual(message, "Appearance rule condition not met.")

        (result,
         message) = item.do_verb("turn on",
                                 extras={"player_appearance_level": 100})
        self.assertTrue(
            result,
            "Should be able to turn item on with player appearance of 100")
        self.assertEqual(message, "Turning on.")

        # As you were
        item.do_verb("turn off")

        # Should get an exception if we don't pass in the required extra.
        with self.assertRaisesRegex(
                Exception, "Item.*requires missing extra.*") as context:
            item.do_verb("turn on", extras={"nottherightextra": 123})
Esempio n. 14
0
class Nederhof(object):
    """
    This is an implementation of the CKY-inspired intersection due to Nederhof and Satta (2008).
    """
    def __init__(self, wcfg, wfsa):
        self._wcfg = wcfg
        self._wfsa = wfsa
        self._agenda = Agenda(active_container_type=ActiveQueue)
        self._firstsym = defaultdict(
            set)  # index rules by their first RHS symbol
        self._item_factory = ItemFactory()

    def get_item(self, rule, dot, inner=[]):
        return self._item_factory.get_item(rule, dot, inner)

    def advance(self, item, dot):
        """returns a new item whose dot has been advanced"""
        return self.get_item(item.rule, dot, item.inner + (item.dot, ))

    def add_symbol(self, sym, sfrom, sto):
        """
        This operation:
            1) completes items waiting for `sym` from `sfrom`
            2) instantiate delayed axioms
        Returns False if the annotated symbol had already been added, True otherwise
        """

        if self._agenda.is_generating(sym, sfrom, sto):
            return False

        # every item waiting for `sym` from `sfrom`
        for item in self._agenda.iterwaiting(sym, sfrom):
            self._agenda.add(self.advance(item, sto))

        # you may interpret this as a delayed axiom
        # every compatible rule in the grammar
        for r in self._firstsym.get(sym, set()):
            self._agenda.add(self.get_item(
                r, sto, inner=(sfrom, )))  # can be interpreted as a lazy axiom

        return True

    def axioms(self):
        """
        The axioms of the program are based on the FSA transitions. 
        """
        # you may interpret the following as a sort of lazy axiom (based on grammar rules)
        for r in self._wcfg:
            self._firstsym[r.rhs[0]].add(r)
        # these are axioms based on the transitions of the automaton
        for sfrom, sto, sym, w in self._wfsa.iterarcs():
            self.add_symbol(sym, sfrom, sto)

    def inference(self):
        """Exhausts the queue of active items"""
        agenda = self._agenda
        while agenda:
            item = agenda.pop()  # always returns an ACTIVE item
            # complete other items (by calling add_symbol), in case the input item is complete
            if item.is_complete():
                self.add_symbol(item.rule.lhs, item.start,
                                item.dot)  # prove the symbol
                agenda.make_complete(item)  # mark the item as complete
            else:
                # merges the input item with previously completed items effectively moving the input item's dot forward
                agenda.make_passive(item)
                for sto in agenda.itercompletions(item.next, item.dot):
                    agenda.add(self.advance(item, sto))  # move the dot forward

    def do(self, root='[S]', goal='[GOAL]'):
        """Runs the program and returns the intersected CFG"""
        self.axioms()
        self.inference()
        return get_cfg(goal, root, self._wfsa, self._agenda)
Esempio n. 15
0
 def setUp(self):
     self.factory = ItemFactory(item_data)
Esempio n. 16
0
class TestPlayerMethods(unittest.TestCase):
    def setUp(self):
        self.item_factory = ItemFactory(item_data)

        self.player = Player(
            inventory={},
            wearing=self.item_factory.create_dictionary_from_nouns(
                [Noun.BOXER_SHORTS]),
            score=0,
            health=100,  # percent
            caffeine_level=50  # milligrams
        )

    def test_combing(self):

        comb = self.item_factory.create_from_noun(Noun.COMB)
        beard_oil = self.item_factory.create_from_noun(Noun.BEARD_OIL)
        self.assertEqual(self.player.beard_status, BeardHealth.STRAGGLY_MESS)

        (result, message) = self.player.do_verb(Verb.COMB, Noun.BEARD)
        self.assertFalse(
            result, "Shouldn't be able to comb if you're not holding a comb")

        self.player.give(comb)

        (result, message) = self.player.do_verb(Verb.COMB)
        self.assertFalse(
            result,
            "I didn't provide a noun, so what the hell did I just comb?")
        self.assertEqual(
            message, "Comb what?",
            "Unexpected message when trying to comb without a noun")

        (result, message) = self.player.do_verb(Verb.COMB, Noun.BOXER_SHORTS)
        self.assertFalse(result,
                         "You should *not* be able to comb your shorts")
        self.assertEqual(
            message, "You can't comb that.",
            "Unexpected message when trying to comb without a noun")

        (result, message) = self.player.do_verb(Verb.COMB, Noun.BEARD)
        self.assertTrue(result)
        self.assertEqual(
            self.player.beard_status, BeardHealth.QUITE_TIDY,
            "Combing beard without oil should result in QUITE TIDY")

        (result, message) = self.player.do_verb(Verb.COMB, Noun.BEARD)
        self.assertFalse(result)
        self.assertEqual(
            self.player.beard_status, BeardHealth.QUITE_TIDY,
            "Combing an already tidy beard should change nothing.")

        self.player.give(beard_oil)
        (result, message) = self.player.do_verb(Verb.COMB, Noun.BEARD)
        self.assertFalse(
            result, "Just having the beard oil should make no difference")
        self.assertEqual(
            self.player.beard_status, BeardHealth.QUITE_TIDY,
            "Just having the beard oil should make no difference")

        self.player.wear(Noun.BEARD_OIL)
        (result, message) = self.player.do_verb(Verb.COMB, Noun.BEARD)
        self.assertTrue(
            result,
            "Combing a QUITE TIDY beard while wearing the beard oil should work"
        )
        self.assertEqual(
            self.player.beard_status, BeardHealth.PERFECTION,
            "Combing a QUITE TIDY beard while wearing the beard oil should result in PERFECTION"
        )

    def test_riding(self):
        # Something you can't ride
        (result, message) = self.player.do_verb(Verb.RIDE, Noun.BOXER_SHORTS)
        self.assertFalse(result, "Shouldn't be able to ride boxer shorts!")

        # Something you can ride
        bike = self.item_factory.create_from_noun(Noun.PENNY_FARTHING)

        self.assertFalse(self.player.is_riding_anything)

        (result, message) = self.player.do_verb(Verb.RIDE, Noun.PENNY_FARTHING)
        self.assertFalse(
            result,
            "Shouldn't be able to ride the bike unless you're holding it.")

        self.player.give(bike)
        (result, message) = self.player.do_verb(Verb.RIDE, Noun.PENNY_FARTHING)
        self.assertTrue(
            result, "Should be able to ride the bike if you're holding it.")

        (result, message) = self.player.do_verb(Verb.DISMOUNT,
                                                Noun.BOXER_SHORTS)
        self.assertFalse(
            result,
            "Shouldn't be able to dismount something you're not riding.")

        self.assertTrue(self.player.is_riding_anything)
        self.assertTrue(self.player.is_riding(Noun.PENNY_FARTHING))
        self.assertFalse(self.player.is_riding(Noun.BOXER_SHORTS))

        (item, message) = self.player.take(Noun.PENNY_FARTHING)
        self.assertIsNone(
            item, "Shouldn't be able to drop something you're riding.")

        (result, message) = self.player.do_verb(Verb.DISMOUNT,
                                                Noun.PENNY_FARTHING)
        self.assertTrue(
            result, "Should be able to dismount the bike if you're riding it.")

        self.assertFalse(self.player.is_riding_anything)

        # Shouldn't be able to ride anything twice
        (result, message) = self.player.do_verb(Verb.RIDE, Noun.PENNY_FARTHING)
        (result, message) = self.player.do_verb(Verb.RIDE, Noun.PENNY_FARTHING)
        self.assertFalse(
            result, "Shouldn't be able to ride more than one thing at once.")

        self.player.do_verb(Verb.DISMOUNT, Noun.PENNY_FARTHING)
        rules = {"can_ride": (False, "You can't ride that in here!")}
        (result, message) = self.player.do_verb(Verb.RIDE, Noun.PENNY_FARTHING,
                                                rules)
        self.assertFalse(result,
                         "Shouldn't be able to ride if prohibited by rules.")
        self.assertEqual(message, "You can't ride that in here!")

    def test_basic_wearing(self):
        self.assertFalse(
            self.player.is_fully_clothed,
            "Player wearing just boxers shouldn't read as fully clothed.")
        # These trousers aren't wearable:
        attrs = {
            'has_trait.return_value': False,
            'get_trait.return_value': None
        }
        trousers = Mock(id="trousers", name="trousers", **attrs)

        self.player.give(trousers)
        (result, message) = self.player.wear("trousers")
        self.assertFalse(
            result,
            "Should not be able to wear an item with no wearable trait")
        self.assertEqual(message, "You can't wear that.",
                         "Unexpected message from wear failure")

        # This shirt is wearable and moveable
        def has_trait(trait):
            return trait in ("wearable", "moveable")

        def get_trait(trait):
            return {} if trait in ("wearable", "moveable") else None

        attrs = {
            'has_trait.side_effect': has_trait,
            'get_trait.side_effect': get_trait
        }
        shirt = Mock(id="shirt", name="shirt", **attrs)

        self.player.give(shirt)
        (result, message) = self.player.wear("shirt")
        self.assertTrue(
            result,
            f"Should be able to wear a basic wearable item. Message was: {message}"
        )

    def test_wearing_tops(self):
        # Two wearable, moveable tops:
        def has_trait(trait):
            return trait in ("wearable", "moveable")

        def get_trait(trait):
            if trait in ("wearable"): return {"slot": "top"}
            if trait in ("moveable"): return {}
            return None

        attrs = {
            'has_trait.side_effect': has_trait,
            'get_trait.side_effect': get_trait
        }
        shirt1 = Mock(id="shirt1", name="shirt one", **attrs)
        shirt2 = Mock(id="shirt2", name="shirt two", **attrs)

        self.player.give(shirt1)
        self.player.give(shirt2)

        (result, message) = self.player.wear("shirt1")
        self.assertTrue(
            result,
            f"Should be able to wear one top. Failure message was: {message}")

        (result, message) = self.player.wear("shirt2")
        self.assertFalse(
            result,
            f"Should not be able to wear two tops. Unexpected success message was: {message}"
        )
        self.assertIn(
            "take something off", message,
            "Failure message on trying to wear two shirts should include correct advice."
        )

    def test_wearing_bottoms(self):
        # Two wearable, moveable bottoms:
        def has_trait(trait):
            return trait in ("wearable", "moveable")

        def get_trait(trait):
            if trait in ("wearable"): return {"slot": "bottom"}
            if trait in ("moveable"): return {}
            return None

        attrs = {
            'has_trait.side_effect': has_trait,
            'get_trait.side_effect': get_trait
        }
        trousers1 = Mock(id="trousers1", **attrs)
        # Workaround because Mock itself has an annoying name attribute! https://docs.python.org/3/library/unittest.mock.html#mock-names-and-the-name-attribute
        trousers1.configure_mock(name="trousers1")
        trousers2 = Mock(id="trousers2", name="trousers two", **attrs)
        # Workaround because Mock itself has an annoying name attribute! https://docs.python.org/3/library/unittest.mock.html#mock-names-and-the-name-attribute
        trousers2.configure_mock(name="trousers2")

        self.player.give(trousers1)
        self.player.give(trousers2)

        (result, message) = self.player.wear("trousers1")
        self.assertTrue(
            result,
            f"Should be able to wear one set of bottoms. Failure message was: {message}"
        )

        (result, message) = self.player.wear("trousers2")
        self.assertFalse(
            result,
            f"Should not be able to wear two sets of bottoms. Unexpected success message was: {message}"
        )
        self.assertIn(
            "take something off", message,
            "Failure message on trying to wear two pairs of trousers should include correct advice."
        )

    def test_wearing_status(self):
        # Top
        def has_trait_top(trait):
            return trait in ("wearable", "moveable")

        def get_trait_top(trait):
            if trait in ("moveable"): return {}
            if trait in ("wearable"): return {"slot": "top"}
            return None

        attrs = {
            'has_trait.side_effect': has_trait_top,
            'get_trait.side_effect': get_trait_top
        }
        shirt = Mock(id="shirt", **attrs)
        # Workaround because Mock itself has an annoying name attribute! https://docs.python.org/3/library/unittest.mock.html#mock-names-and-the-name-attribute
        shirt.configure_mock(name="shirt")

        # Bottoms
        def has_trait_bottom(trait):
            return trait in ("wearable", "moveable")

        def get_trait_bottom(trait):
            if trait in ("wearable"): return {"slot": "bottom"}
            if trait in ("moveable"): return {}
            return None

        attrs = {
            'has_trait.side_effect': has_trait_bottom,
            'get_trait.side_effect': get_trait_bottom
        }
        trousers = Mock(id="trousers", **attrs)
        # Workaround because Mock itself has an annoying name attribute! https://docs.python.org/3/library/unittest.mock.html#mock-names-and-the-name-attribute
        trousers.configure_mock(name="trousers")

        self.player.give(shirt)
        self.player.give(trousers)

        # Basics
        self.assertTrue(self.player.is_wearing(Noun.BOXER_SHORTS),
                        "Test player should start with boxers on")
        self.assertFalse(
            self.player.is_wearing("didgeridoo"),
            "is_wearing should not be true for an arbitrary didgeridoo")

        self.assertFalse(self.player.is_fully_clothed)

        # Add a top and re-test
        self.player.wear("shirt")
        self.assertEqual(self.player.wearing_in_slot('top'), shirt)
        self.assertIsNone(self.player.wearing_in_slot('bottom'))
        self.assertFalse(self.player.is_fully_clothed)

        # Add trousers
        self.player.wear("trousers")
        self.assertEqual(self.player.wearing_in_slot('top'), shirt)
        self.assertEqual(self.player.wearing_in_slot('bottom'), trousers)
        self.assertTrue(self.player.is_fully_clothed)

        self.player.unwear("trousers")
        self.assertFalse(self.player.is_fully_clothed)

        self.player.unwear("shirt")
        self.assertFalse(self.player.is_fully_clothed)
Esempio n. 17
0
    def print(self, text=""):
        # "If replace_whitespace is false, newlines may appear in the middle of a
        #  line and cause strange output. For this reason, text should be split
        #  into paragraphs (using str.splitlines() or similar) which are wrapped
        #  separately." -- https://docs.python.org/3/library/textwrap.html
        # "Sigh" -- me
        for line in text.splitlines():
            print(self.wrapper.fill(line))


o = Outputter()

# All our items are stamped out from this data-driven
# item factory.
item_factory = ItemFactory(data.item_data)

rooms = {}

# Build the universe.
for id, room_data in data.room_data.items():
    rooms[id] = Room(id, item_factory, room_data)

o.print("\nWelcome to the Bristol Hipster Adventure.\n")

current_room = rooms["livingroom"]
visited_rooms = set()
suppress_room_description = False
no_tick = False

player = Player(