我正在研究一种自动为角色扮演游戏创建角色表的算法。在游戏中,你有一些属性,你可以用它来增加它们。但是,在某个值处,需要2个点才能将实际属性的值增加1.您可以使用一定数量的点开始,默认情况下每个属性的值为1
我有一个随机分配点的程序,但是我不知道如何更改这些值(在字典中)以便在必要时向下舍入。
例如,如果我在"力量"中加入3分,那很好,我得到了一个"力量"值3(包括基数1)。但是,如果我输入4个点,我仍然应该只有4个值。它应该取5个点(加上基数1)以获得值5.然后需要另外2个点来获得值6,3点得到7分和3分得到值8。
我目前用来分配attibutes的代码如下所示:
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)
我想要的只是一个简单的函数,它采用字典"属性"作为参数,并将每个属性所具有的点数转换为它应该具有的正确值。
即。 "strength": 4
保持为"strength": 4
,但"wits": 6"
下降到"wits": 5"
,"intelligence: 9
下降到"intelligence: 7"
。
我使用字典时有点新,所以我通常会采用这种方法:
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
效率不高或漂亮,但仍然是一个解决方案。但是,你不能只是在字典中循环索引,所以我不完全确定如何去做这样的事情。
一般解释或功能将不胜感激。
答案 0 :(得分:7)
似乎bisection algo非常适合您的需求 - 指向“投资”总是被排序和定义。创建带有参考点的数组,如果没有if
s:
>>> from bisect import bisect
>>> points_to_invest = [1, 2, 3, 4, 6, 8, 10, 13]
>>> bisect(points_to_invest, 1)
1
>>> bisect(points_to_invest, 4)
4
>>> bisect(points_to_invest, 5)
4
>>> bisect(points_to_invest, 6)
5
这种方法将为您提供更轻松的可维护性
答案 1 :(得分:2)
您可以使用dictionary.items()
循环播放元素
然后,您可以修改转换功能:
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
答案 2 :(得分:1)
比“转换”功能少一点空间,但仍然是手工劳动:
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}
如果您希望“翻译员”减少手动工作量并更好地扩展,那么您可以通过一些代码预先生成它,具体取决于您指向值的逻辑。
答案 3 :(得分:0)
经过多次反复试验,这是一个单行功能:
def convert(x):
return x - (x > 4) - (x > 6) - (x > 8) * (x - 8) + (x > 10) + (x > 13)
这是一个测试:
print([(points, convert(points)) for points in range(20)])
# [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 4), (6, 5), (7, 5), (8, 6), (9, 6), (10, 6), (11, 7), (12, 7), (13, 7), (14, 8), (15, 8), (16, 8), (17, 8), (18, 8), (19, 8)]
但是, if
和elif
语句可能更清晰。
此功能只是将输入点的数量转换为值。您可以将convert
函数应用于列表的每个元素。