2017-07-26 2 views
10

Ich arbeite an einem Algorithmus, um automatisch Zeichenblätter für ein Rollenspiel zu erstellen. Im Spiel haben Sie Attribute, in die Sie Punkte setzen, um sie zu erhöhen. Bei einem bestimmten Wert dauert es jedoch 2 Punkte, um den Wert des tatsächlichen Attributs um 1 zu erhöhen. Sie beginnen mit einer bestimmten Anzahl von Punkten, und jedes Attribut hat standardmäßig den WertWie man auf bestimmte Werte in Python aufrundet

Ich habe ein Programm, das Ordnet die Punkte zufällig zu, aber ich bin fest, wie ich dann diese Werte ändern (die in einem Wörterbuch sind), um bei Bedarf abzurunden.

Zum Beispiel, wenn ich 3 Punkte in "Stärke", das ist in Ordnung, bekomme ich einen "Stärke" -Wert von 3 (einschließlich der Basis 1). Wenn ich jedoch 4 Punkte einstelle, sollte ich immer noch nur einen Wert von 4 haben. Es sollte 5 Punkte (plus die Basis 1) nehmen, um einen Wert von 5 zu bekommen. Es braucht dann noch 2 Punkte, um einen Wert von zu erhalten 6, 3 Punkte einen Wert von 7 und 3 Punkte bekommen Wert von 8.

der Code, den ich die attibutes zuweisen bin mit zur Zeit zu erhalten wie folgt aussieht:

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) 

Was ich will, ist nur eine einfache Funktion, die das Wörterbuch "attributes" als Parameter akzeptiert und die Anzahl der Punkte, die jedes Attribut hat, in den richtigen Wert umwandelt.

heißt "strength": 4 Aufenthalte als "strength": 4, aber "wits": 6" geht bis auf "wits": 5" und "intelligence: 9 geht bis auf "intelligence: 7".

Ich bin etwas Neues zu Wörterbuch und so die Art und Weise unter Verwendung würde ich dies in der Regel Ansatz:

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 

nicht effizient oder hübsch, aber immer noch ein solutuion. Sie können jedoch nicht einfach Indizes in einem Dictionary durchlaufen, so dass ich mir nicht ganz sicher bin, wie ich so etwas machen soll.

Allgemeine Erklärung oder Funktion würde geschätzt werden.

+8

Ich schätze, dass als Anfänger Sie sich die Zeit genommen und Mühe um Ihre eigene Lösung zu machen, bevor Sie fragen. Egal wie ineffizient es ist, Sie werden in der Lage sein, andere Lösungen viel besser zu verstehen, und Sie sind bereits als Programmierer gewachsen. –

+3

Verwenden Sie nicht den Namen des eingebauten Namens 'list'. Es ist üblich mindestens 'list_' zu verwenden. Es ist nicht so, dass Ihr Code sofort bricht, aber Sie werden nicht in der Lage sein, die eingebaute Funktion aufzurufen, um Dinge in Listen umzuwandeln. Auch die Zeile 'row = list' macht praktisch nichts Sinnvolles. Rufen Sie einfach den Eingabeparameter 'row' an und töten Sie zwei Fliegen mit einer Klappe. –

+0

@MadPhysicist Danke, ich habe das Programm aktualisiert –

Antwort

8

Scheint, dass bisection algo Ihren Bedürfnissen ziemlich gut entspricht - Punkte zu "investieren" werden immer sortiert und definiert. Erstellen Sie Array mit Referenzpunkten und Sie sind gut zu ohne Bündel 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 

Dieser Ansatz wird Ihnen viel einfacher Wartbarkeit für zukünftige

+0

Genau das habe ich gesucht! Vielen Dank! Was ist der beste Weg, um es in das Funktionsformat zu bringen, das ich brauche? –

+0

Mb Ich habe missverstanden, aber ich dachte, dass das Hauptproblem hier war, die Attributwerte zu bekommen. Wenn Sie diese Idee haben, ist Ruhe einfach - iterieren Sie durch 'attribute_dict.items()' und erhalten Sie Werte durch Halbierung. Wenn Sie dies versucht haben und immer noch Probleme haben - pls, erstellen Sie eine neue Frage auf stackoverflow, es ist besser, Blähungen Single mit Ausarbeitungen – Slam

+0

Sorry, nein, es funktioniert jetzt perfekt, ich warf es einfach unter den ersten beiden Zeilen in der Frage unten . –

2

können Sie Schleife über die Elemente von dictionary.items() verwenden, können Sie dann Ihre Funktion convert ändern:

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

Das funktioniert perfekt, danke! (Obwohl in der letzten Zeile, müssen Sie es ändern, um 'attributes [key] = value' zu ​​sein, da new_value nirgendwo sonst existiert) –

0

Nach vielen Versuch und Irrtum, hier ist ein Einzeiler Funktion:

def convert(x): 
    return x - (x > 4) - (x > 6) - (x > 8) * (x - 8) + (x > 10) + (x > 13) 

Hier ein Test:

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 und elif Aussagen könnten jedoch klarer sein.

Diese Funktion konvertiert einfach eine Anzahl von Eingabepunkten in einen Wert. Sie können die Funktion convert auf jedes Element einer Liste anwenden.

+0

Vielen Dank für die Antwort, aber die andere hilft mir zu verstehen, was ich brauchte zu ändern und gab mir die klarere Lösung. –

1

Ein bisschen weniger Platz dann „convert“ Funktion, aber immer noch Handarbeit:

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} 

Wenn Sie Ihr ‚Übersetzer‘ weniger manuelle Arbeit zu nehmen und skalieren besser, dann können Sie im Voraus generieren es über einige Code, abhängig von Ihrer Logik der Punkte zu Werten.

+0

Danke, das sieht schneller aus, und ich werde es in das Programm schreiben, um einige Geschwindigkeitstests gegen die andere zu machen. Auch die Idee eines Übersetzers ist hilfreich, aber die aktuelle Antwort hat mir geholfen, die Unterschiede zu verstehen, mit denen ich zu kämpfen hatte. –

Verwandte Themen