Read the main article here.
This program was written for python3.6 and above. For compatibility with older versions of python3, simply replace the fstrings in the last line with str.format, or an equivalent.
from random import random
ENHANCE_SUCCESS = 1
ENHANCE_MAINTAIN = 2
ENHANCE_DEGRADE = 3
ENHANCE_DESTROYED = 4
COST_TABLE = {
1: 10_000, 2: 15_000, 3: 20_000, 4: 55_000, 5: 100_000,
6: 200_000, 7: 300_000, 8: 400_000, 9: 600_000, 10: 800_000,
11: 1_000_000, 12: 1_400_000, 13: 1_800_000, 14: 2_200_000, 15: 2_600_000,
16: 3_000_000, 17: 3_500_000, 18: 4_000_000, 19: 4_500_000, 20: 5_000_000,
21: 6_000_000, 22: 7_000_000, 23: 8_000_000, 24: 9_000_000, 25: 10_000_000,
26: 11_800_000, 27: 14_900_000, 28: 18_000_000, 29: 21_100_000, 30: 24_200_000
}
PROBS = { # (success, maintain, degraded, destroyed)
1: ( 1, 0, 0, 0), 2: (.95, .05, 0, 0), 3: (.90, .10, 0, 0),
4: (.85, .15, 0, 0), 5: (.80, .20, 0, 0), 6: (.75, .25, 0, 0),
7: (.70, .30, 0, 0), 8: (.65, .35, 0, 0), 9: (.60, .40, 0, 0),
10: (.55, .45, 0, 0), 11: (.50, .35, .10, .05), 12: (.45, .40, .10, .05),
13: (.40, .40, .15, .05), 14: (.35, .45, .15, .05), 15: (.30, .45, .20, .05),
16: (.25, .50, .20, .05), 17: (.20, .50, .25, .05), 18: (.15, .55, .25, .05),
19: (.10, .55, .30, .05), 20: (.05, .60, .30, .05), 21: (.01, .49, .40, .10),
22: (.01, .49, .40, .10), 23: (.01, .49, .40, .10), 24: (.01, .49, .40, .10),
25: (.01, .49, .40, .10), 26: (.01, .39, .45, .15), 27: (.01, .39, .45, .15),
28: (.01, .39, .45, .15), 29: (.01, .39, .45, .15), 30: (.01, .39, .45, .15)
}
assert all([sum(p) == 1 for p in PROBS.values()])
def simulate(n, target_SF):
results = [enhance_cost(target_SF) for _ in range(n)]
return (
sum(map(lambda x: x[0], results))/n,
sum(map(lambda x: x[1], results))/n
)
def enhance_cost(until_SF):
cost_so_far = [1, 0] # [num equipment, meso cost]
current_SF = 0
while current_SF < until_SF:
cost_so_far[1] += COST_TABLE[current_SF+1]
outcome = random_enhance_outcome(current_SF+1)
if outcome == ENHANCE_SUCCESS:
current_SF += 1
elif outcome == ENHANCE_MAINTAIN:
continue
elif outcome == ENHANCE_DEGRADE:
current_SF -= 1
elif outcome == ENHANCE_DESTROYED:
cost_so_far[0] += 1
return cost_so_far
def random_enhance_outcome(target_SF):
roll = random()
probs = PROBS[target_SF]
if roll < probs[0]:
return ENHANCE_SUCCESS
elif probs[0] <= roll < sum(probs[0:2]):
return ENHANCE_MAINTAIN
elif sum(probs[0:2]) <= roll < sum(probs[0:3]):
return ENHANCE_DEGRADE
else:
return ENHANCE_DESTROYED
for i in range(1, 31):
n = 100_000
costs = simulate(n, i)
print(f'Average {costs[1]} mesos & {costs[0]} equipment are required to get SF{i}')