如何在Python中舍入到特定值

时间:2017-07-26 15:34:39

标签: python function rounding

我正在研究一种自动为角色扮演游戏创建角色表的算法。在游戏中,你有一些属性,你可以用它来增加它们。但是,在某个值处,需要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

效率不高或漂亮,但仍然是一个解决方案。但是,你不能只是在字典中循环索引,所以我不完全确定如何去做这样的事情。

一般解释或功能将不胜感激。

4 个答案:

答案 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)]
但是,

ifelif语句可能更清晰。

此功能只是将输入点的数量转换为值。您可以将convert函数应用于列表的每个元素。