PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Lösung für zu große Verschachtelungen?



Sanghelios
14.08.2012, 13:43
Habe gerade das Problem, das ich in einem Event so viel verschachtelt habe, das der Event-Code rechts bereits aus dem Contents-Fenster ragt und ich ihn nunmehr nicht mehr sehe. Gibt es dafür eine einfache Lösung? Ich muss zwingend knapp 70 Conditional Branches auf die folgende Weise verschachteln. Bin eigentlich fest davon ausgegangen, das unten ein Scrollbalken erscheint sobald kein Platz mehr da ist.

http://s14.directupload.net/images/120814/oslr3jg8.jpg

MagicMaker
14.08.2012, 14:04
Ich hab sogar mal versucht, dem Makerchen das beizubringen, erfolglos.

Wenn es keinen Pointer gibt, der sämtliche geschachtelte IFs überflüssig macht,
musst du wohl alles in Abschnitte unterheben.

Bei 1~100 wäre das zB in übergeordneten 25ern:


◆ If XYZ < 26
◆ If XYZ == 1
◆ ...
:Else
◆ If XYZ == 2
◆ ...
:Else
◆ If XYZ == 3
◆ ...
:Else
◆ .......
[...]
:END
:END
:END
:Else
◆ If XYZ < 51
◆ If XYZ == 26
◆ ...
:Else
◆ If XYZ == 27
◆ ...
:Else
◆ .......
[...]
:END
:END
:Else
◆ If XYZ < 76
◆ If XYZ == 51
◆ ...
:Else
◆ If XYZ == 52
◆ ...
:Else
◆ .......
[...]
:END
:END
:Else (If XYZ < 101 ist nicht wirklich nötig)
◆ If XYZ == 76
◆ ...
:Else
◆ If XYZ == 77
◆ ...
:Else
◆ .......
[...]
[...]
◆ If XYZ == 100
◆ ...
:END
[...]
[...]
:END
:END
:END
:END
:END

Zu weit nach innen zu gehen ist nicht nur schlecht für die Übersicht sondern könnte auch
irgendwann zu Fehlermeldungen führen, weil die Software damit nicht mehr klar kommt.

Cornix
14.08.2012, 16:40
Ruby-Script.

Sanghelios
15.08.2012, 03:22
Ich hab sogar mal versucht, dem Makerchen das beizubringen, erfolglos.

Wenn es keinen Pointer gibt, der sämtliche geschachtelte IFs überflüssig macht,
musst du wohl alles in Abschnitte unterheben.

Bei 1~100 wäre das zB in übergeordneten 25ern:


◆ If XYZ < 26
◆ If XYZ == 1
◆ ...
:Else
◆ If XYZ == 2
◆ ...
:Else
◆ If XYZ == 3
◆ ...
:Else
◆ .......
[...]
:END
:END
:END
:Else
◆ If XYZ < 51
◆ If XYZ == 26
◆ ...
:Else
◆ If XYZ == 27
◆ ...
:Else
◆ .......
[...]
:END
:END
:Else
◆ If XYZ < 76
◆ If XYZ == 51
◆ ...
:Else
◆ If XYZ == 52
◆ ...
:Else
◆ .......
[...]
:END
:END
:Else (If XYZ < 101 ist nicht wirklich nötig)
◆ If XYZ == 76
◆ ...
:Else
◆ If XYZ == 77
◆ ...
:Else
◆ .......
[...]
[...]
◆ If XYZ == 100
◆ ...
:END
[...]
[...]
:END
:END
:END
:END
:END

Zu weit nach innen zu gehen ist nicht nur schlecht für die Übersicht sondern könnte auch
irgendwann zu Fehlermeldungen führen, weil die Software damit nicht mehr klar kommt.

Vielen Dank für die Hilfe. Hab es jetzt mal so eingebaut und es funktioniert wunderbar. =)

-KD-
15.08.2012, 18:14
Wenn sich deine Abfragen gegenseitig ausschließen, brauchst du gar keine Verschachtelung.

