6 Stimmen

Einfachere / effizientere Methode des verschachtelten if ... else Flusses?

Ich arbeite derzeit an einem Emulationsserver für ein Flash-Client-basiertes Spiel, das ein "Haustiersystem" hat, und ich habe mich gefragt, ob es einen einfacheren Weg gibt, um die Stufe bestimmter Haustiere zu überprüfen.

Aktueller Code:

public int Level
{
    get
    {
        if (Expirience > 100) // Level 2
        {
            if (Expirience > 200) // Level 3
            {
                if (Expirience > 400) // Level 4 - Unsure of Goal
                {
                    if (Expirience > 600) // Level 5 - Unsure of Goal
                    {
                        if (Expirience > 1000) // Level 6
                        {
                            if (Expirience > 1300) // Level 7
                            {
                                if (Expirience > 1800) // Level 8
                                {
                                    if (Expirience > 2400) // Level 9
                                    {
                                        if (Expirience > 3200) // Level 10
                                        {
                                            if (Expirience > 4300) // Level 11
                                            {
                                                if (Expirience > 7200) // Level 12 - Unsure of Goal
                                                {
                                                    if (Expirience > 8500) // Level 13 - Unsure of Goal
                                                    {
                                                        if (Expirience > 10100) // Level 14
                                                        {
                                                            if (Expirience > 13300) // Level 15
                                                            {
                                                                if (Expirience > 17500) // Level 16
                                                                {
                                                                    if (Expirience > 23000) // Level 17
                                                                    {
                                                                        return 17; // Bored
                                                                    }
                                                                    return 16;
                                                                }
                                                                return 15;
                                                            }
                                                            return 14;
                                                        }
                                                        return 13;
                                                    }
                                                    return 12;
                                                }
                                                return 11;
                                            }
                                            return 10;
                                        }
                                        return 9;
                                    }
                                    return 8;
                                }
                                return 7;
                            }
                            return 6;
                        }
                        return 5;
                    }
                    return 4;
                }
                return 3;
            }
            return 2;
        } 
        return 1;
    }
}

Ja, ich bin mir bewusst, dass ich Experience falsch geschrieben habe, ich hatte den Fehler in einer früheren Funktion gemacht und war nicht dazu gekommen, alles zu aktualisieren.

22voto

Mark Byers Punkte 761508

Verwenden Sie eine SortedList<int, int> und iterieren Sie darüber, bis Sie einen Wert finden, der höher ist als der gesuchte Wert. Sie können dies mit einer einfachen Iteration tun, wie in der Antwort, die Sie bereits akzeptiert haben. Oder man kann es auf elegante Weise mit LINQ machen (mit leichten Leistungseinbußen):

SortedList<int, int> levels = new SortedList<int, int>
    {
        {0, 1},
        {100, 2},
        {200, 3},
        {400, 4},
        {600, 5},
    };

public int Experience;
public int Level
{
    get
    {
        return levels.Last(kvp => Experience >= kvp.Key).Value;
    }
}

Beachten Sie, dass die Speicherung der "Ebene" nicht unbedingt erforderlich ist, da Sie sie aus dem Index des Elements in der Liste ableiten können. Es kann von Vorteil sein, eine einfache List<int> die stattdessen sortiert wird, um Fehler zu vermeiden, bei denen Sie versehentlich eine Stufe auslassen, wie in der Lösung, die Sie bereits akzeptiert haben.

Wenn Sie eine bessere Leistung wünschen, können Sie Folgendes verwenden List.BinarySearch aber ich denke, die zusätzliche Komplexität ist es nicht wert, es sei denn, Sie haben ein Leistungsprofil erstellt und festgestellt, dass dies der Engpass ist.

List<int> levels = new List<int> { 0, 100, 200, 400, 600 /* etc... */ };

int index = levels.BinarySearch(Experience);
int level;
if (index < 0)
{
    level = ~index;
}
else
{
    level = index + 1;
}
return level;

13voto

TreDubZedd Punkte 2493
int[] levelCutoffs = new int[] {0, 100, 200, 400, 600 /*...*/};

for (int level = 0; level < levelCuttoffs.size; ++level) {
    if (Experience < levelCuttofs[level])
        return level;
}
return levelCuttoffs.size;

Edit: geändert, um Bradley Mountfords Vorschlag zu verwenden.

4voto

LBushkin Punkte 124894

Der Vorschlag von @Mark ist vernünftig. Sie könnten auch die Reihenfolge der Auswertung der Erfahrung umkehren, um die Wenns zu entschachteln:

if (Expirience > 23000) return 17; 
if (Expirience > 17500) return 16;
//... and so on.

Aber ich würde wahrscheinlich einfach ein normales C#-Array und die BinärSuche Methode, die den Index des übereinstimmenden Elements oder das 2er-Komplement des kleinsten Elements, das gerade größer als der gesuchte Wert ist, zurückgeben kann:

int[] levelThresholds = new[] { 100, 200, 400, 600, 1000, ..., 23000 };

int experience = 11403;
int index = Array.BinarySearch( levelThresholds, experience );
// returns either the index, or the 2's complement of the 
// first index greater than the value being sought
int level = index < 0 ? ~index : index+1;

3voto

Wikser Punkte 810

Wie wäre es mit einer einfachen Formel, die auf einer logarithmischen Funktion basiert?

Etwas wie

return Math.Floor(LinearScale * Math.Log(Expirience, LogBase));

2voto

Matt M Punkte 29

Sie gehen von der umfassendsten zur exklusivsten Variante über. Wenn Sie in die andere Richtung gehen, brauchen Sie diese Verschachtelungen nicht.

if (Expirience > 23000) // Level 17
  {
    return 17; // Bored
  }
  else if (Expirience > 17500) // Level 16
  {
    return 16;
  }
  else if (Expirience > 13300) // Level 15
  {
    return 15;
  }
  ...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X