Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import collections
- import random
- class Card(collections.namedtuple('Card', ['name', 'type', 'money', 'cards'])):
- __slots__ = ()
- def __str__(self):
- return self.name
- TREASURE = 0
- ACTION = 1
- VICTORY = 2
- COPPER = Card(name='Copper', type=TREASURE, money=1, cards=0)
- ESTATE = Card(name='Estate', type=VICTORY, money=0, cards=0)
- SILVER = Card(name='Silver', type=TREASURE, money=2, cards=0)
- # TODO: account for terminal collisions. Not needed for Plan, hopefully
- TERM_SILVER = Card(name='TermSilver', type=ACTION, money=2, cards=0)
- TERM_COPPER = Card(name='TermCopper', type=ACTION, money=1, cards=0)
- TERM_NOTHING = Card(name='TermNothing', type=ACTION, money=0, cards=0)
- CANTRIP = Card(name='Cantrip', type=ACTION, money=0, cards=1)
- CANTRIP_COPPER = Card(name='Cantrip', type=ACTION, money=1, cards=1)
- SMITHY = Card(name='Smithy', type=ACTION, money=0, cards=3)
- TWO_CARDS = Card(name='TwoCards', type=ACTION, money=0, cards=2)
- def draw(deck, discard, debug=False):
- if len(deck) == 0:
- if debug:
- print 'Reshuffle, deck size is %d' % len(discard)
- deck.extend(discard)
- discard[:] = []
- c = random.choice(deck)
- deck.remove(c)
- return c
- def play(deck):
- # Plays 2 hands from deck, stores money distribution (over pairs)
- # Ignores turn 5 because it's harder to reason about
- deck = list(deck) # Make copy
- moneys = []
- discard = []
- in_play = []
- for _ in range(2):
- # Start hand
- cards = [draw(deck, discard) for _ in range(5)]
- # Play actions if they exist
- actions = [c for c in cards if c.type == ACTION]
- while len(actions) > 0:
- card = actions[0]
- actions = actions[1:]
- cards.remove(card)
- in_play.append(card)
- for _ in range(card.cards):
- cards.append(draw(deck, discard))
- # Play remaining treasures
- moneys.append(sum(c.money for c in cards) + sum(c.money for c in in_play))
- # Move to discard
- discard.extend(cards)
- discard.extend(in_play)
- in_play[:] = []
- return moneys
- def distribution(deck):
- TRIALS = 10 ** 5
- values = [play(deck) for _ in xrange(TRIALS)]
- values = [tuple(sorted(v)) for v in values]
- t34 = collections.Counter(values)
- for k in t34:
- t34[k] /= float(TRIALS)
- # Print BB code
- print '[table]'
- print '[tr][td][b]Money on turns 3/4[/b][/td][td][b]Probability[/b][/td][/tr]'
- for k, v in sorted(t34.iteritems()):
- print '[tr][td]%d/%d[/td][td]%.2f%%[/td][/tr]' % (k[0], k[1], 100 * v)
- print '[/table]'
- zero5 = 0
- for k, v in t34.iteritems():
- if k[0] < 5 and k[1] < 5:
- zero5 += v
- print '\n[b]Hit exactly 0 $5+ hands: %.2f%%[/b]' % (zero5 * 100)
- one5 = 0
- for k, v in t34.iteritems():
- if k[0] < 5 and k[1] >= 5:
- one5 += v
- print '[b]Hit exactly 1 $5+ hand: %.2f%%[/b]' % (one5 * 100)
- two5 = 0
- for k, v in t34.iteritems():
- if k[0] >= 5 and k[1] >= 5:
- two5 += v
- print '[b]Hit exactly 2 $5+ hands: %.2f%%[/b]\n' % (two5 * 100)
- zero4 = 0
- for k, v in t34.iteritems():
- if k[0] < 4 and k[1] < 4:
- zero4 += v
- print '[b]Hit exactly 0 $4+ hands: %.2f%%[/b]' % (zero4 * 100)
- one4 = 0
- for k, v in t34.iteritems():
- if k[0] < 4 and k[1] >= 4:
- one4 += v
- print '[b]Hit exactly 1 $4+ hand: %.2f%%[/b]' % (one4 * 100)
- two4 = 0
- for k, v in t34.iteritems():
- if k[0] >= 4 and k[1] >= 4:
- two4 += v
- print '[b]Hit exactly 2 $4+ hands: %.2f%%[/b]' % (two4 * 100)
- print '\n'
- DEFAULT = [COPPER] * 7 + [ESTATE] * 3
- TWO_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [SILVER] * 2
- TERM_SILVER_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TERM_SILVER]
- CANTRIP_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [CANTRIP, SILVER]
- CANTRIP_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [CANTRIP]
- TERM_COPPER_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [TERM_COPPER, SILVER]
- TERM_COPPER_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TERM_COPPER]
- TERM_NOTHING_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [TERM_NOTHING, SILVER]
- TERM_NOTHING_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TERM_NOTHING]
- CANTRIP_COPPER_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [CANTRIP_COPPER, SILVER]
- CANTRIP_COPPER_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [CANTRIP_COPPER]
- SMITHY_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [SMITHY, SILVER]
- SMITHY_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [SMITHY]
- TWOCARDS_SILVER = [COPPER] * 7 + [ESTATE] * 3 + [TWO_CARDS, SILVER]
- TWOCARDS_PLAN = [COPPER] * 7 + [ESTATE] * 2 + [TWO_CARDS]
- print '[table][tr][td]'
- print '[b]Silver + Terminal Silver[/b]'
- distribution(TWO_SILVER)
- print '[/td][td]'
- print '[b]Plan + Terminal Silver[/b]'
- distribution(TERM_SILVER_PLAN)
- print '[/td][/tr][/table]'
- print '[table][tr][td]'
- print '[b]Silver + Terminal Copper[/b]'
- distribution(TERM_COPPER_SILVER)
- print '[/td][td]'
- print '[b]Plan + Terminal Copper[/b]'
- distribution(TERM_COPPER_PLAN)
- print '[/td][/tr][/table]'
- print '[table][tr][td]'
- print '[b]Silver + Terminal Giving $0[/b]'
- distribution(TERM_NOTHING_SILVER)
- print '[/td][td]'
- print '[b]Plan + Terminal Giving $0[/b]'
- distribution(TERM_NOTHING_PLAN)
- print '[/td][/tr][/table]'
- print '[table][tr][td]'
- print '[b]Silver + Poacher[/b]'
- distribution(CANTRIP_COPPER_SILVER)
- print '[/td][td]'
- print '[b]Plan + Poacher[/b]'
- distribution(CANTRIP_COPPER_PLAN)
- print '[/td][/tr][/table]'
- print '[table][tr][td]'
- print '[b]Silver + Smithy[/b]'
- distribution(SMITHY_SILVER)
- print '[/td][td]'
- print '[b]Plan + Smithy[/b]'
- distribution(SMITHY_PLAN)
- print '[/td][/tr][/table]'
- print '[table][tr][td]'
- print '[b]Silver + Terminal Giving +2 Cards[/b]'
- distribution(TWOCARDS_SILVER)
- print '[/td][td]'
- print '[b]Plan + Terminal Giving +2 Cards[/b]'
- distribution(TWOCARDS_PLAN)
- print '[/td][/tr][/table]'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement