mwchase icon

LC:Nobilis Update 6: diff

mwchase | PRO | 06/19/17 04:48:05 PM UTC | 0 ⭐ | 903 👁️ | Never ⏰ | []
Diff |

10.33 KB

|

None

|

0 👍

/

0 👎

diff --git a/src/nobilis/game_data.py b/src/nobilis/game_data.py
--- a/src/nobilis/game_data.py
+++ b/src/nobilis/game_data.py
@@ -244,18 +244,18 @@
 SPECIAL_CONTACT_TEMPLATES += GeneralTemplate('Mystery Cult', ()),
 
 
-AFFLIATION_TEMPLATES = ()
-AFFLIATION_TEMPLATES += GeneralTemplate(
+AFFILIATION_TEMPLATES = ()
+AFFILIATION_TEMPLATES += GeneralTemplate(
     '(The Song of) Heaven', (1, 2, 3)),
-AFFLIATION_TEMPLATES += GeneralTemplate(
+AFFILIATION_TEMPLATES += GeneralTemplate(
     '(The Song of) Hell', (4, 5, 6)),
-AFFLIATION_TEMPLATES += GeneralTemplate(
+AFFILIATION_TEMPLATES += GeneralTemplate(
     '(The Song of) The Light', (7, 8)),
-AFFLIATION_TEMPLATES += GeneralTemplate(
+AFFILIATION_TEMPLATES += GeneralTemplate(
     '(The Song of) The Dark', (9, 10)),
-AFFLIATION_TEMPLATES += GeneralTemplate(
+AFFILIATION_TEMPLATES += GeneralTemplate(
     '(The Song of) The Wild', (11, 12, 13)),
-AFFLIATION_TEMPLATES += GeneralTemplate(
+AFFILIATION_TEMPLATES += GeneralTemplate(
     'An Independent Song', (14, 15, 16)),
 
 
diff --git a/src/nobilis/lifepath.py b/src/nobilis/lifepath.py
--- a/src/nobilis/lifepath.py
+++ b/src/nobilis/lifepath.py
@@ -12,6 +12,7 @@
 
 
 def key(item):
+    """Return a type-based key for the given item."""
     return type(item), item
 
 
@@ -19,6 +20,7 @@
 # now. Basically, it needs to be used as a mixin AHEAD OF a namedtuple class
 # with a first field of "hash".
 class QuickHash:
+    """Base class for namedtuples that store their hash in the first field."""
 
     __slots__ = ()
 
@@ -28,6 +30,7 @@
 
     @classmethod
     def _pre_hash(cls, *args, **kwargs):
+        """Return the hash the instance will use."""
         args = tuple(args)
         fields = getattr(cls, '_fields', ('hash',))[1:]
         keywords = fields[len(args):]
@@ -42,10 +45,12 @@
 
 
 class Child(Business):
+    """Purely structural child visitor."""
 
     __slots__ = ()
 
     def default_visit(self, node):
+        """Yield zero times."""
         yield from ()
 
 
@@ -53,6 +58,7 @@
 
 
 class Tree(QH, nt('Tree', 'hash root reverse_mapping')):
+    """Purely structural tree structure, for determining parents."""
 
     __slots__ = ()
 
@@ -71,77 +77,64 @@
         return super().__new__(cls, root, mapping.Map(reverse_mapping))
 
     def parent(self, node):
+        """Return the parent of the given node."""
         return self.reverse_mapping.get(key(node))
 
 
 @Business.mark
 class Choice(QH, nt('Choice', 'hash template')):
-
-    __slots__ = ()
-
-
[email protected]
-class ChoiceDisplay(QH, nt('ChoiceDisplay', 'hash choice')):
+    """An underlying choice for tracking state."""
 
     __slots__ = ()
 
 
+# First to test in rewrite.
 @Business.mark
-class ChoiceTaken(QH, nt('ChoiceTaken', 'hash choice')):
+class Tab(QH, nt('Tab', 'hash name node')):
 
     __slots__ = ()
 
 
[email protected]
-class ChoiceListed(QH, nt('ChoiceListed', 'hash choice')):
-
-    __slots__ = ()
-
-
+# First to test in rewrite.
 @Business.mark
-class ChoiceList(QH, nt('ChoiceList', 'hash choices initial_min initial_max')):
-
-    __slots__ = ()
-
-
[email protected]
-class DisplayList(QH, nt('DisplayList', 'hash factory choices_ sections_')):
+class TabList(QH, nt('TabList', 'hash tabs')):
 
     __slots__ = ()
 
     @property
-    def choices(self):
-        return map_tuple.MapTuple(self.factory, self.choices_)
-
-    @property
-    def sections(self):
-        return map_tuple.MapTuple(
-            functools.partial(Section, self), range(len(self.sections_)))
+    def enumerated_names(self):
+        return tuple(enumerate(tab.name for tab in self.tabs))
 
 
+# Second to test in rewrite, may need rename.
 @Business.mark
-class Section(QH, nt('Section', 'hash display_list index')):
+class Table(QH, nt('Table', 'hash heading node')):
+
+    __slots__ = ()
+
+
+# Second to test in rewrite, may need rename.
[email protected]
+class TableList(QH, nt('TableList', 'hash items')):
 
     __slots__ = ()
 
-    @property
-    def _data(self):
-        return self.display_list.sections_[self.index]
 
-    @property
-    def name(self):
-        return self._data[0]
-
-    @property
-    def predicate(self):
-        return self._data[1]
[email protected](Tab)
+def Child(self, node, next_visitor):
+    yield node.node
 
 
[email protected](ChoiceList)
[email protected](TabList)
 def Child(self, node, next_visitor):
-    yield from node.choices
+    yield from node.tabs
 
 
[email protected](DisplayList)
[email protected](Table)
 def Child(self, node, next_visitor):
-    yield from node.choices
+    yield node.node
+
+
[email protected](TableList)
+def Child(self, node, next_visitor):
+    yield from node.items
diff --git a/tests/nobilis/test_lifepath.py b/tests/nobilis/test_lifepath.py
--- a/tests/nobilis/test_lifepath.py
+++ b/tests/nobilis/test_lifepath.py
@@ -7,7 +7,7 @@
 
 def test_key(lifepath):
     assert lifepath.key(lifepath.Choice(None)) != lifepath.key(
-        lifepath.ChoiceDisplay(None))
+        lifepath.TabList(None))
 
 
 def test_hash_amortization(lifepath):
@@ -61,55 +61,133 @@
 def test_children(lifepath):
     child = lifepath.Child()
 
-    leaf = lifepath.Choice(None)
+    tab = lifepath.Tab('name', None)
 
-    assert tuple(child.visit(leaf)) == ()
+    tab_list = lifepath.TabList((tab,))
+
+    assert tuple(child.visit(tab_list)) == (tab,)
+    assert tuple(child.visit(tab)) == (None,)
 
-    for wrapper in (lifepath.ChoiceDisplay, lifepath.ChoiceTaken,
-                    lifepath.ChoiceListed):
-        assert tuple(child.visit(wrapper(leaf))) == ()
+    item = lifepath.Table('heading', None)
 
-    assert tuple(child.visit(lifepath.ChoiceList((leaf,), 0, None))) == (leaf,)
+    item_list = lifepath.TableList((item,))
 
-    display_list = lifepath.DisplayList(
-        lifepath.ChoiceDisplay, (leaf,), (('name', None),))
-
-    assert tuple(child.visit(display_list)) == (lifepath.ChoiceDisplay(leaf),)
+    assert tuple(child.visit(item_list)) == (item,)
+    assert tuple(child.visit(item)) == (None,)
 
 
 def test_tree(lifepath):
-    leaf = lifepath.Choice(None)
-    root = lifepath.ChoiceList((leaf,), 0, None)
+    leaf = lifepath.Tab('test1', None)
+    root = lifepath.TabList((leaf,))
     tree = lifepath.Tree(root)
     assert tree.parent(leaf) == root
 
-    rooter = lifepath.ChoiceList((root,), 0, None)
+    rooter = lifepath.TabList((root,))
 
     treeer = lifepath.Tree(rooter)
     assert treeer.parent(root) == rooter
     assert treeer.parent(leaf) == root
 
-    dag = lifepath.ChoiceList((leaf, leaf), 0, None)
+    dag = lifepath.TabList((leaf, leaf))
 
     with pytest.raises(ValueError):
         print(lifepath.Tree(dag))
 
 
-def test_section(lifepath):
-    leaf = lifepath.Choice(None)
-    sentinel = object()
-
-    display_list = lifepath.DisplayList(
-        lifepath.ChoiceDisplay, (leaf,), (('name', sentinel),))
-
-    section, = display_list.sections
-
-    assert section.name == 'name'
-    assert section.predicate is sentinel
-
-
 def test_state(lifepath):
     # Okay, so, let's think how this has to go.
     # Ideally, I wouldn't be relying on mutable state, so...
     # state = lifepath.State()
     pass
+
+
+# Okay, let's start over. At the current way of thinking of things, a character
+# sheet is going to have multiple tabs.
+
+def test_power_tabs(lifepath):
+    placeholder = object()
+
+    # Must be selected before the others.
+    key_tab = lifepath.Tab('Keys', placeholder)
+    # No additional dependencies.
+    foundation_tab = lifepath.Tab('Foundation', placeholder)
+    # No additional dependencies.
+    estate_tab = lifepath.Tab('Estate', placeholder)
+    # Internal dependencies.
+    origins_tab = lifepath.Tab('Origins', placeholder)
+    # Some interaction with Origins.
+    contacts_tab = lifepath.Tab('Contacts', placeholder)
+    # No additional dependencies.
+    affiliation_tab = lifepath.Tab('Affiliation', placeholder)
+    # No additional dependencies.
+    background_tab = lifepath.Tab('Background', placeholder)
+
+    tab_list = lifepath.TabList((
+        key_tab,
+        foundation_tab,
+        estate_tab,
+        origins_tab,
+        contacts_tab,
+        affiliation_tab,
+        background_tab))
+
+    # Now that we have the tab_list, we need to reason about it...
+    # Would be good to get an enumerated list of names.
+
+    assert tab_list.enumerated_names == (
+        (0, 'Keys'),
+        (1, 'Foundation'),
+        (2, 'Estate'),
+        (3, 'Origins'),
+        (4, 'Contacts'),
+        (5, 'Affiliation'),
+        (6, 'Background'),)
+
+
+# Actually, what if I do both kinds of character sheet?
+
+def test_deceiver_tabs(lifepath):
+    placeholder = object()
+
+    # Must be selected before the others.
+    key_tab = lifepath.Tab('Keys', placeholder)
+    # The Foundation tab seems the most mix-and-matchable.
+    # No additional dependencies.
+    foundation_tab = lifepath.Tab('Foundation', placeholder)
+    # No additional dependencies.
+    p_state_tab = lifepath.Tab('pState', placeholder)
+    # No internal dependencies.
+    breakthrough_tab = lifepath.Tab('Breakthrough', placeholder)
+    # May end up with 2 plan tabs
+    # No internal dependencies.
+    plans_tab = lifepath.Tab('Plans', placeholder)
+    # Contacts divided into typical and rare, both sorted, which implies some
+    # way of marking them outside of a section label.
+    # Of note: no dependency on other sections. Just pick "up to three"
+    # Not sure if that REQUIRES at least 1, it's probably a good idea though.
+    # No internal dependencies.
+    contacts_tab = lifepath.Tab('Contacts', placeholder)
+    # No internal dependencies.
+    justification_tab = lifepath.Tab('Justification', placeholder)
+    # No internal dependencies.
+    territory_tab = lifepath.Tab('Territory', placeholder)
+
+    tab_list = lifepath.TabList((
+        key_tab,
+        foundation_tab,
+        p_state_tab,
+        breakthrough_tab,
+        plans_tab,
+        contacts_tab,
+        justification_tab,
+        territory_tab))
+
+    assert tab_list.enumerated_names == (
+        (0, 'Keys'),
+        (1, 'Foundation'),
+        (2, 'pState'),
+        (3, 'Breakthrough'),
+        (4, 'Plans'),
+        (5, 'Contacts'),
+        (6, 'Justification'),
+        (7, 'Territory'),)

Comments