Maplestory M: A program to simulate star force enhancements

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}')

Leave a comment

Design a site like this with WordPress.com
Get started