mwchase

LC:Nobilis Update 6: diff

Jun 19th, 2017
897
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 10.33 KB | None | 0 0
  1. diff --git a/src/nobilis/game_data.py b/src/nobilis/game_data.py
  2. --- a/src/nobilis/game_data.py
  3. +++ b/src/nobilis/game_data.py
  4. @@ -244,18 +244,18 @@
  5.  SPECIAL_CONTACT_TEMPLATES += GeneralTemplate('Mystery Cult', ()),
  6.  
  7.  
  8. -AFFLIATION_TEMPLATES = ()
  9. -AFFLIATION_TEMPLATES += GeneralTemplate(
  10. +AFFILIATION_TEMPLATES = ()
  11. +AFFILIATION_TEMPLATES += GeneralTemplate(
  12.      '(The Song of) Heaven', (1, 2, 3)),
  13. -AFFLIATION_TEMPLATES += GeneralTemplate(
  14. +AFFILIATION_TEMPLATES += GeneralTemplate(
  15.      '(The Song of) Hell', (4, 5, 6)),
  16. -AFFLIATION_TEMPLATES += GeneralTemplate(
  17. +AFFILIATION_TEMPLATES += GeneralTemplate(
  18.      '(The Song of) The Light', (7, 8)),
  19. -AFFLIATION_TEMPLATES += GeneralTemplate(
  20. +AFFILIATION_TEMPLATES += GeneralTemplate(
  21.      '(The Song of) The Dark', (9, 10)),
  22. -AFFLIATION_TEMPLATES += GeneralTemplate(
  23. +AFFILIATION_TEMPLATES += GeneralTemplate(
  24.      '(The Song of) The Wild', (11, 12, 13)),
  25. -AFFLIATION_TEMPLATES += GeneralTemplate(
  26. +AFFILIATION_TEMPLATES += GeneralTemplate(
  27.      'An Independent Song', (14, 15, 16)),
  28.  
  29.  
  30. diff --git a/src/nobilis/lifepath.py b/src/nobilis/lifepath.py
  31. --- a/src/nobilis/lifepath.py
  32. +++ b/src/nobilis/lifepath.py
  33. @@ -12,6 +12,7 @@
  34.  
  35.  
  36.  def key(item):
  37. +    """Return a type-based key for the given item."""
  38.      return type(item), item
  39.  
  40.  
  41. @@ -19,6 +20,7 @@
  42.  # now. Basically, it needs to be used as a mixin AHEAD OF a namedtuple class
  43.  # with a first field of "hash".
  44.  class QuickHash:
  45. +    """Base class for namedtuples that store their hash in the first field."""
  46.  
  47.      __slots__ = ()
  48.  
  49. @@ -28,6 +30,7 @@
  50.  
  51.      @classmethod
  52.      def _pre_hash(cls, *args, **kwargs):
  53. +        """Return the hash the instance will use."""
  54.          args = tuple(args)
  55.          fields = getattr(cls, '_fields', ('hash',))[1:]
  56.          keywords = fields[len(args):]
  57. @@ -42,10 +45,12 @@
  58.  
  59.  
  60.  class Child(Business):
  61. +    """Purely structural child visitor."""
  62.  
  63.      __slots__ = ()
  64.  
  65.      def default_visit(self, node):
  66. +        """Yield zero times."""
  67.          yield from ()
  68.  
  69.  
  70. @@ -53,6 +58,7 @@
  71.  
  72.  
  73.  class Tree(QH, nt('Tree', 'hash root reverse_mapping')):
  74. +    """Purely structural tree structure, for determining parents."""
  75.  
  76.      __slots__ = ()
  77.  
  78. @@ -71,77 +77,64 @@
  79.          return super().__new__(cls, root, mapping.Map(reverse_mapping))
  80.  
  81.      def parent(self, node):
  82. +        """Return the parent of the given node."""
  83.          return self.reverse_mapping.get(key(node))
  84.  
  85.  
  86.  @Business.mark
  87.  class Choice(QH, nt('Choice', 'hash template')):
  88. -
  89. -    __slots__ = ()
  90. -
  91. -
  92. -class ChoiceDisplay(QH, nt('ChoiceDisplay', 'hash choice')):
  93. +    """An underlying choice for tracking state."""
  94.  
  95.      __slots__ = ()
  96.  
  97.  
  98. +# First to test in rewrite.
  99.  @Business.mark
  100. -class ChoiceTaken(QH, nt('ChoiceTaken', 'hash choice')):
  101. +class Tab(QH, nt('Tab', 'hash name node')):
  102.  
  103.      __slots__ = ()
  104.  
  105.  
  106. -class ChoiceListed(QH, nt('ChoiceListed', 'hash choice')):
  107. -
  108. -    __slots__ = ()
  109. -
  110. -
  111. +# First to test in rewrite.
  112.  @Business.mark
  113. -class ChoiceList(QH, nt('ChoiceList', 'hash choices initial_min initial_max')):
  114. -
  115. -    __slots__ = ()
  116. -
  117. -
  118. -class DisplayList(QH, nt('DisplayList', 'hash factory choices_ sections_')):
  119. +class TabList(QH, nt('TabList', 'hash tabs')):
  120.  
  121.      __slots__ = ()
  122.  
  123.      @property
  124. -    def choices(self):
  125. -        return map_tuple.MapTuple(self.factory, self.choices_)
  126. -
  127. -    @property
  128. -    def sections(self):
  129. -        return map_tuple.MapTuple(
  130. -            functools.partial(Section, self), range(len(self.sections_)))
  131. +    def enumerated_names(self):
  132. +        return tuple(enumerate(tab.name for tab in self.tabs))
  133.  
  134.  
  135. +# Second to test in rewrite, may need rename.
  136.  @Business.mark
  137. -class Section(QH, nt('Section', 'hash display_list index')):
  138. +class Table(QH, nt('Table', 'hash heading node')):
  139. +
  140. +    __slots__ = ()
  141. +
  142. +
  143. +# Second to test in rewrite, may need rename.
  144. +class TableList(QH, nt('TableList', 'hash items')):
  145.  
  146.      __slots__ = ()
  147.  
  148. -    @property
  149. -    def _data(self):
  150. -        return self.display_list.sections_[self.index]
  151.  
  152. -    @property
  153. -    def name(self):
  154. -        return self._data[0]
  155. -
  156. -    @property
  157. -    def predicate(self):
  158. -        return self._data[1]
  159. +def Child(self, node, next_visitor):
  160. +    yield node.node
  161.  
  162.  
  163. [email protected](ChoiceList)
  164.  def Child(self, node, next_visitor):
  165. -    yield from node.choices
  166. +    yield from node.tabs
  167.  
  168.  
  169. [email protected](DisplayList)
  170.  def Child(self, node, next_visitor):
  171. -    yield from node.choices
  172. +    yield node.node
  173. +
  174. +
  175. +def Child(self, node, next_visitor):
  176. +    yield from node.items
  177. diff --git a/tests/nobilis/test_lifepath.py b/tests/nobilis/test_lifepath.py
  178. --- a/tests/nobilis/test_lifepath.py
  179. +++ b/tests/nobilis/test_lifepath.py
  180. @@ -7,7 +7,7 @@
  181.  
  182.  def test_key(lifepath):
  183.      assert lifepath.key(lifepath.Choice(None)) != lifepath.key(
  184. -        lifepath.ChoiceDisplay(None))
  185. +        lifepath.TabList(None))
  186.  
  187.  
  188.  def test_hash_amortization(lifepath):
  189. @@ -61,55 +61,133 @@
  190.  def test_children(lifepath):
  191.      child = lifepath.Child()
  192.  
  193. -    leaf = lifepath.Choice(None)
  194. +    tab = lifepath.Tab('name', None)
  195.  
  196. -    assert tuple(child.visit(leaf)) == ()
  197. +    tab_list = lifepath.TabList((tab,))
  198. +
  199. +    assert tuple(child.visit(tab_list)) == (tab,)
  200. +    assert tuple(child.visit(tab)) == (None,)
  201.  
  202. -    for wrapper in (lifepath.ChoiceDisplay, lifepath.ChoiceTaken,
  203. -                    lifepath.ChoiceListed):
  204. -        assert tuple(child.visit(wrapper(leaf))) == ()
  205. +    item = lifepath.Table('heading', None)
  206.  
  207. -    assert tuple(child.visit(lifepath.ChoiceList((leaf,), 0, None))) == (leaf,)
  208. +    item_list = lifepath.TableList((item,))
  209.  
  210. -    display_list = lifepath.DisplayList(
  211. -        lifepath.ChoiceDisplay, (leaf,), (('name', None),))
  212. -
  213. -    assert tuple(child.visit(display_list)) == (lifepath.ChoiceDisplay(leaf),)
  214. +    assert tuple(child.visit(item_list)) == (item,)
  215. +    assert tuple(child.visit(item)) == (None,)
  216.  
  217.  
  218.  def test_tree(lifepath):
  219. -    leaf = lifepath.Choice(None)
  220. -    root = lifepath.ChoiceList((leaf,), 0, None)
  221. +    leaf = lifepath.Tab('test1', None)
  222. +    root = lifepath.TabList((leaf,))
  223.      tree = lifepath.Tree(root)
  224.      assert tree.parent(leaf) == root
  225.  
  226. -    rooter = lifepath.ChoiceList((root,), 0, None)
  227. +    rooter = lifepath.TabList((root,))
  228.  
  229.      treeer = lifepath.Tree(rooter)
  230.      assert treeer.parent(root) == rooter
  231.      assert treeer.parent(leaf) == root
  232.  
  233. -    dag = lifepath.ChoiceList((leaf, leaf), 0, None)
  234. +    dag = lifepath.TabList((leaf, leaf))
  235.  
  236.      with pytest.raises(ValueError):
  237.          print(lifepath.Tree(dag))
  238.  
  239.  
  240. -def test_section(lifepath):
  241. -    leaf = lifepath.Choice(None)
  242. -    sentinel = object()
  243. -
  244. -    display_list = lifepath.DisplayList(
  245. -        lifepath.ChoiceDisplay, (leaf,), (('name', sentinel),))
  246. -
  247. -    section, = display_list.sections
  248. -
  249. -    assert section.name == 'name'
  250. -    assert section.predicate is sentinel
  251. -
  252. -
  253.  def test_state(lifepath):
  254.      # Okay, so, let's think how this has to go.
  255.      # Ideally, I wouldn't be relying on mutable state, so...
  256.      # state = lifepath.State()
  257.      pass
  258. +
  259. +
  260. +# Okay, let's start over. At the current way of thinking of things, a character
  261. +# sheet is going to have multiple tabs.
  262. +
  263. +def test_power_tabs(lifepath):
  264. +    placeholder = object()
  265. +
  266. +    # Must be selected before the others.
  267. +    key_tab = lifepath.Tab('Keys', placeholder)
  268. +    # No additional dependencies.
  269. +    foundation_tab = lifepath.Tab('Foundation', placeholder)
  270. +    # No additional dependencies.
  271. +    estate_tab = lifepath.Tab('Estate', placeholder)
  272. +    # Internal dependencies.
  273. +    origins_tab = lifepath.Tab('Origins', placeholder)
  274. +    # Some interaction with Origins.
  275. +    contacts_tab = lifepath.Tab('Contacts', placeholder)
  276. +    # No additional dependencies.
  277. +    affiliation_tab = lifepath.Tab('Affiliation', placeholder)
  278. +    # No additional dependencies.
  279. +    background_tab = lifepath.Tab('Background', placeholder)
  280. +
  281. +    tab_list = lifepath.TabList((
  282. +        key_tab,
  283. +        foundation_tab,
  284. +        estate_tab,
  285. +        origins_tab,
  286. +        contacts_tab,
  287. +        affiliation_tab,
  288. +        background_tab))
  289. +
  290. +    # Now that we have the tab_list, we need to reason about it...
  291. +    # Would be good to get an enumerated list of names.
  292. +
  293. +    assert tab_list.enumerated_names == (
  294. +        (0, 'Keys'),
  295. +        (1, 'Foundation'),
  296. +        (2, 'Estate'),
  297. +        (3, 'Origins'),
  298. +        (4, 'Contacts'),
  299. +        (5, 'Affiliation'),
  300. +        (6, 'Background'),)
  301. +
  302. +
  303. +# Actually, what if I do both kinds of character sheet?
  304. +
  305. +def test_deceiver_tabs(lifepath):
  306. +    placeholder = object()
  307. +
  308. +    # Must be selected before the others.
  309. +    key_tab = lifepath.Tab('Keys', placeholder)
  310. +    # The Foundation tab seems the most mix-and-matchable.
  311. +    # No additional dependencies.
  312. +    foundation_tab = lifepath.Tab('Foundation', placeholder)
  313. +    # No additional dependencies.
  314. +    p_state_tab = lifepath.Tab('pState', placeholder)
  315. +    # No internal dependencies.
  316. +    breakthrough_tab = lifepath.Tab('Breakthrough', placeholder)
  317. +    # May end up with 2 plan tabs
  318. +    # No internal dependencies.
  319. +    plans_tab = lifepath.Tab('Plans', placeholder)
  320. +    # Contacts divided into typical and rare, both sorted, which implies some
  321. +    # way of marking them outside of a section label.
  322. +    # Of note: no dependency on other sections. Just pick "up to three"
  323. +    # Not sure if that REQUIRES at least 1, it's probably a good idea though.
  324. +    # No internal dependencies.
  325. +    contacts_tab = lifepath.Tab('Contacts', placeholder)
  326. +    # No internal dependencies.
  327. +    justification_tab = lifepath.Tab('Justification', placeholder)
  328. +    # No internal dependencies.
  329. +    territory_tab = lifepath.Tab('Territory', placeholder)
  330. +
  331. +    tab_list = lifepath.TabList((
  332. +        key_tab,
  333. +        foundation_tab,
  334. +        p_state_tab,
  335. +        breakthrough_tab,
  336. +        plans_tab,
  337. +        contacts_tab,
  338. +        justification_tab,
  339. +        territory_tab))
  340. +
  341. +    assert tab_list.enumerated_names == (
  342. +        (0, 'Keys'),
  343. +        (1, 'Foundation'),
  344. +        (2, 'pState'),
  345. +        (3, 'Breakthrough'),
  346. +        (4, 'Plans'),
  347. +        (5, 'Contacts'),
  348. +        (6, 'Justification'),
  349. +        (7, 'Territory'),)
Advertisement
Add Comment
Please, Sign In to add comment