Guest User

Untitled

a guest
Sep 14th, 2018
12
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import collections
  2. import random
  3.  
  4. class Card(collections.namedtuple('Card', ['name', 'type', 'money', 'cards'])):
  5.     __slots__ = ()
  6.     def __str__(self):
  7.         return self.name
  8.  
  9. TREASURE = 0
  10. ACTION = 1
  11. VICTORY = 2
  12.  
  13. COPPER = Card(name='Copper', type=TREASURE, money=1, cards=0)
  14. ESTATE = Card(name='Estate', type=VICTORY, money=0, cards=0)
  15. SILVER = Card(name='Silver', type=TREASURE, money=2, cards=0)
  16. # TODO: account for terminal collisions. Not needed for Plan, hopefully
  17. TERM_SILVER = Card(name='TermSilver', type=ACTION, money=2, cards=0)
  18. TERM_COPPER = Card(name='TermCopper', type=ACTION, money=1, cards=0)
  19. TERM_NOTHING = Card(name='TermNothing', type=ACTION, money=0, cards=0)
  20. CANTRIP = Card(name='Cantrip', type=ACTION, money=0, cards=1)
  21. CANTRIP_COPPER = Card(name='Cantrip', type=ACTION, money=1, cards=1)
  22. SMITHY = Card(name='Smithy', type=ACTION, money=0, cards=3)
  23. TWO_CARDS = Card(name='TwoCards', type=ACTION, money=0, cards=2)
  24.  
  25.  
  26. def draw(deck, discard, debug=False):
  27.     if len(deck) == 0:
  28.         if debug:
  29.             print 'Reshuffle, deck size is %d' % len(discard)
  30.         deck.extend(discard)
  31.         discard[:] = []
  32.     c = random.choice(deck)
  33.     deck.remove(c)
  34.     return c
  35.  
  36.  
  37. def play(deck):
  38.     # Plays 2 hands from deck, stores money distribution (over pairs)
  39.     # Ignores turn 5 because it's harder to reason about
  40.     deck = list(deck)  # Make copy
  41.     moneys = []
  42.     discard = []
  43.     in_play = []
  44.     for _ in range(2):
  45.         # Start hand
  46.         cards = [draw(deck, discard) for _ in range(5)]
  47.         # Play actions if they exist
  48.         actions = [c for c in cards if c.type == ACTION]
  49.         while len(actions) > 0:
  50.             card = actions[0]
  51.             actions = actions[1:]
  52.             cards.remove(card)
  53.             in_play.append(card)
  54.             for _ in range(card.cards):
  55.                 cards.append(draw(deck, discard))
  56.         # Play remaining treasures
  57.         moneys.append(sum(c.money for c in cards) + sum(c.money for c in in_play))
  58.         # Move to discard
  59.         discard.extend(cards)
  60.         discard.extend(in_play)
  61.         in_play[:] = []
  62.     return moneys
  63.  
  64.  
  65. def distribution(deck):
  66.     TRIALS = 10 ** 5
  67.     values = [play(deck) for _ in xrange(TRIALS)]
  68.     values = [tuple(sorted(v)) for v in values]
  69.     t34 = collections.Counter(values)
  70.     for k in t34:
  71.         t34[k] /= float(TRIALS)
  72.     # Print BB code
  73.     print '[table]'
  74.     print '[tr][td][b]Money on turns 3/4[/b][/td][td][b]Probability[/b][/td][/tr]'
  75.     for k, v in sorted(t34.iteritems()):
  76.         print '[tr][td]%d/%d[/td][td]%.2f%%[/td][/tr]' % (k[0], k[1], 100 * v)
  77.     print '[/table]'
  78.  
  79.     zero5 = 0
  80.     for k, v in t34.iteritems():
  81.         if k[0] < 5 and k[1] < 5:
  82.             zero5 += v
  83.     print '\n[b]Hit exactly 0 $5+ hands: %.2f%%[/b]' % (zero5 * 100)
  84.  
  85.     one5 = 0
  86.     for k, v in t34.iteritems():
  87.         if k[0] < 5 and k[1] >= 5:
  88.             one5 += v
  89.  
  90.     print '[b]Hit exactly 1 $5+ hand: %.2f%%[/b]' % (one5 * 100)
  91.     two5 = 0
  92.     for k, v in t34.iteritems():
  93.         if k[0] >= 5 and k[1] >= 5:
  94.             two5 += v
  95.  
  96.     print '[b]Hit exactly 2 $5+ hands: %.2f%%[/b]\n' % (two5 * 100)
  97.  
  98.     zero4 = 0
  99.     for k, v in t34.iteritems():
  100.         if k[0] < 4 and k[1] < 4:
  101.             zero4 += v
  102.     print '[b]Hit exactly 0 $4+ hands: %.2f%%[/b]' % (zero4 * 100)
  103.  
  104.     one4 = 0
  105.     for k, v in t34.iteritems():
  106.         if k[0] < 4 and k[1] >= 4:
  107.             one4 += v
  108.  
  109.     print '[b]Hit exactly 1 $4+ hand: %.2f%%[/b]' % (one4 * 100)
  110.     two4 = 0
  111.     for k, v in t34.iteritems():
  112.         if k[0] >= 4 and k[1] >= 4:
  113.             two4 += v
  114.  
  115.     print '[b]Hit exactly 2 $4+ hands: %.2f%%[/b]' % (two4 * 100)
  116.     print '\n'
  117.  
  118.  
  119. DEFAULT = [COPPER] * 7 + [ESTATE] * 3
  120.  
  121. TWO_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [SILVER] * 2
  122. TERM_SILVER_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TERM_SILVER]
  123.  
  124. CANTRIP_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [CANTRIP, SILVER]
  125. CANTRIP_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [CANTRIP]
  126.  
  127. TERM_COPPER_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [TERM_COPPER, SILVER]
  128. TERM_COPPER_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TERM_COPPER]
  129.  
  130. TERM_NOTHING_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [TERM_NOTHING, SILVER]
  131. TERM_NOTHING_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TERM_NOTHING]
  132.  
  133. CANTRIP_COPPER_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [CANTRIP_COPPER, SILVER]
  134. CANTRIP_COPPER_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [CANTRIP_COPPER]
  135.  
  136. SMITHY_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [SMITHY, SILVER]
  137. SMITHY_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [SMITHY]
  138.  
  139. TWOCARDS_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [TWO_CARDS, SILVER]
  140. TWOCARDS_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TWO_CARDS]
  141.  
  142. print '[table][tr][td]'
  143. print '[b]Silver + Terminal Silver[/b]'
  144. distribution(TWO_SILVER)
  145.  
  146. print '[/td][td]'
  147. print '[b]Plan + Terminal Silver[/b]'
  148. distribution(TERM_SILVER_PLAN)
  149. print '[/td][/tr][/table]'
  150.  
  151. print '[table][tr][td]'
  152. print '[b]Silver + Terminal Copper[/b]'
  153. distribution(TERM_COPPER_SILVER)
  154.  
  155. print '[/td][td]'
  156. print '[b]Plan + Terminal Copper[/b]'
  157. distribution(TERM_COPPER_PLAN)
  158. print '[/td][/tr][/table]'
  159.  
  160. print '[table][tr][td]'
  161. print '[b]Silver + Terminal Giving $0[/b]'
  162. distribution(TERM_NOTHING_SILVER)
  163.  
  164. print '[/td][td]'
  165. print '[b]Plan + Terminal Giving $0[/b]'
  166. distribution(TERM_NOTHING_PLAN)
  167. print '[/td][/tr][/table]'
  168.  
  169. print '[table][tr][td]'
  170. print '[b]Silver + Poacher[/b]'
  171. distribution(CANTRIP_COPPER_SILVER)
  172.  
  173. print '[/td][td]'
  174. print '[b]Plan + Poacher[/b]'
  175. distribution(CANTRIP_COPPER_PLAN)
  176. print '[/td][/tr][/table]'
  177.  
  178. print '[table][tr][td]'
  179. print '[b]Silver + Smithy[/b]'
  180. distribution(SMITHY_SILVER)
  181.  
  182. print '[/td][td]'
  183. print '[b]Plan + Smithy[/b]'
  184. distribution(SMITHY_PLAN)
  185. print '[/td][/tr][/table]'
  186.  
  187. print '[table][tr][td]'
  188. print '[b]Silver + Terminal Giving +2 Cards[/b]'
  189. distribution(TWOCARDS_SILVER)
  190.  
  191. print '[/td][td]'
  192. print '[b]Plan + Terminal Giving +2 Cards[/b]'
  193. distribution(TWOCARDS_PLAN)
  194. print '[/td][/tr][/table]'
RAW Paste Data