I am working on an algorithm to automatically create character sheets for a roleplaying game. In the game, you have attributes which you put points into to increase them. However, at a certain value it takes 2 points to increase the value of the actual attribute by 1. You start of with a certain number of points, and each attribute has a value of 1 by default
I have a program that randomly assigns the points, however I am stuck as to how I then change these values (that are in a dictionary) to round down when necessary.
For example, if I put 3 points in "strength", thats fine, I get a "strength" value of 3 (including tha base 1). However, if I put 4 points in, I still should only have a value of 4. It should take 5 points (plus the base 1) in order to get a value of 5. It then takes another 2 points to get a value of 6, 3 points to get a value of 7 and 3 points to get a value of 8.
The code I am currently using to assign the attibutes looks like this:
attributes = {}
row1 = ['strength', 'intelligence', 'charisma']
row2 = ['stamina', 'willpower']
row3 = ['dexterity', 'wits', 'luck']
def assignRow(row, p): # p is the number of points you have to assign to each row
rowValues = {}
for i in range(0, len(row)-1):
val = randint(0, p)
rowValues[row[i]] = val + 1
p -= val
rowValues[row[-1]] = p + 1
return attributes.update(rowValues)
assignRow(row1, 7)
assignRow(row2, 5)
assignRow(row3, 3)
What I want is just a simple function that takes the dictionary "attributes" as a parameter, and converts the number of points each attribute has to the proper value it should be.
i.e. "strength": 4
stays as "strength": 4
, but "wits": 6"
goes down to "wits": 5"
, and "intelligence: 9
goes down to "intelligence: 7"
.
I'm somewhat new to using dictionaries and so the ways I would normally approach this:
def convert(list):
for i in range(len(list)):
if list[i] <= 4:
list[i] = list[i]
if list[i] in (5, 6):
list[i] -= 1
if list[i] in (7, 8):
list[i] -= 2
if list[i] in (9, 10):
list[i] = 6
if list[i] in (11, 12, 13):
list[i] = 7
else:
list[i] = 8
Not efficient or pretty but still a solutuion. However, you can't just loop over indexes in a dictionary so I am not entirely sure how to go about something like this.
General explanation or function would be appreciated.
Python's round() function requires two arguments. First is the number to be rounded. Second argument decides the number of decimal places to which it is rounded. To round the number to 2 decimals, give second argument as 2.
Round a Number Down to the nearest 5 in Python #Call the math. floor() method passing it the number divided by 5 . Multiply the result by 5 . The result of the calculation is the number rounded down to the nearest 5 .
Use the round() function to round a float to 3 decimal places, e.g. result = round(6.36789, 3) . The round() function will round the floating-point number to 3 decimal places and will return the result. Copied!
Python round() Function The round() function returns a floating point number that is a rounded version of the specified number, with the specified number of decimals. The default number of decimals is 0, meaning that the function will return the nearest integer.
You can loop over the elements by using dictionary.items()
You can then modify your convert function:
def convert(attributes):
for key, value in attributes.items():
# do your conversion on value here
if value <= 4:
continue # do nothing for this element
elif value in (5, 6):
value -= 1
elif value in (7, 8):
value -= 2
elif value in (9, 10):
value = 6
elif value in (11, 12, 13):
value = 7
else:
value = 8
# to replace the value in the dictionary you can use
attributes[key] = new_value
A bit less space then your "convert" function, though still manual labor:
p_to_v = {1:1, 2:2, 3:3, 4:4, 5:4, 6:5, 7:5, 8:6} # 'translator' dict, fill up further
input = {'strength':6, 'wits':8} # dict with stats and their points
output = dict((stat, p_to_v[point]) for stat, point in input.items()) # {'strength':5, 'wits':6}
If you want your 'translator' to take less manual work and scale better then you can pre-generate it via some code, depending on your logic of points to values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With