[quote=Guy Scrum][quote=Dr. Hieronymous Alloy]…but I’d be really interested to see if anyone’s done the math.
[/quote]
So I just finished a big project for work, and clearly needed more nerdy math things to do. This time, let’s do a Monte Carlo simulation. I wrote a short program to simulate someone trying to pass at different levels of making waves. Assuming you can get 2 CP of making waves per action and you need 40 levels of making waves to get 100%, I come up with the following:
[li] Attempting with 15 making waves (assuming you have to get at least this high to force a draw), you should expect to spend about 149 actions. There’s about a 25% chance you’ll spend 200+ actions, and 2.5% chance you’ll spend 400+ actions.
[/li][li] Attempting with higher making waves generally takes more actions.
[/li][li] Attempting with 40 making waves takes 417 actions (using my probably wrong assumptions).
The program is in the spoiler tag. Run it in a python terminal if you want to play with it.
from random import random
def actionsForSuccess(attemptLevel = 40, challengeLevel = 40, CPperAction = 2.0, drawCPpenalty = 10):
~~~~Uses a RNG to figure out how many actions it will take to gain a point of notability.
~~~~challengeLevel - the level you need to get 100% success rate
~~~~CPperAction - how many actions it takes to get 1 CP of making waves
~~~~attemptLevel - the level at which you take a gamble
~~~~drawCPpenalty - how many CP you lose to force draw the card
~~~~Number of actions it took to gain the point.
~~~~"""
~~~~actions = 0
~~~~CP = 0
~~~~attemptCP = attemptLevel*(attemptLevel+1)/2
~~~~while True:
~~~~~~~~delta_CP = attemptCP + drawCPpenalty - CP
~~~~~~~~actions += delta_CP / CPperAction
~~~~~~~~actions += 2 # one for draw, one for trying to pass
~~~~~~~~success_probability = attemptLevel * 1.0 / challengeLevel
~~~~~~~~if (success_probability > random()):
~~~~~~~~~~~~# success!
~~~~~~~~~~~~return actions
~~~~~~~~else:
~~~~~~~~~~~~# fail...
~~~~~~~~~~~~# Assume your making waves level gets cut in half, rounded up
~~~~~~~~~~~~newLevel = attemptLevel//2 + attemptLevel%2
~~~~~~~~~~~~CP = newLevel*(newLevel+1)/2
# Now run this a bunch of times, and see what the distribution is
def runManyTimes(n = 10**6, **args):
~~~~action_distribution = {}
~~~~for i in xrange(n):
~~~~~~~~actionsForThisTrial = actionsForSuccess(**args)
~~~~~~~~if actionsForThisTrial not in action_distribution:
~~~~~~~~~~~~action_distribution[actionsForThisTrial] = 0.0
~~~~~~~~action_distribution[actionsForThisTrial] += 1./n
~~~~
~~~~expectedActions = 0
~~~~for actionCount in action_distribution.keys():
~~~~~~~~expectedActions += actionCount * action_distribution[actionCount]
~~~~return expectedActions, action_distribution
expectedActions, action_distribution = runManyTimes(attemptLevel = 15)
print expectedActions
print action_distribution
edit: Evidently I can’t post things with leading spaces. Remove the tildes and put in spaces if you want to run the code.[/li]
edited by Guy Scrum on 12/5/2013[/quote]
[li]
Thanks! This is exactly the sort of thing I was wondering about. Here’s a follow-up question:
How does all this math change if you’re using the Life of the Mind options to grind MW (and thus also have to periodically grind Society connections each time you leave court to summon the Amanuensis) vs. using social options and being able to grind straight through?