2017-07-26 21 views
10

我正在研究一種爲角色扮演遊戲自動創建角色表的算法。在遊戲中,你可以添加點數來增加它們的屬性。但是,在某個值時,需要2點才能將實際屬性的值增加1.您以一定數量的點開始,並且每個屬性的默認值爲1如何四捨五入到Python中的特定值

我有一個程序隨機分配點,但是我堅持如何改變這些值(在字典中)以在必要時舍入。例如,如果我在「強度」中放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 

效率不高或漂亮,但仍然是一個solutuion。但是,你不能只循環字典中的索引,所以我不完全確定如何去做這樣的事情。

一般的解釋或功能,將不勝感激。

+8

我明白,作爲一個初學者,你花時間和精力的方式更容易維護在問問題之前制定自己的解決方案。不管效率如何低下,您都可以更好地理解其他解決方案,並且您已經成長爲程序員。 –

+3

也就是說,不要使用內建名稱'list'的名稱。傳統上至少使用'list_'。這並不是說你的代碼會立即崩潰,但是你將無法調用內置函數來將事物轉換爲列表。而且,'row = list'行幾乎沒有用處。只需調用輸入參數'row'並且用一塊石頭就可以殺死兩隻鳥。 –

+0

@MadPhysicist謝謝,我已經更新了程序 –

回答

8

似乎bisection算法適合您的需求非常好 - 點「投資」總是排序和定義。創建基準點陣列,你是好到無一堆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 

這種方法會給你未來的

+0

這正是我所期待的!謝謝!將它放入我需要的函數格式中的最佳方式是什麼? –

+0

Mb我誤解了,但我認爲這裏的主要問題是獲取屬性值。如果你有這個想法,休息很簡單 - 遍歷'attribute_dict.items()'並通過bisect獲取值。如果你已經嘗試了這個,但仍然有問題 - 請在stackoverflow上創建新問題,它的方式最好是用單純的單精度填充 – Slam

+0

對不起,不,現在它工作完美,我只是把它扔在下面問題的前兩行。 –

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 
+0

完美的作品,謝謝! (雖然在最後一行你必須將它改爲'attributes [key] = value',因爲new_value在其他地方不存在) –

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)] 

儘管如此,和elif陳述可能會更清晰。

此功能只是將輸入點的數量轉換爲值。您可以將convert函數應用於列表的每個元素。

+0

非常感謝你的回答,但另一個幫助我理解我需要什麼改變並給了我更清晰的解決方案。 –

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} 

如果你想你的「翻譯」少拿手工作業和規模更好,那麼你可以通過預先生成它一些代碼,取決於你指向值的邏輯。

+0

謝謝,這看起來更快,我會把它放在程序中再次進行一些速度測試。譯者的想法也很有幫助,但目前的答案幫助我理解了我正在努力的差異。 –