There's a lot of ways this code can be improved:
Setting coreRarity -
This code below:
valid = True
if coreType == "Common":
coreRarity = 1
elif coreType == "Rare":
coreRarity = 1.5
elif coreType == "Legendary":
coreRarity = 3
else:
print("Invalid core type")
valid = False
can be made into a dictionary lookup
coreRarityDict = {
"Common": 1,
"Rare": 1.5,
"Legendary": 3
}
To set valid
and coreRarity
uses readable dictionary methods
valid = coreType in coreRarityDict
if valid:
coreRarity = coreRarityDict[coreType] # dictionary lookup
else:
print("Invalid core type")
Setting idea - The next part:
if justice > compassion and justice > truth and justice > bravery:
idea = "justice"
elif compassion > justice and compassion > truth and compassion > bravery:
idea = "compassion"
elif truth > compassion and truth > justice and truth > bravery:
idea = truth
elif bravery > compassion and bravery > truth and bravery > justice:
idea = "bravery"
else:
idea = "all"
The logic here is basically boils down to which is the (strict) maximum of justice, compassion, truth, bravery
. If there is a ties for the maximum, set idea to "all".
Note idea = truth
looks like it should be idea = "truth"
Again let's use a dictionary
ideasDict = {
"justice": justice,
"compassion": compassion,
"truth": truth,
"bravery": bravery,
}
To set idea we want the key with the strict largest value
See - Getting key with maximum value in dictionary?
idea = max(ideasDict, key=lambda x: ideasDict[x])
To check for ties we can count the number of times this idea value occurs in our dictionary - see Python 2.7 Counting number of dictionary items with given value
sum(1 for x in ideasDict.values() if x == idea)
Combining this,
idea = max(ideasDict, key=lambda x: ideasDict[x])
idea_freq = sum(1 for x in ideasDict.values() if x == idea)
if idea_freq > 1:
idea = "all"
Setting boost - This code
if idea == "justice" and (element == "Light" or element == "Shadow"):
boost = justice
elif idea == "truth" and (element == "Ice" or element == "Wind"):
boost = truth
elif idea == "compassion" and (element == "Earth" or element == "Lightning"):
boost = compassion
elif idea == "bravery" and (element == "Fire" or element == "Water"):
boost = bravery
elif idea == "all":
boost = bravery #basically the above determines what the highest idea is and sets it but if the highest is all it means they are all the same so It doesn't matter one one the boost's value is cause its all the same
Notice you are repeating if idea == "xx": boost = xx
Reusing the dictionary the code would look like
if idea == "justice" and (element == "Light" or element == "Shadow"):
boost = ideasDict[idea]
elif idea == "truth" and (element == "Ice" or element == "Wind"):
boost = ideasDict[idea]
elif idea == "compassion" and (element == "Earth" or element == "Lightning"):
boost = ideasDict[idea]
elif idea == "bravery" and (element == "Fire" or element == "Water"):
boost = ideasDict[idea]
elif idea == "all":
boost = bravery #basically the above determines what the highest idea is and sets it but if the highest is all it means they are all the same so It doesn't matter one one the boost's value is cause its all the same
That's a lot of repeating boost = ideasDict[idea]
! Let's simplify further! Note the elif
can just be made as an if
as your conditions are non-overlapping: idea
can't be both == "justice"
and == "truth"
. Let's use a dictionary again
elementsBoostDict = {
"justice": ["Light", "Shadow"],
"compassion": ["Ice", "Wind"],
"truth": ["Earth", "Lightning"],
"bravery": ["Fire", "Water"],
}
if idea == "all":
boost = bravery
elif element in elementsBoostDict[idea]:
boost = ideasDict[idea]
Notice boost
may not be set e.g idea == "justice"
and element == "ice"
and boost
is not used anywhere else in your code? Is this intended?
Calculating chance - this is your code
if valid == True:
chance = math.max(math.sqrt(luck*0.01*1.3)+0.95,1)*0.01*(0.01*(100+5*idea)*coreRarity*baseChance)
if coreType == "common":
chance =* 0.25
print(chance)
Note idea
is a string (I get error TypeError: unsupported operand type(s) for +: 'int' and 'str'
after previously correcting to idea = "truth"
) and should be replaced by it's relative value.
The line if valid == True:
can be simplified to if valid:
Your chance calculation includes a lot of hard coded numbers and can be simplified 0.01*0.01 = 0.0001
. Let's move this into a function with some defaults. Also as luck
is a percentage we'll use luck=0.54
and remove the multiplication by 0.01
.
def chance_calc(coreType, coreRarity, idea, luck=0.54, baseChance=0.01):
temp = math.max(math.sqrt(luck * 1.3) + 0.95, 1)
chance = temp * 0.0001 * (100 + 5 * ideasDict[idea]) * coreRarity * baseChance
if coreType == "common":
chance *= 0.25
return chance
Final code
import math
justice = 0
compassion = 1
bravery = 1
truth = 2
coreType = "Legendary"
element = "Light"
coreRarityDict = {
"Common": 1,
"Rare": 1.5,
"Legendary": 3
}
ideasDict= {
"justice": justice,
"compassion": compassion,
"truth": truth,
"bravery": bravery,
}
elementsBoost = {
"justice": ["Light", "Shadow"],
"compassion": ["Ice", "Wind"],
"truth": ["Earth", "Lightning"],
"bravery": ["Fire", "Water"],
}
# set coreRarity
valid = coreType in coreRarityDict
if valid:
coreRarity = coreRarityDict[coreType]
else:
print("Invalid core type")
# set idea
idea = max(ideasDict, key=lambda x: ideasDict[x])
idea_freq = sum(1 for x in ideasDict.values() if x == idea)
if idea_freq > 1:
idea = "all"
# set boost
if idea == "all":
boost = bravery
elif element in elementsBoost[idea]:
boost = ideasDict[idea]
def chance_calc(coreType, coreRarity, idea, luck=0.54, baseChance=0.01):
temp = math.max(math.sqrt(luck * 1.3) + 0.95, 1)
chance = temp * 0.0001 * (100 + 5 * ideasDict[idea]) * coreRarity * baseChance
if coreType == "common":
chance *= 0.25
return chance
if valid:
chance = chance_calc(coreType, coreRarity, idea)
print(chance)
# result 0.0005899919528666251
Final thoughts and post mortem
There's a high chance I changed what you intended or made some error.
Using a structured data type like a dictionary has the benefit of simplifying code and provides methods we can use. An alternative could be using classes which could combine ideasDict
and elementsBoost
.
If idea is "all" then ideasDict[idea]
will return None
and chance_calc
will return an error.
boost
is not used
If ideasDict[idea]
is big enough the chance may be bigger than 1.
The chance calculation looks like it could be improved. A good idea might be to write down a bunch of combinations of justice, compassion, bravery, truth, coreType, element
and what chance you would like for each and then try to write a function that gets close to this.