Advertisement
mwchase

LC:Nobilis Update 6: diff

Jun 19th, 2017
169
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. -@Business.mark
  93. -class ChoiceDisplay(QH, nt('ChoiceDisplay', 'hash choice')):
  94. +    """An underlying choice for tracking state."""
  95.  
  96.      __slots__ = ()
  97.  
  98.  
  99. +# First to test in rewrite.
  100.  @Business.mark
  101. -class ChoiceTaken(QH, nt('ChoiceTaken', 'hash choice')):
  102. +class Tab(QH, nt('Tab', 'hash name node')):
  103.  
  104.      __slots__ = ()
  105.  
  106.  
  107. -@Business.mark
  108. -class ChoiceListed(QH, nt('ChoiceListed', 'hash choice')):
  109. -
  110. -    __slots__ = ()
  111. -
  112. -
  113. +# First to test in rewrite.
  114.  @Business.mark
  115. -class ChoiceList(QH, nt('ChoiceList', 'hash choices initial_min initial_max')):
  116. -
  117. -    __slots__ = ()
  118. -
  119. -
  120. -@Business.mark
  121. -class DisplayList(QH, nt('DisplayList', 'hash factory choices_ sections_')):
  122. +class TabList(QH, nt('TabList', 'hash tabs')):
  123.  
  124.      __slots__ = ()
  125.  
  126.      @property
  127. -    def choices(self):
  128. -        return map_tuple.MapTuple(self.factory, self.choices_)
  129. -
  130. -    @property
  131. -    def sections(self):
  132. -        return map_tuple.MapTuple(
  133. -            functools.partial(Section, self), range(len(self.sections_)))
  134. +    def enumerated_names(self):
  135. +        return tuple(enumerate(tab.name for tab in self.tabs))
  136.  
  137.  
  138. +# Second to test in rewrite, may need rename.
  139.  @Business.mark
  140. -class Section(QH, nt('Section', 'hash display_list index')):
  141. +class Table(QH, nt('Table', 'hash heading node')):
  142. +
  143. +    __slots__ = ()
  144. +
  145. +
  146. +# Second to test in rewrite, may need rename.
  147. +@Business.mark
  148. +class TableList(QH, nt('TableList', 'hash items')):
  149.  
  150.      __slots__ = ()
  151.  
  152. -    @property
  153. -    def _data(self):
  154. -        return self.display_list.sections_[self.index]
  155.  
  156. -    @property
  157. -    def name(self):
  158. -        return self._data[0]
  159. -
  160. -    @property
  161. -    def predicate(self):
  162. -        return self._data[1]
  163. +@Child.bind(Tab)
  164. +def Child(self, node, next_visitor):
  165. +    yield node.node
  166.  
  167.  
  168. -@Child.bind(ChoiceList)
  169. +@Child.bind(TabList)
  170.  def Child(self, node, next_visitor):
  171. -    yield from node.choices
  172. +    yield from node.tabs
  173.  
  174.  
  175. -@Child.bind(DisplayList)
  176. +@Child.bind(Table)
  177.  def Child(self, node, next_visitor):
  178. -    yield from node.choices
  179. +    yield node.node
  180. +
  181. +
  182. +@Child.bind(TableList)
  183. +def Child(self, node, next_visitor):
  184. +    yield from node.items
  185. diff --git a/tests/nobilis/test_lifepath.py b/tests/nobilis/test_lifepath.py
  186. --- a/tests/nobilis/test_lifepath.py
  187. +++ b/tests/nobilis/test_lifepath.py
  188. @@ -7,7 +7,7 @@
  189.  
  190.  def test_key(lifepath):
  191.      assert lifepath.key(lifepath.Choice(None)) != lifepath.key(
  192. -        lifepath.ChoiceDisplay(None))
  193. +        lifepath.TabList(None))
  194.  
  195.  
  196.  def test_hash_amortization(lifepath):
  197. @@ -61,55 +61,133 @@
  198.  def test_children(lifepath):
  199.      child = lifepath.Child()
  200.  
  201. -    leaf = lifepath.Choice(None)
  202. +    tab = lifepath.Tab('name', None)
  203.  
  204. -    assert tuple(child.visit(leaf)) == ()
  205. +    tab_list = lifepath.TabList((tab,))
  206. +
  207. +    assert tuple(child.visit(tab_list)) == (tab,)
  208. +    assert tuple(child.visit(tab)) == (None,)
  209.  
  210. -    for wrapper in (lifepath.ChoiceDisplay, lifepath.ChoiceTaken,
  211. -                    lifepath.ChoiceListed):
  212. -        assert tuple(child.visit(wrapper(leaf))) == ()
  213. +    item = lifepath.Table('heading', None)
  214.  
  215. -    assert tuple(child.visit(lifepath.ChoiceList((leaf,), 0, None))) == (leaf,)
  216. +    item_list = lifepath.TableList((item,))
  217.  
  218. -    display_list = lifepath.DisplayList(
  219. -        lifepath.ChoiceDisplay, (leaf,), (('name', None),))
  220. -
  221. -    assert tuple(child.visit(display_list)) == (lifepath.ChoiceDisplay(leaf),)
  222. +    assert tuple(child.visit(item_list)) == (item,)
  223. +    assert tuple(child.visit(item)) == (None,)
  224.  
  225.  
  226.  def test_tree(lifepath):
  227. -    leaf = lifepath.Choice(None)
  228. -    root = lifepath.ChoiceList((leaf,), 0, None)
  229. +    leaf = lifepath.Tab('test1', None)
  230. +    root = lifepath.TabList((leaf,))
  231.      tree = lifepath.Tree(root)
  232.      assert tree.parent(leaf) == root
  233.  
  234. -    rooter = lifepath.ChoiceList((root,), 0, None)
  235. +    rooter = lifepath.TabList((root,))
  236.  
  237.      treeer = lifepath.Tree(rooter)
  238.      assert treeer.parent(root) == rooter
  239.      assert treeer.parent(leaf) == root
  240.  
  241. -    dag = lifepath.ChoiceList((leaf, leaf), 0, None)
  242. +    dag = lifepath.TabList((leaf, leaf))
  243.  
  244.      with pytest.raises(ValueError):
  245.          print(lifepath.Tree(dag))
  246.  
  247.  
  248. -def test_section(lifepath):
  249. -    leaf = lifepath.Choice(None)
  250. -    sentinel = object()
  251. -
  252. -    display_list = lifepath.DisplayList(
  253. -        lifepath.ChoiceDisplay, (leaf,), (('name', sentinel),))
  254. -
  255. -    section, = display_list.sections
  256. -
  257. -    assert section.name == 'name'
  258. -    assert section.predicate is sentinel
  259. -
  260. -
  261.  def test_state(lifepath):
  262.      # Okay, so, let's think how this has to go.
  263.      # Ideally, I wouldn't be relying on mutable state, so...
  264.      # state = lifepath.State()
  265.      pass
  266. +
  267. +
  268. +# Okay, let's start over. At the current way of thinking of things, a character
  269. +# sheet is going to have multiple tabs.
  270. +
  271. +def test_power_tabs(lifepath):
  272. +    placeholder = object()
  273. +
  274. +    # Must be selected before the others.
  275. +    key_tab = lifepath.Tab('Keys', placeholder)
  276. +    # No additional dependencies.
  277. +    foundation_tab = lifepath.Tab('Foundation', placeholder)
  278. +    # No additional dependencies.
  279. +    estate_tab = lifepath.Tab('Estate', placeholder)
  280. +    # Internal dependencies.
  281. +    origins_tab = lifepath.Tab('Origins', placeholder)
  282. +    # Some interaction with Origins.
  283. +    contacts_tab = lifepath.Tab('Contacts', placeholder)
  284. +    # No additional dependencies.
  285. +    affiliation_tab = lifepath.Tab('Affiliation', placeholder)
  286. +    # No additional dependencies.
  287. +    background_tab = lifepath.Tab('Background', placeholder)
  288. +
  289. +    tab_list = lifepath.TabList((
  290. +        key_tab,
  291. +        foundation_tab,
  292. +        estate_tab,
  293. +        origins_tab,
  294. +        contacts_tab,
  295. +        affiliation_tab,
  296. +        background_tab))
  297. +
  298. +    # Now that we have the tab_list, we need to reason about it...
  299. +    # Would be good to get an enumerated list of names.
  300. +
  301. +    assert tab_list.enumerated_names == (
  302. +        (0, 'Keys'),
  303. +        (1, 'Foundation'),
  304. +        (2, 'Estate'),
  305. +        (3, 'Origins'),
  306. +        (4, 'Contacts'),
  307. +        (5, 'Affiliation'),
  308. +        (6, 'Background'),)
  309. +
  310. +
  311. +# Actually, what if I do both kinds of character sheet?
  312. +
  313. +def test_deceiver_tabs(lifepath):
  314. +    placeholder = object()
  315. +
  316. +    # Must be selected before the others.
  317. +    key_tab = lifepath.Tab('Keys', placeholder)
  318. +    # The Foundation tab seems the most mix-and-matchable.
  319. +    # No additional dependencies.
  320. +    foundation_tab = lifepath.Tab('Foundation', placeholder)
  321. +    # No additional dependencies.
  322. +    p_state_tab = lifepath.Tab('pState', placeholder)
  323. +    # No internal dependencies.
  324. +    breakthrough_tab = lifepath.Tab('Breakthrough', placeholder)
  325. +    # May end up with 2 plan tabs
  326. +    # No internal dependencies.
  327. +    plans_tab = lifepath.Tab('Plans', placeholder)
  328. +    # Contacts divided into typical and rare, both sorted, which implies some
  329. +    # way of marking them outside of a section label.
  330. +    # Of note: no dependency on other sections. Just pick "up to three"
  331. +    # Not sure if that REQUIRES at least 1, it's probably a good idea though.
  332. +    # No internal dependencies.
  333. +    contacts_tab = lifepath.Tab('Contacts', placeholder)
  334. +    # No internal dependencies.
  335. +    justification_tab = lifepath.Tab('Justification', placeholder)
  336. +    # No internal dependencies.
  337. +    territory_tab = lifepath.Tab('Territory', placeholder)
  338. +
  339. +    tab_list = lifepath.TabList((
  340. +        key_tab,
  341. +        foundation_tab,
  342. +        p_state_tab,
  343. +        breakthrough_tab,
  344. +        plans_tab,
  345. +        contacts_tab,
  346. +        justification_tab,
  347. +        territory_tab))
  348. +
  349. +    assert tab_list.enumerated_names == (
  350. +        (0, 'Keys'),
  351. +        (1, 'Foundation'),
  352. +        (2, 'pState'),
  353. +        (3, 'Breakthrough'),
  354. +        (4, 'Plans'),
  355. +        (5, 'Contacts'),
  356. +        (6, 'Justification'),
  357. +        (7, 'Territory'),)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement