Skip to content

Instantly share code, notes, and snippets.

@ckurtz22
Created July 23, 2020 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ckurtz22/8b3c96c53fbf023486e2f6249ece3e5f to your computer and use it in GitHub Desktop.
Save ckurtz22/8b3c96c53fbf023486e2f6249ece3e5f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import random
class Blade:
def __init__(self, name, pity, probs, elem, weapon=None):
self.name = name
self.pity = pity
self.probs = probs
self.count = 0
self.elem = elem
self.weapon = weapon
def isPity(self, group):
if group == 1:
return group == self.pity
return (group - 1) == self.pity
def getProb(self, group):
return self.probs[group-1]
def getName(self):
return self.name
def getWeapon(self):
return self.weapon
def getElem(self):
return self.elem
def pulled(self):
self.count += 1
def pullCount(self):
return self.count
def matchIdea(self, idea):
if idea == 1:
return self.elem in [1, 2]
if idea == 2:
return self.elem in [3, 6]
if idea == 3:
return self.elem in [4, 5]
if idea == 4:
return self.elem in [7, 8]
return False
blades = [
Blade("Godfrey", 1, [0.63, 0.63, 1.25, 1.56, 2.19], 6),
Blade("Perceval", 2, [1.50, 0.25, 0.50, 1.00, 1.75], 8),
Blade("Vale", 5, [0.75, 0.25, 0.25, 0.25, 0.25], 8),
Blade("Agate", 1, [0.25, 0.38, 0.75, 0.75, 0.13], 4),
Blade("Gorg", 3, [1.00, 1.00, 0.50, 1.50, 1.00], 2),
Blade("Boreas", 1, [0.25, 2.13, 2.13, 0.56, 1.19], 3),
Blade("Dagas", 0, [0.50, 0.75, 0.50, 1.25, 0.50], 1),
Blade("Perun", 3, [2.44, 0.25, 0.63, 1.88, 1.06], 6),
Blade("Kora", 4, [0.63, 1.88, 1.88, 0.31, 1.56], 5),
Blade("Azami", 2, [0.31, 1.88, 1.25, 0.63, 2.19], 8),
Blade("Ursula", 5, [2.25, 0.63, 1.25, 1.88, 0.25], 6),
Blade("Newt", 0, [0.25, 0.25, 0.25, 0.25, 0.75], 1),
Blade("Nim", 4, [1.00, 1.00, 1.75, 0.25, 1.00], 4),
Blade("Adenine", 2, [1.50, 0.25, 1.00, 1.75, 0.50], 3),
Blade("Electra", 3, [1.88, 2.25, 0.63, 1.25, 0.25], 5),
Blade("Zenobia", 0, [0.25, 0.75, 0.25, 0.25, 0.25], 3),
Blade("Finch", 4, [0.50, 1.00, 1.75, 0.25, 1.50], 3),
Blade("Floren", 5, [1.75, 1.50, 1.00, 0.50, 0.25], 4),
Blade("KOS-MOS", 0, [0.10, 0.10, 0.10, 0.10, 0.10], 7),
Blade("Dahlia", 0, [0.13, 0.50, 0.25, 0.88, 0.75], 6),
Blade("Akhos", 0, [0.25, 0.25, 0.25, 0.25, 0.25], 5),
Blade("Patroka", 0, [0.25, 0.25, 0.25, 0.25, 0.25], 4),
Blade("Obrona", 0, [0.50, 0.50, 0.50, 0.50, 0.50], 5),
Blade("Perdido", 0, [0.50, 0.50, 0.50, 0.50, 0.50], 1),
Blade("Cressidus", 0, [0.50, 0.50, 0.50, 0.50, 0.50], 4),
Blade("Sever", 0, [0.50, 0.50, 0.50, 0.50, 0.50], 3),
Blade("Kasandra", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 8),
Blade("Sheba", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 2),
Blade("Herald", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 5),
Blade("Aegaeon", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 2),
Blade("Praxis", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 6),
Blade("Theory", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 6),
Blade("Vess", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 5),
Blade("Wulfric", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 4),
Blade("T-elos", 0, [5.00, 5.00, 5.00, 5.00, 5.00], 8),
Blade("Crossette", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 1),
Blade("Corvin", 0, [1.00, 1.00, 1.00, 1.00, 1.00], 7)
]
#import argparse
#parser = argparse.ArgumentParser(description='Find probability of finding blades.')
#parser.add_argument('-p', '--pulled', action='extend', nargs='+', default=[], help='List of blades already pulled.')
#parser.add_argument('-r', '--released', action='extend', nargs='+', default=[], help='List of blades that have been released.')
#parser.add_argument('-l', '--luck', '--luk', action='store', default=0, type=int, help='Current LUK stat on driver pulling blades')
#parser.add_argument('-g', '--pity', '--group', action='store', default=0, type=int)
#parser.add_argument('-i', '--ideas', action='extend', count=4, default=[0, 0, 0, 0], type=int, help='Idea stats on driver pulling blades: --ideas bravery truth compassion justice')
#parser.add_argument('-b', '--booster', action='store', default=0, type=int, help='Type of booster used, if any used: 1 for bravery, 2 for truth, etc')
#parser.add_argument('-c', '--core', action='store', default=1, type=int, help='Type of core crystal used: 1 for common, 2 for rare, 3 for legendary')
#parser.parse_args()
## Parameters
pulled = []
released = []
ngplus = False
luk = 900
ideas = [2, 5, 3, 7]
booster = 0
numcores = 25
cores = [3 for i in range(99*4)]# + [2 for i in range(4)]
#cores = [2 for i in range(4)]
for i in reversed(range(len(blades))):
if i < 20 or (i < 26 and ngplus):
if blades[i].getName() in pulled:
blades.pop(i)
else:
if blades[i].getName() not in released:
blades.pop(i)
num_iters = 10000
successes = 0
for niter in range(num_iters):
pity = random.randint(1,5)
blades_iter = blades[:]
pulled_blades = []
pity_points = 0
corePoints = [5, 25, 50]
for core in cores:
pity_points += corePoints[core-1]
candidate = -1
if booster is not 0:
idea_type = booster
else:
idea_type = random.choice([i+1 for i in range(len(ideas)) if ideas[i] == max(ideas)])
idea_level = ideas[idea_type-1]
coreRNG = [0.24, 0.99, 0.99]
coreProbs = [1.0, 1.5, 3.0]
if random.random() < coreRNG[core-1]:
candidates = []
for i, blade in enumerate(blades_iter):
bladeProb = blade.getProb(pity) / 100.0
coreProb = coreProbs[core-1]
ideaProb = 1.0 + 0.05*idea_level if blade.matchIdea(idea_type) else 1.0
lukProb = max(1.0, (luk ** 0.5)/100 * 1.3 + 0.95)
if random.random() < bladeProb * coreProb * ideaProb * lukProb:
candidates.append(i)
if len(candidates) > 0:
if len(candidates) > 1:
matchedIdea = [i for i in candidates if blades_iter[i].matchIdea(idea_type)]
if len(matchedIdea) > 0:
candidates = matchedIdea
if len(candidates) > 1:
probs = [blades_iter[i].getProb(pity) for i in candidates]
lowestProb = [i for i in candidates if blades_iter[i].getProb(pity) == min(probs)]
if len(lowestProb) > 0:
candidates = lowestProb
candidate = random.choice(candidates)
pity_points = 0
if candidate == -1:
if pity_points >= 100:
pityBlades = [i for i, blade in enumerate(blades_iter) if blade.isPity(pity)]
if len(pityBlades) > 0:
pity_points = 0
probs = [blades_iter[i].getProb(pity)/100 for i in pityBlades]
probs = [p / sum(probs) for p in probs]
rng = random.random()
for i, p in enumerate(probs):
if rng < p:
break
rng -= p
candidate = pityBlades[i]
pity_points = 0
if candidate != -1:
pulled_blades.append(blades_iter.pop(candidate))
pulled_blades[-1].pulled()
else:
probs = [15 for i in range(7)]
if idea_type == 1:
probs[0] = 35
probs[1] = 35
if idea_type == 2:
probs[2] = 35
probs[5] = 35
if idea_type == 3:
probs[3] = 35
probs[5] = 35
if idea_type == 4:
probs[6] = 35
probs = [p / sum(probs) for p in probs]
rng = random.random()
for i, p in enumerate(probs):
if rng < p:
break
rng -= p
i = 8 if i is 6 else i + 1
pulled_blades.append(Blade("common", 0, [0,0,0,0,0], i, random.randint(1,8)))
earths = 0
fires = 0
winds = 0
nopon = 0
ancient = 0
keeneye = 0
leaping = 0
fortitude = 0
nonhealer = 0
healer = 0
for blade in pulled_blades:
if blade.getName() in ["Floren", "Nim"] or (blade.getName() is "common" and blade.getElem() is 4):
earths += 1
if blade.getName() is "common" and blade.getElem() is 1:
fires += 1
if blade.getWeapon() <= 2:
healer += 1
if blade.getWeapon() >= 4:
nonhealer += 1
if blade.getName() in ["Zenobia", "Adenine"] or (blade.getName() is "common" and blade.getElem() is 3):
winds += 1
if blade.getName() is "Boreas":
nopon += 1
if blade.getName() is "Perun":
ancient += 1
if blade.getName() in ["Gorg", "Adenine", "Agate"]:
keeneye += 1
if blade.getName() in ["Zenobia", "Finch", "Perceval"]:
leaping += 1
if blade.getName() in ["Ursula", "Gorg"]:
fortitude += 1
# DLC success check
#if earths >= 0 and fires >= 0 and winds >= 0 and nopon >= 1 and ancient >= 0 and keeneye >= 0 and leaping >= 0 and nonhealer >= 0 and healer >= 0:
#successes += 1
#print(earths-3, fires-2, winds-1, nopon-1, ancient-1, keeneye-1, leaping-1, nonhealer-1)
#exit()
if len(blades_iter) is 0:
successes += 1
print("%d of the DLC blade pulls were successful" % successes)
for blade in blades:
print("Blade %s was pulled %d%% of the time" % (blade.getName(), blade.pullCount() * 100 / num_iters))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment