Talk:Basement Diving Guide
From A KoL Wiki
Code
For reasons of generality, the buff rate on the article is entirely arbitrary, and excludes equipment. That's unreasonable in practice, so here's some Python code that can calculate base stat/damage at given basement levels, as well as required main stat given a buff level that a player can maintain. It'll spit out two tables of tab-separated data, which should be able to be copy-pasted into any decent spreadsheet program. --Bagatelle 15:13, 12 November 2007 (CST)
################################################################################ # control outputs # interval between basement levels to output... # so 25 would output every 25th level BLStep = 25 # minimum level to output BLStart = 24 # maximum level to output, subject to BLStep and BLStart parameters # i.e., it is possible to output zero levels if these parameters # have strange values BLEnd = 500 # percentage to pad tests when calculating challenge numbers # 0 to suppress padding rows PadPct = 5 # for those who wish to display ONLY padded output for the damage/required # main stat tables, set this to "False" # so setting PadPct = 0 and PrintUnpadded = False will guarantee empty output PrintUnpadded = False # whether to print basement levels that are multiples of 5 # usually set to "False" because levels mod 5 are always rewards, so # no point in printing them # however, if BLStep, BLStart, BLEnd are set to output only multiples of 5, # the program will output an empty table Print5 = False ################################################################################ # character/buff configuration: used to calculate main stat required to # complete a dive # the script has no error-checking, so don't be a nut a say "True" to both # Seal Clubber/Turtle Tamer? MusChar = True # Pastamancer/Sauceror? MysChar = False # HP/MP percentage boosts: do you have these skills available? GnomishHardigness = False CosmicUgnderstanding = True WisdomOfTheElderTortoises = True SpiritOfRavioli = True # Outfit data: all outfits assume you are not suffering a # NET negative effect on stats # input total percentages for equipment/effects using "Pct" parameters # input total absolute modifiers for equipment/effects using "Abs" parameters # input the equipment/buffs you are willing to sustain for the entire dive # Muscle outfit MusPct = 900 MusAbs = 50 # Mysticality outfit MysPct = 900 MysAbs = 50 # Moxie outfit MoxPct = 900 MoxAbs = 50 # HP outfit: ignores DR, which is negligible at high BL HPMusPct = 800 HPMusAbs = 50 HPAbs = 0 HPDA = 1000 # MP outfit MPMysPct = 900 MPMysAbs = 50 MPAbs = 0 # Elemental resistance outfit: assumes outfit is the same for all elements EltMusPct = 900 EltMusAbs = 50 EltHPAbs = 0 EltPct = 60 # end configuration # do not edit anything below this line ################################################################################ from math import * # standardise percents into multiplier fractions MusFrac = 1 + MusPct / 100.0 MysFrac = 1 + MysPct / 100.0 MoxFrac = 1 + MoxPct / 100.0 DAFrac = 1 - (sqrt(HPDA / 10) - 1) / 10 EltFrac = 1 - EltPct / 100.0 EltMusFrac = 1 + EltMusPct / 100.0 HPMusFrac = 1 + HPMusPct / 100.0 MPMysFrac = 1 + MPMysPct / 100.0 PadFrac = 1 + PadPct / 100.0 # change passive "skills" into multipliers if MusChar: ClassHP = 1.5 else: ClassHP = 1.0 if MysChar: ClassMP = 1.5 else: ClassMP = 1.0 if WisdomOfTheElderTortoises: MPWisdom = 1.5 else: MPWisdom = 1.0 if CosmicUgnderstanding: MPCosmic = 1.05 else: MPCosmic = 1.0 if SpiritOfRavioli: HPSpirit = 1.25 else: HPSpirit = 1.0 if GnomishHardigness: HPHardiness = 1.05 else: HPHardiness = 1.0 # generate headers for list of basement data BL = dict( BL = "BL", Stat = "Stat", Elt = "Elt (2x)", Phys = "Phys", Drain = "Drain" ) Basement = [BL] # calculate challenge data for desired basement levels for Level in range(BLStart, BLEnd, BLStep): if Print5 or Level % 5 != 0: # format harddrive Basement.append(dict( BL = Level, Stat = Level**1.4 + 2, Elt = 4.48 * Level**1.4 + 8, Phys = 10 * Level**1.4, Drain = 1.67 * Level**1.4 )) # calculate chart of stat/damage done for common stat levels for Rec in range(0, len(Basement)): Level = Basement[Rec] if Rec == 0: # header row TestStrengths = [[ ["BL"], ["Stat"], ["Phys (0% DA)", "Phys (60% DA)", "Phys (90% DA)"], ["Drain"], ["Elt (0% Res)", "Elt (60% Res)", "Elt (80% Res)"] ]] else: # calculate unrounded numbers for common stat levels TempArray = [ [Level["BL"]], [Level["Stat"]], [Level["Phys"], 0.4 * Level["Phys"], 0.1 * Level["Phys"]], [Level["Drain"]], [Level["Elt"], 0.4 * Level["Elt"], 0.2 * Level["Elt"]] ] # unpadded data: round up if PrintUnpadded: TestStrengths.append( [[repr(TempArray[0])]] + \ [map(lambda x: int(ceil(x)), Arr) for Arr in TempArray[1:]] ) # padded numbers: pad, then round up if PadPct != 0: TestStrengths.append( [[repr(TempArray[0][0]) + " (" + repr(PadPct) + "% padding)"]] + \ [map(lambda x: int(ceil(PadFrac * x)), Arr) for Arr in TempArray[1:]] ) # calculate required main stat given sustained buffed main stat and # character configurations as defined by parameters for Rec in range(0, len(TestStrengths)): Level = TestStrengths[Rec] if Rec == 0: ReqStat = [["BL", "Mus", "Mys", "Mox", "Phys", "Drain", "Elt"]] else: # the HP/MP backsolve formulae are not exact, because ceiling() and floor() # do not have inverse functions # however, the large numbers involved and the understanding that there # is basement variation anyway makes this largely irrelevant # for each basement level with calculated data (including padded data, # if calculated), backsolve main stat for three stat tests, # HP/MP tests, and elemental test ReqStat.append( [Level[0][0]] + map(lambda x: int(ceil(x)), [ # Muscle (Level[1][0] - MusAbs) / MusFrac, # Mysticality (Level[1][0] - MysAbs) / MysFrac, # Moxie (Level[1][0] - MoxAbs) / MoxFrac, # HP ( (DAFrac * Level[2][0] / (HPHardiness * HPSpirit) - HPAbs) / ClassHP \ - 3 - HPMusAbs ) / HPMusFrac, # MP (Level[3][0] / (MPCosmic * MPWisdom) - MPMysAbs - MPAbs) / MPMysFrac, # Elemental ( (EltFrac * Level[4][0] / (HPHardiness * HPSpirit) - EltHPAbs) / \ ClassHP - 3 - EltMusAbs ) / EltMusFrac ]) ) # flatten list of lists into a single list def Flatten(Arg): Val = [] for Arr in Arg: if isinstance(Arr, str) or isinstance(Arr, int): Val.append(Arr) else: # kmail all your rares to a random account Val += Arr return Val # tab-separated output def TabPrint(InList): Table = "" for Rec in InList: Line = "\n" Rec = Flatten(Rec) for Item in Rec: Line += str(Item) + "\t" Table += Line print Table print "Test Strengths" TabPrint(TestStrengths) print "\nRequired Main Stat (w/ equalising potions and calculated buffs)" TabPrint(ReqStat)