IF XYZ==1
mache was
END[
IF XYZ == 2
mache was
END
...

Linkey
15.08.2012, 19:55
Würde das, theoretisch gesehen, keine (wenn auch übertrieben minimale) Verschlechterung der Performance bedeuten? Hab mich damit noch nicht so beschäftigt, deshalb frage ich nach (:
Würde einfach jetzt erwarten, dass wenn ich bspw. 200 Abfragen habe und ich diese in bspw. 4 "Abschnitte" unterteile, es "schneller" abgefragt wird, als wenn alle 200 durchlaufen werden.

Bei 200 Abfragen, ohne Unterteilung, prüft das Programm 200 mal, ob XYZ == ABC ist.
Bei 200 Abfragen aufgeteilt in 4 Blöcke ( XYZ < 50, XYZ < 100, XYZ < 150, ELSE) werden maximal 51 Abfragen getätigt.

Cornix
15.08.2012, 20:16
Zuallerersteinmal musst du dir vergewissern, dass du, wenn du mit Event-Script arbeitest, sowieso eine sehr viel schlechtere Performance hast als wenn du die gesamten Abfragen direkt mit Ruby implementieren würdest.
Und obwohl du zwar recht hast, dass du Performance verlierst wenn du die If-Abfragen hintereinander setzt anstatt sie zu schachteln, so musst du dir im klaren sein, dass diese Abfragen allesamt sehr minimal und einfach sind.
Es sind allesamt lediglich Vergleiche auf Integern oder Abfragen von Booleans. Beides bedeutet minimalen Aufwand.

Wenn du diesen Abschnitt wirklich sehr oft laufen lässt und dir Sorgen um Performance machst so kann ich dir wirklich nur nocheinmal dazu raten es einfach in Ruby zu schreiben und im Event ein Custom-Script aufzurufen.
Wenn du uns einmal zeigen könntest was genau du eigentlich in den Event-Commands stehen hast könnten wir dir sicher dabei helfen falls du dir unsicher bist.

Linkey
15.08.2012, 21:34
Na ging ja nur um's Prinzip. Ich selbst verwende solche Verschachtelungen/Events nicht ...
Hab mich nur nie tief mit der Abarbeitung vom Eventcode des Makers beschäftigt (VX schon einmal gar nicht).
Habe ja auch gleich gesagt, dass eine simple Abfrage im Normalfall eh schon minmale Auswirkungen hat, aber wie gesagt keine Ahnung was dort im Maker alles passiert.

Die vom TE dargestellte Verschachtelung sieht ganz nebenbei fast so aus,wie du auch schon angedeutet hast, als könnte man diese auch durch 3-4 Zeilen Ruby ersetzen.

caesa_andy
15.08.2012, 23:16
Würde das, theoretisch gesehen, keine (wenn auch übertrieben minimale) Verschlechterung der Performance bedeuten? Hab mich damit noch nicht so beschäftigt, deshalb frage ich nach (:
Würde einfach jetzt erwarten, dass wenn ich bspw. 200 Abfragen habe und ich diese in bspw. 4 "Abschnitte" unterteile, es "schneller" abgefragt wird, als wenn alle 200 durchlaufen werden.

Bei 200 Abfragen, ohne Unterteilung, prüft das Programm 200 mal, ob XYZ == ABC ist.
Bei 200 Abfragen aufgeteilt in 4 Blöcke ( XYZ < 50, XYZ < 100, XYZ < 150, ELSE) werden maximal 51 Abfragen getätigt.

Wenn sich die Abfragen gegenseitig ausschließen, kann er ans Ende jedes true-blocks einen "Jump to label" befehl setzen, durch den das script von da aus hinter die letzte Abfrage springt. Dann werden - genau wie bei der verschachtelung auch - die Conditionals nur so lange durchlaufen, bis das script auf die erste bedingung stößt, die "true" ist.
Vom Grundsatz her hast du aber natürlich recht., ich wqürde vermutlich bei 200 Abfragen auch erstmal "Bereiche" abfragen.

Sanghelios
16.08.2012, 01:13
Das ganze sollte dafür gedacht sein, den Inhalt einer Booster-Packung für mein Spiel zu bestimmen. Dafür habe ich am Anfang des Events ein Random 1-346 erstellt.
Die Erweiterung hat eigentlich nur 70 Karten, die 346 kommt zustande, weil ich nicht will das jede Karte die selbe Chance hat in der Packung zu sein. So hat eine Stern-Karte nun 4, eine Karo 5 und Kreis 6 Zahlen zugeordnet bekommen.

Mit den Blöcken klappt es ganz gut. Kann eigentlich keine Performance-Einbrüche wahrnehmen, wenn das Event läuft.

http://s1.directupload.net/images/120816/fk89siiv.jpg

@Cornix: Dachte ich mir schon, aber ich habe leider keine Ahnung vom Scripten. Von daher muss ich mir erstmal mit Events weiterhelfen. Sollte ich aber evtl. mal lernen. ;)

Todu
16.08.2012, 02:08
In dem Fall bietet sich aber tatsächlich, wie Vorposter geschrieben haben, es nicht in Elsifs zu packen, sondern mit einem Label ans Ende zu Springen

if Var11 <= x
code
jump to label endBooster
end
if Var11 <= y
code
jump to label endBooster
end
(...)
Label: endBooster


so kommst du nie tiefer als Verschachtelungstiefe 1 innerhalb dieser Funktion

Linkey
16.08.2012, 08:27
Nein, das ändert auch nichts. Das Jump mag zwar das ganze verkürzen, aber das kannst du zusätzlich auch benutzen, wenn du Bereiche verwendest.
Nehmen wir mal den Fall, dass die Variable 200 ist. Dann würde er ohne Unterteilung trotzdem 200 Abfragen durchrattern. Bei einer Unterteilung in vier Bereiche wie gesagt nur 50.

-KD-
16.08.2012, 19:58
Prinzipiell magst du ja recht haben, aber der Event-Interpreter ist sowieso nicht "so effizient". Letztlich bedeutet jede Zeile Eventcode mehr Aufwand für den Interpreter. Zuviele zusätzliche Branches und Einrückungen können das Ganze genauso gut auch langsamer machen.

Aber kommen wir mal auf das Problem zurück: Es geht um Boosterpackungen. Da der Spieler wohl kaum im Millisekundentakt Boosterpackungen erhält, ist es vollkommen Wurscht wie schnell das Programm durchläuft. Mach dir also keinen Stress und setz es so um wie du es am einfachsten und übersichtlichsten findest.

caesa_andy
17.08.2012, 11:33
Äh ... ich bin mir jetzt echt nicht sicherf, ob das an mir und mangelndem verständniss deinem Script gegenüber liegt, aber so wie ich das sehe, KANN das Event, das du da oben gepostet hast gar nicht funktionieren, Confodere.

Wenn du mit Else-ifs arbeitest, muss der größte Bedigungswert der erste in der Reihe sein. Denn wenn die Bedingung "Variable 0011 <= 12" wahr ist, ist auch die Bedingung "Variable 0011 <= 4" wahr, womit das Event niemals weiter als bis zur ersten abfrage durchlaufen wird.

Cornix
17.08.2012, 16:49
Äh ... ich bin mir jetzt echt nicht sicherf, ob das an mir und mangelndem verständniss deinem Script gegenüber liegt, aber so wie ich das sehe, KANN das Event, das du da oben gepostet hast gar nicht funktionieren, Confodere.

Wenn du mit Else-ifs arbeitest, muss der größte Bedigungswert der erste in der Reihe sein. Denn wenn die Bedingung "Variable 0011 <= 12" wahr ist, ist auch die Bedingung "Variable 0011 <= 4" wahr, womit das Event niemals weiter als bis zur ersten abfrage durchlaufen wird.

Das Event ist meines Erachtens nach korrekt.

Für Werte zwischen 1 und 4 gibt es Shiva, zwischen 5 und 8 Diablo, zwischen 9 und 12 Volt, etc etc.
Immerhin ist 5 nicht kleiner gleich 4 aber kleiner gleich 8.

caesa_andy
17.08.2012, 16:54
Ah ... vergiss was ich gesagt hatte, ich war mit den Vorzeichen durcheinander gekommen.

Passt schon so.

Todu
24.08.2012, 19:32
Richtig, mein Lösungsvorschlag ist nich effizienter, aber du kannst den Code hinterher noch lesen, weil er nicht ewig weit eingerückt wird. Ich hab nicht mitbekommen dass es um Effizient geht, falls dem so ist, und ansonsten geb ich KD recht, ist vermutlich irrelevant.